二叉树可以通过递归调用和非递归调用
其中,递归调用,分为先序遍历、中序遍历和后续遍历,还有非递归调用的前序遍历、中序遍历和后续遍历(通过压栈的方式实现) ,具体实现如下:
1. /** 递归实现前序遍历 */
2. protected static void preorder(Node p) {
3. if (p != null) {
4. visit(p);
5. preorder(p.getLeft());
6. preorder(p.getRight());
7. }
8. }
9.
10. /** 递归实现中序遍历 */
11. protected static void inorder(Node p) {
12. if (p != null) {
13. inorder(p.getLeft());
14. visit(p);
15. inorder(p.getRight());
16. }
17. }
18.
19. /** 递归实现后序遍历 */
20. protected static void postorder(Node p) {
21. if (p != null) {
22. postorder(p.getLeft());
23. postorder(p.getRight());
24. visit(p);
25. }
26. }
27.
28.
29. /**********************************************************************************************/
30. /** 非递归实现前序遍历 */
31. protected static void iterativePreorder(Node p) {
32. Stack<Node> stack = new Stack<Node>();
33. if (p != null) {
34. stack.push(p);
35. while (!stack.empty()) {
36. p = stack.pop();
37. visit(p);
38. if (p.getRight() != null)
39. stack.push(p.getRight());
40. if (p.getLeft() != null) //为什么p.getLeft() 在后,getRight()在前应为while 循环第一句就是pop visit所以要把left放上,先访问。之中方法是即压即访问法。
41. stack.push(p.getLeft());
42. }
43. }
44. }
45.
46. /** 非递归实现中序遍历 */ //思路与上面iterativePreorder 一致。
47. protected static void iterativeInorder(Node p) {
48. Stack<Node> stack = new Stack<Node>();
49. while (p != null) {
50. while (p != null) {
51. if (p.getRight() != null)
52. stack.push(p.getRight());// 当前节点右子入栈
53. stack.push(p);// 当前节点入栈
54. p = p.getLeft();
55. }
56. p = stack.pop();
57. while (!stack.empty() && p.getRight() == null) {
58. visit(p);
59. p = stack.pop();
60. }
61. visit(p);
62. if (!stack.empty())
63. p = stack.pop();
64. else
65. p = null;
66. }
67. }
68.
69. /*******************************************************************************************/
70.
71. /*******************************************************************************************/
72. /** 非递归实现前序遍历2 */
73. protected static void iterativePreorder2(Node p) {
74. Stack<Node> stack = new Stack<Node>();
75. Node node = p;
76. while (node != null || stack.size() > 0) {
77. while (node != null) {//压入所有的左节点,压入前访问它。左节点压入完后pop访问右节点。像这样算法时思考规律性的东西在哪。不管哪个节点都要压所节点判断右节点。
78. visit(node);
79. stack.push(node);
80. node = node.getLeft();
81. }
82. if (stack.size() > 0) {//
83. node = stack.pop();
84. node = node.getRight();
85. }
86. }
87. }
88.
89. /** 非递归实现中序遍历2 */
90. protected static void iterativeInorder2(Node p) {
91. Stack<Node> stack = new Stack<Node>();
92. Node node = p;
93. while (node != null || stack.size() > 0) {
94. while (node != null) {
95. stack.push(node);
96. node = node.getLeft();
97. }
98. if (stack.size() > 0) {
99. node = stack.pop();
100. visit(node); //与iterativePreorder2比较只有这句话的位置不一样,弹出时再访问。
101. node = node.getRight();
102. }
103. }
104. }