二叉树的先序遍历顺序是根、左、右;中序遍历顺序是左、根、右;后序遍历顺序是左、右、根。
递归方式实现如下:
1 public class TreeNode {
2 private int value;
3 private TreeNode left, right;
4
5 public TreeNode(int data) {
6 value = data;
7 }
8
9 // 递归方式实现先序遍历
10 public void preorder(TreeNode treeNode) {
11 if (treeNode == null) {
12 return;
13 }
14
15 System.out.println(treeNode.value + " ");
16 preorder(treeNode.left);
17 preorder(treeNode.right);
18 }
19
20 // 递归方式实现中序遍历
21 public void inorder(TreeNode treeNode) {
22 if (treeNode == null) {
23 return;
24 }
25
26 inorder(treeNode.left);
27 System.out.println(treeNode.value + " ");
28 inorder(treeNode.right);
29 }
30
31 // 递归方式实现后序遍历
32 public void postorder(TreeNode treeNode) {
33 if (treeNode == null) {
34 return;
35 }
36
37 postorder(treeNode.left);
38 postorder(treeNode.right);
39 System.out.println(treeNode.value + " ");
40 }
41 }
递归方式能解决的问题都能用非递归方式来解决,因为递归方式通过函数栈来保存信息,普通的栈或队列也能达到相同效果。
非递归方式实现先序遍历,参考【经典面试题二】二叉树的递归与非递归遍历(前序、中序、后序)。
非递归方式实现中序遍历,步骤如下:
1 如果当前结点为空,则结束。
2 创建实现了Deque接口的LinkedList对象,引用为stack。
3 当前结点入栈,左孩子结点不断入栈,直到没有左孩子结点。
4 栈顶结点出栈,打印其结点值。如果有右孩子结点,则把它设为当前结点;否则,重复该步骤,直到有右孩子结点或者stack为空。
5 重复步骤3和4。
Java代码:
1 // 非递归方式实现中序遍历
2 public void inOrder(TreeNode cur) {
3 if (cur != null) {
4 Deque<TreeNode> stack = new LinkedList<TreeNode>();
5 while (true) {
6 // 已保证当前结点非空
7 stack.addFirst(cur);
8 for (cur = cur.left; cur != null; cur = cur.left) {
9 stack.addFirst(cur);
10 }
11
12 while (true) {
13 // 当前结点出栈并打印
14 cur = stack.removeFirst();
15 System.out.println(cur.value + " ");
16
17 TreeNode right = cur.right;
18 if (right != null) {
19 cur = right;
20 break;
21 } else if (stack.isEmpty()) {
22 return;
23 }
24 }
25 }
26 }
27 }
非递归方式实现后序遍历,步骤如下:
1 如果当前结点为空,则结束。
2 创建两个实现了Deque接口的LinkedList对象,引用分别为stack1和stack2。
3 当前结点入栈stack1。
4 stack1栈顶结点出栈,该结点入栈stack2,该结点的非空左右孩子结点入栈stack1。
5 重复步骤4,直到stack1为空。
6 stack2栈顶结点出栈,打印其结点值,重复该步骤,直到stack2为空。
Java代码:
1 // 非递归方式实现后序遍历
2 public void postOrder(TreeNode cur) {
3 if (cur != null) {
4 Deque<TreeNode> stack1 = new LinkedList<TreeNode>();
5 Deque<TreeNode> stack2 = new LinkedList<TreeNode>();
6
7 stack1.addFirst(cur);
8 while (!stack1.isEmpty()) {
9 cur = stack1.removeFirst();
10 stack2.addFirst(cur);
11
12 TreeNode left = cur.left, right = cur.right;
13 if (left != null) {
14 stack1.addFirst(left);
15 }
16 if (right != null) {
17 stack1.addFirst(right);
18 }
19 }
20
21 while (!stack2.isEmpty()) {
22 System.out.println(stack2.removeFirst().value + " ");
23 }
24 }
25 }
参考资料
《程序员代码面试指南 IT名企算法与数据结构题目最优解》P88-95