数据结构之树(Tree)_二叉树的创建及遍历概述
Posted fanglongxiang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构之树(Tree)_二叉树的创建及遍历概述相关的知识,希望对你有一定的参考价值。
树的第一部分(数据结构之树(Tree)(一)_树的基础)介绍了树的各个基础:什么是树、树的特点、树的表示方法、树的种类、树在存储结构中的表示、树/森林/二叉树之间的转换(原理)等。
这部分主要介绍下二叉树的创建及遍历(一种实现,主要了解二叉树遍历的过程)。遍历是二叉树重要的运算,是其他运算的基础。树、森林都可以转换成二叉树进行运算。
由于树的内容比较多,实现多样。关于二叉树的多种创建实现、二叉树的多种遍历(非递归、广度优先、深度优先等)实现、树转二叉树的实现 等后续整理总结。
二叉树遍历概述
根据二叉树的根结点及左、右子树遍历的次序,二叉树的遍历主要有3种方式。
- 先序遍历
先遍历根结点,再遍历左子树,最后遍历右子树。 - 中序遍历
先遍历左子树,再遍历根结点,最后遍历右子树。 - 后序遍历
先遍历左子树,再遍历右子树,最后遍历根结点。
如图,是一颗二叉树。遍历都是递归的方式。
先序遍历:ABDGHCEFI
中序遍历:BGDHAECIF
后序遍历:GHDBEIFCA
二叉树遍历的一种实现
二叉树先序遍历 创建树
上图看到的图像表示,人看了很容易理解。但在程序中需要通过一定规则实现它,这就需要创建树。(根据输入或者要求,创建实现方法多样,这里采用一种,多种创建方法后续总结。)
单个遍历结果(先序或者中序或者后序)无法确定一棵树的唯一样子。主要是单种遍历方式结果,你无法知道某个结点是否有孩子结点 还是仅有某个孩子结点,所以如果用#表示结点孩子结点不存在的位置,即某结点某方向在此停止,这样树的结构就确定了。然后通过这样的结果来创建树。
这样上图,先序遍历的结果就是:AB#DG##H##CE##FI###
注意:每个结点如果孩子结点不存在都要用#表示,即使是叶子结点也需要。
实现参考下面代码中的方法:createBinaryTree()。
创建及遍历的实现
具体看代码和注释,很容易理解:
public class BinaryTree {
//二叉树结点定义:数据、左孩子、右孩子。
static class BinaryNode {
Object data;
BinaryNode leftChild, rightChild;
public BinaryNode(Object data) {
this.data = data;
this.leftChild = this.rightChild = null;
}
}
//根结点
static BinaryNode root;
public BinaryTree() {
root = null;
}
//用于先序遍历创建树的输入
static char[] treeNodes = "AB#DG##H##CE##FI###".toCharArray();
static int index = -1;
//创建二叉树
public static BinaryNode createBinaryTree() throws Exception {
BinaryNode newBinaryNode = null;
index++;
if (treeNodes[index] != ‘#‘) {
newBinaryNode = new BinaryNode(treeNodes[index]);
newBinaryNode.leftChild = createBinaryTree();
newBinaryNode.rightChild = createBinaryTree();
}
//当碰到# 即newBinaryNode为null,即父结点没有某个孩子结点(左孩子或右孩子) 那条分支到这停止了。
return newBinaryNode;
}
//先序遍历
public static void preOrderTraversal(BinaryNode node) {
if (node == null)
return;
System.out.print(node.data + " ");
preOrderTraversal(node.leftChild);
preOrderTraversal(node.rightChild);
}
//中序遍历
public static void inOrderTraversal(BinaryNode node) {
if (node == null)
return;
inOrderTraversal(node.leftChild);
System.out.print(node.data + " ");
inOrderTraversal(node.rightChild);
}
//后序遍历
public static void postOrderTraversal(BinaryNode node) {
if (node == null)
return;
postOrderTraversal(node.leftChild);
postOrderTraversal(node.rightChild);
System.out.print(node.data + " ");
}
public static void main(String[] args) {
try {
//创建二叉树,返回根结点
root = createBinaryTree();
System.out.println("创建成功!");
} catch (Exception e) {
System.out.println("创建失败,请检查输入是否有误!");
e.printStackTrace();
}
//分别用3种遍历方式,打印结果
System.out.println("先序遍历:");
preOrderTraversal(root);
System.out.println();
System.out.println("中序遍历:");
inOrderTraversal(root);
System.out.println();
System.out.println("后序遍历:");
postOrderTraversal(root);
}
}
从代码中看到输入的就是 AB#DG##H##CE##FI### ,让我们看下执行结果:
创建成功!
先序遍历:
A B D G H C E F I
中序遍历:
B G D H A E C I F
后序遍历:
G H D B E I F C A
从结果看创建成功,遍历结果也与开始的一致:
先序遍历:ABDGHCEFI
中序遍历:BGDHAECIF
后序遍历:GHDBEIFCA
以上是关于数据结构之树(Tree)_二叉树的创建及遍历概述的主要内容,如果未能解决你的问题,请参考以下文章