有关树的一些基础知识点请参考【这篇文章】。

  本文主要记录Java语言描述的二叉树相关的一些操作,如创建、遍历等。

  首先,我们需要一个表示树中节点的数据结构TreeNode,代码如下:

public class TreeNode<T> {
public T data;
public TreeNode<T> lChild;
public TreeNode<T> rChild;
public TreeNode<T> parent; public TreeNode() {
} public TreeNode(T data) {
this.data = data;
this.lChild = null;
this.rChild = null;
this.parent = null;
} public TreeNode(T data, TreeNode<T> parent, boolean isLeftC) {
this.data = data;
this.parent = parent;
if (isLeftC) {
parent.lChild = this;
} else {
parent.rChild = this;
}
}
}

  在二叉树的工具类BinaryTree中,提供了很多的方法,详细介绍如下:

(1)创建二叉树的时候,通过传入的字符串来自动生成二叉树的结构。注意:字符串是前序遍历的结构,每个节点都有左右两个节点,如果某个节点为空,则用“#”符号表示;节点与节点之间用空格隔开。

(2)使用递归和非递归的方式进行二叉树的前、中、后序遍历的方法。

(3)对二叉树进行层序遍历的方法。

(4)获取树的深度和树中节点总数的方法。

  以下是BinaryTree类中的详细代码:

public class BinaryTree {
private TreeNode<String> root;
private int size; // 根据初始化字符串生成二叉树
public BinaryTree(String content) {
root = createBTree(new Scanner(content));
} // 直接将一棵TreeNode树赋值为二叉树
public BinaryTree(TreeNode<String> root) {
this.root = root;
} // 根据字符串创建二叉树
private TreeNode<String> createBTree(Scanner scanner) {
String data = scanner.next();
if ("#".equals(data)) return null;
TreeNode<String> node = new TreeNode<>(data);
size++;
node.lChild = createBTree(scanner);
node.rChild = createBTree(scanner);
return node;
} // 获取二叉树的深度
public int getBTreeDepth() {
return getBTreeDepth(root);
} private int getBTreeDepth(TreeNode root) {
return root == null ? 0 : Math.max(getBTreeDepth(root.lChild), getBTreeDepth(root.rChild)) + 1;
} // 返回二叉树中节点个数
public int size() {
return size;
} // 前序遍历二叉树(useRec:是否使用递归方式)
public void traverseBefore(boolean useRec) {
if (useRec) {
traverseBeforeRec(root);
} else {
traverseBeforeNonRec();
}
} // 前序遍历二叉树(递归)
private void traverseBeforeRec(TreeNode node) {
if (node == null) {
System.out.print("#");
} else {
System.out.print(node.data);
traverseBeforeRec(node.lChild);
traverseBeforeRec(node.rChild);
}
} // 前序遍历二叉树(非递归)
private void traverseBeforeNonRec() {
Stack<TreeNode<String>> stack = new Stack<>();
TreeNode<String> currRoot = root;
while (true) {
if (currRoot != null) {
System.out.print(currRoot.data);
stack.push(currRoot.rChild);
currRoot = currRoot.lChild;
} else {
System.out.print("#");
if (stack.size() == 0) break;
currRoot = stack.pop();
}
}
} // 中序遍历二叉树
public void traverseMiddle(boolean useRec) {
if (useRec) {
traverseMiddleRec(root);
} else {
traverseMiddleNonRec();
}
} // 中序遍历二叉树(递归)
private void traverseMiddleRec(TreeNode node) {
if (node == null) {
System.out.print("#");
} else {
traverseMiddleRec(node.lChild);
System.out.print(node.data);
traverseMiddleRec(node.rChild);
}
} // 中序遍历二叉树(非递归)
private void traverseMiddleNonRec() {
Stack<TreeNode<String>> stack = new Stack<>();
TreeNode<String> currRoot = root;
while (true) {
if (currRoot != null) {
stack.push(currRoot);
currRoot = currRoot.lChild;
} else {
System.out.print("#");
if (stack.size() == 0) break;
TreeNode<String> middleNode = stack.pop();
System.out.print(middleNode.data);
currRoot = middleNode.rChild;
}
}
} // 后序遍历二叉树
public void traverseAfter(boolean useRec) {
if (useRec) {
traverseAfterRec(root);
} else {
traverseAfterNonRec();
}
} // 后序遍历二叉树(递归)
private void traverseAfterRec(TreeNode node) {
if (node == null) {
System.out.print("#");
} else {
traverseAfterRec(node.lChild);
traverseAfterRec(node.rChild);
System.out.print(node.data);
}
} // 后序遍历二叉树(非递归)
private void traverseAfterNonRec() {
Stack<TreeNode<String>> stack = new Stack<>();
TreeNode<String> lastNode = null;
TreeNode<String> currRoot = root;
while (true) {
if (currRoot != null) {
if (lastNode != null && currRoot.rChild == lastNode) {
System.out.print(currRoot.data);
lastNode = currRoot;
currRoot = stack.peek().rChild;
if (root.rChild == currRoot && currRoot == lastNode) {
System.out.print(root.data);
break;
}
} else if (lastNode != null && currRoot.lChild == lastNode) {
if (currRoot.rChild == null) {
System.out.print("#" + currRoot.data);
lastNode = currRoot;
currRoot = stack.pop();
}
} else {
stack.push(currRoot);
currRoot = currRoot.lChild;
}
} else {
System.out.print("#");
currRoot = stack.peek().rChild;
if (currRoot == null) {
System.out.print("#");
lastNode = stack.pop();
System.out.print(lastNode.data);
currRoot = stack.pop();
}
}
}
} // 层序遍历二叉树
public void traverseCeng() {
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()) {
TreeNode node = queue.poll();
if (node == null) {
System.out.print("#");
} else {
System.out.print(node.data);
queue.offer(node.lChild);
queue.offer(node.rChild);
}
}
}
}

  测试类代码:

