定义二叉树节点类
public class TreeNode {
//key为二叉树的节点的值
int key;
TreeNode left;
TreeNode right;
public TreeNode(int key) {
this.key = key;
left = null;
right = null;
}
}
构建测试用二叉树
其实前,中,后序的区别在于遍历根(父)节点与其左右节点的顺序不同,前序位先遍历根节点,中序为第二遍历根节点,后序为最后遍历根节点。
前序遍历结果(根,左,右):
中序遍历结果(左,根,右):
后序遍历结果(左,右,根):
根据上图我们可以得到前中后序遍历的结果为:
前:1 2 4 5 3 6
中:
后:
代码如下:
public static void main(String[] args) {
//构建一棵二叉树
TreeNode a = new TreeNode(1);
TreeNode b = new TreeNode(2);
TreeNode c = new TreeNode(3);
TreeNode d = new TreeNode(4);
TreeNode e = new TreeNode(5);
TreeNode f = new TreeNode(6);
a.left=b;
a.right=c;
b.left=d;
b.right=e;
c.left=f;
}
前序遍历
//前序遍历
public void static preOrder(TreeNode node){
if (node == null){
return;
}
//顺序为根节点-->递归左节点-->递归右节点
System.out.print(node.key+" ");
preOrder(node.left);
preOrder(node.right);
}
思路分析:
递归代码非常简洁,但可能并不是非常好理解。我们已经知道先序遍历的顺序为根,左,右,而二叉树的每一个节点(原始根节点除外)又可以理解为一棵子树的根。例如:
- 节点2可以理解为子树 2, 4,5的根
- 节点3可以理解为子树3, 6, null的根
- 节点6可以理解为没有子节点的“根”
因此当我们要前序遍历上述中的二叉树时,我们首先要访问根节点,即node 1。
之后根据 “根,左,右”的遍历顺序,下一个应该被访问的应为node 1的左节点,即为node 2。 node 2作为子树(2, 4, 5)的根节点,已经被访问,根据 “根,左,右”的顺序。下一个被访问的应该node 2的左节点,即为node 4。node 4作为没有子节点的“根”(叶子节点),已经没有节点可以遍历,此时便退回上级方法,即其父节点node 2调用的方法。
在node 2调用方法时,子树(2, 4, 5)中的2已经作为根节点被访问,4作为其左节点已经被访问,根据 “根,左,右”的顺序,对于子树(2, 4,5)仅剩作为右节点的node 5没有被访问,因此此时应当访问node 5。
依次类推,直到所有调用方法都结束。
控制台输出结果:
中序遍历
道理同上,只是遍历顺序为**“左,根,右”**,因此我们只需要调整递归调用的顺序即可,代码如下:
//中序遍历
public static void inOrder(TreeNode node){
if (node == null){
return;
}
//顺序为递归左节点-->根节点-->递归右节点
inOrder(node.left);
System.out.print(node.key+" ");
inOrder(node.right);
}
后序遍历
public static void postOrder(TreeNode node){
if (node == null){
return;
}
//顺序为递归左节点-->递归右节点-->根节点
postOrder(node.left);
postOrder(node.right);
System.out.print(node.key+" ");
}
测试类
public static void main(String[] args) {
//构建一棵二叉树
TreeNode a = new TreeNode(1);
TreeNode b = new TreeNode(2);
TreeNode c = new TreeNode(3);
TreeNode d = new TreeNode(4);
TreeNode e = new TreeNode(5);
TreeNode f = new TreeNode(6);
a.left=b;
a.right=c;
b.left=d;
b.right=e;
c.left=f;
System.out.print("前序遍历结果:");
preOrder(a);
System.out.println();
System.out.print("中序遍历结果:");
inOrder(a);
System.out.println();
System.out.print("后序遍历结果:");
postOrder(a);
}
控制台输出结果: