原来一直以为二叉树遍历没有什么难度,直到最近发现没有搞太清晰。所以我用Java来实现了一下,来捋顺思路。
首先创建一个二叉树:
package com.company;
/**
* Created by wuguangzu on 14-10-4.
*/
public class BinaryTree {
int data;//根节点数据
BinaryTree left;//左子树
BinaryTree right;//右子树
//构造函数实例化二叉树
public BinaryTree(int data) {
this.data = data;
left = null;
right = null;
}
//向二叉树中插入节点
public void insert(BinaryTree root, int data){
if(data < root.data){//二叉树的左节点比根节点小
if(root.left == null){
root.left = new BinaryTree(data);//左节点为空,则生成左节点
}else {
this.insert(root.left, data);//递归调用,插入左节点
}
}else {
if(data > root.data){//二叉树的右节点比根节点大
if(root.right == null){
root.right = new BinaryTree(data);//右节点为空,则生成右节点
}else {
this.insert(root.right, data);//不为空则递归调用,插入右节点
}
}
}
}
}
然后就可以创建二叉树实例,并实现二叉树的先序遍历、中序遍历、后序遍历:
package com.company;
/**
* Created by wuguangzu on 14-10-4.
*/
public class BinaryTreeTraversal {
//先序遍历(又称作先根遍历,下同)
public static void preTraversal(BinaryTree root){
if (root != null){
System.out.print(root.data + "-");
preTraversal(root.left);
preTraversal(root.right);
}
}
//中序遍历
public static void inOrderTraversal(BinaryTree root){
if (root != null){
inOrderTraversal(root.left);
System.out.print(root.data + "-");
inOrderTraversal(root.right);
}
}
//后序遍历
public static void postTraversal(BinaryTree root){
if (root != null){
postTraversal(root.left);
postTraversal(root.right);
System.out.print(root.data + "-");
}
}
public static void main(String args[]){
int arr[] = {23,14,54,45,36,7,22,12,79};
BinaryTree root = new BinaryTree(arr[0]);//创建一个二叉树
for(int i=0; i<arr.length; i++){
root.insert(root, arr[i]);//向二叉树中插入数据
}
System.out.println("先序遍历:");
preTraversal(root);
System.out.println();
System.out.println("中序遍历:");
inOrderTraversal(root);
System.out.println();
System.out.println("后序遍历:");
postTraversal(root);
}
}
输出结果:
先序遍历:
23-14-7-12-22-54-45-36-79-
中序遍历:
7-12-14-22-23-36-45-54-79-
后序遍历:
12-7-22-14-36-45-79-54-23-
练习:
1)可以通过其先序遍历和中序遍历推导出图的形状,用后序遍历验证。2)改变数组的输出顺序可以改变图的形状,以此练习推导二叉树图。
如果搞不定可以参考下面的例子:
在网上找了一个带有附图的二叉树,其图如下:
数组定义为:
int arr[] = {12,76,35,22,16,48,90,46,9,40};
输出结果:
先序遍历:
12-9-76-35-22-16-48-46-40-90-
中序遍历:
9-12-16-22-35-40-46-48-76-90-
后序遍历:
9-16-22-40-46-48-35-90-76-12-
推导:
1)根据先序遍历确定根节点为12。
2)那么中序遍历中12前面的为左子树,后面的为树的右子树。
3)左子树只有一个叶子节点,根据先序遍历,先根,后左右,则9为12的左节点,76为右节点。
4)左子树的数据肯定小于根节点,右子树大于根节点,那么只有90是76的右节点。
5)看中序遍历
16-22-35-40-46-48
有可能是全部都是只有左叶子节点的左子树,但是先序遍历中
12-9-76-35
说明35是一个有左右子树的根节点,那么以此划分。
递归此思路可解决类似问题。