public class TestTree {
private static final String TREE_CONTENT = "A B D # G # # E # # C # F H # # #"; public static void main(String args[]) {
System.out.println("根据字符串" + TREE_CONTENT + "生成二叉树");
BinaryTree bTree = new BinaryTree(TREE_CONTENT); System.out.print("二叉树前序遍历结果:");
bTree.traverseBefore(false); System.out.print("\n二叉树中序遍历结果:");
bTree.traverseMiddle(false); System.out.print("\n二叉树后序遍历结果:");
bTree.traverseAfter(false); System.out.print("\n二叉树层序遍历结果:");
bTree.traverseCeng(); System.out.println("\n二叉树深度:" + bTree.getBTreeDepth()); System.out.println("二叉树中节点个数:" + bTree.size());
}
}

  运行结果:

根据字符串A B D # G # # E # # C # F H # # #生成二叉树
二叉树前序遍历结果:ABD#G##E##C#FH###
二叉树中序遍历结果:#D#G#B#E#A#C#H#F#
二叉树后序遍历结果:###G##E###HFC
二叉树层序遍历结果:ABCDE#F#G##H#####
二叉树深度:4
二叉树中节点个数:8

【数据结构】之二叉树(Java语言描述)的更多相关文章

  1. 数据结构与抽象 Java语言描述 第4版 pdf (内含标签)

    数据结构与抽象 Java语言描述 第4版 目录 前言引言组织数据序言设计类P.1封装P.2说明方法P.2.1注释P.2.2前置条件和后置条件P.2.3断言P.3Java接口P.3.1写一个接口P.3. ...

  2. 《数据结构与算法分析-Java语言描述》 分享下载

    书籍信息 书名:<数据结构与算法分析-Java语言描述> 原作名:Data Structures and Algorithm Analysis in Java 作者: 韦斯 (Mark A ...

  3. 读书笔记:《数据结构与算法分析Java语言描述》

    目录 第 3 章 表.栈和队列 3.2 表 ADT 3.2.1 表的简单数组实现 3.2.2 简单链表 3.3 Java Collections API 中的表 3.3.1 Collection 接口 ...

  4. 数据结构(java语言描述)

    概念性描述与<数据结构实例教程>大同小异,具体参考:http://www.cnblogs.com/bookwed/p/6763300.html. 概述 基本概念及术语 数据 信息的载体,是 ...

  5. 数据结构(Java语言描述)-第一章:概述

    第一章 概述 1.0 序言 自己为啥要学数据结构嘞,我觉得主要有以下三个原因: 前段时间在看并发编程时,发现aqs,corrunthashmap等底层都用到了数据结构,主要的有队列,还有链表,学习数据 ...

  6. C语言学习书籍推荐《数据结构与算法分析:C语言描述(原书第2版)》下载

    维斯 (作者), 冯舜玺 (译者) <数据结构与算法分析:C语言描述(原书第2版)>内容简介:书中详细介绍了当前流行的论题和新的变化,讨论了算法设计技巧,并在研究算法的性能.效率以及对运行 ...

  7. 数据结构与算法分析——C语言描述 第三章的单链表

    数据结构与算法分析--C语言描述 第三章的单链表 很基础的东西.走一遍流程.有人说学编程最简单最笨的方法就是把书上的代码敲一遍.这个我是头文件是照抄的..c源文件自己实现. list.h typede ...

  8. 三元组表压缩存储稀疏矩阵实现稀疏矩阵的快速转置(Java语言描述)

    三元组表压缩存储稀疏矩阵实现稀疏矩阵的快速转置(Java语言描述) 用经典矩阵转置算法和普通的三元组矩阵转置在时间复杂度上都是不乐观的.快速转置算法在增加适当存储空间后实现快速转置具体原理见代码注释部 ...

  9. 利用栈实现算术表达式求值(Java语言描述)

    利用栈实现算术表达式求值(Java语言描述) 算术表达式求值是栈的典型应用,自己写栈,实现Java栈算术表达式求值,涉及栈,编译原理方面的知识.声明:部分代码参考自茫茫大海的专栏. 链栈的实现: pa ...

随机推荐

  1. quartus使用串口IP模块

    在quartus平台中使用串口模块的IP,需要使用到platform designer软件来实现. 1.在quartus界面调出IP Catalog界面. 2.在IP catalog中搜索UART,找 ...

  2. SpringBoot整合Redis在可视化工具乱码问题,以及常用的api

     pom依赖: <parent> <groupId>org.springframework.boot</groupId> <artifactId>spr ...

  3. 使用ASP.NET Core 3.x 构建 RESTful API - 1.准备工作

    以前写过ASP.NET Core 2.x的REST API文章,今年再更新一下到3.0版本. 先决条件 我在B站有一个非常入门的ASP.NET Core 3.0的视频教程,如果您对ASP.NET Co ...

  4. mock和axios常见的传参方式

    第一次接手项目,传参方式还有些吃力,因此做一下总结. 首先我们需要会看swagger中的接口.里面写了某个接口需要接收什么样的值,前端怎么传递这个值 在mock中的传参方式: mock中传参的方式有两 ...

  5. MySQL的统计信息学习总结

    统计信息概念 MySQL统计信息是指数据库通过采样.统计出来的表.索引的相关信息,例如,表的记录数.聚集索引page个数.字段的Cardinality.....MySQL在生成执行计划时,需要根据索引 ...

  6. 学习笔记39_EF的DAL层(精)

    通用的分页查询 public IQueryable<UserInfo> GetPage<T>(int pageSize,int pageIndex,out int total, ...

  7. 学习笔记50_mongodb

    MongoVUE,MongoDB可视化客户端: 添加一个连接: 数据库下就是集合. 实际上是json数据的集合 Mongodb->数据库->文档集合:相当于表->文档:相当于表里面的 ...

  8. csps60爆零记

    整场考试心态是崩的,T1水题打了半天表,将近两个小时才A掉. T2数据结构题想麻烦了,码了5.1K(数据结构选手) 等到最后一刻我发现T3水题,生无可恋.jpg 然后吃屎地在暴力中输出了下标,(%%% ...

  9. 用python实现对元素的长截图

    一.目标 浏览网页的时候,看见哪个元素,就能截取哪个元素当图片,不管那个元素有多长 二.所用工具和第三方库 python ,PIL,selenium pycharm 三.代码部分 长截图整体思路: 1 ...

  10. node.js 需要注意知识点

    复习node.js 需要注意知识点--(重点) 2.1:参数传递获取造型 客户端脚手架(发)    (参数传递)    node.js(收) -发ajax  this.axios.get(" ...