1、分析

        二叉树的深度优先遍历的非递归的通用做法是采用栈,广度优先遍历的非递归的通用做法是采用队列。

        深度优先遍历:对每一个可能的分支路径深入到不能再深入为止,而且每个结点只能访问一次。要特别注意的是,二叉树的深度优先遍历比较特殊,可以细分为先序遍历、中序遍历、后序遍历。具体说明如下:



  • 先序遍历:对任一子树,先访问根,然后遍历其左子树,最后遍历其右子树。
  • 中序遍历:对任一子树,先遍历其左子树,然后访问根,最后遍历其右子树。
  • 后序遍历:对任一子树,先遍历其左子树,然后遍历其右子树,最后访问根。

        广度优先遍历:又叫层次遍历,从上往下对每一层依次访问,在每一层中,从左往右(也可以从右往左)访问结点,访问完一层就进入下一层,直到没有结点可以访问为止。

2、举例说明

        对下图所示的二叉排序树进行遍历,要求使用先序遍历(递归、非递归)、中序遍历(递归、非递归)、后序遍历(递归、非递归)和广度优先遍历。

深度优先遍历 栈实现 java 深度优先遍历 树_结点

2.1、参考代码


[java]  
1. package BinaryTreeTraverseTest;  
2.   
3. import java.util.LinkedList;  
4. import java.util.Queue;  
5.   
6. /**
7.  * 二叉树的深度优先遍历和广度优先遍历
8.  * @author Fantasy
9.  * @version 1.0 2016/10/05 - 2016/10/07
10.  */  
11. public class BinaryTreeTraverseTest {  
12. public static void main(String[] args) {  
13.           
14. new BinarySortTree<Integer>();  
15.           
16. 35);  
17. 20);  
18. 15);  
19. 16);  
20. 29);  
21. 28);  
22. 30);  
23. 40);  
24. 50);  
25. 45);  
26. 55);  
27.           
28. "先序遍历(递归):");  
29.         tree.preOrderTraverse(tree.getRoot());  
30.         System.out.println();  
31. "中序遍历(递归):");  
32.         tree.inOrderTraverse(tree.getRoot());  
33.         System.out.println();  
34. "后序遍历(递归):");  
35.         tree.postOrderTraverse(tree.getRoot());  
36.         System.out.println();  
37.           
38. "先序遍历(非递归):");  
39.         tree.preOrderTraverseNoRecursion(tree.getRoot());  
40.         System.out.println();  
41. "中序遍历(非递归):");  
42.         tree.inOrderTraverseNoRecursion(tree.getRoot());  
43.         System.out.println();  
44. "后序遍历(非递归):");  
45.         tree.postOrderTraverseNoRecursion(tree.getRoot());  
46.         System.out.println();  
47.           
48. "广度优先遍历:");  
49.         tree.breadthFirstTraverse(tree.getRoot());  
50.     }  
51. }  
52.   
53. /**
54.  * 结点
55.  */  
56. class Node<E extends Comparable<E>> {  
57.       
58.     E value;  
59.     Node<E> left;  
60.     Node<E> right;  
61.       
62.     Node(E value) {  
63. this.value = value;  
64. null;  
65. null;  
66.     }  
67.       
68. }  
69.   
70. /**
71.  * 使用一个先序序列构建一棵二叉排序树(又称二叉查找树)
72.  */  
73. class BinarySortTree<E extends Comparable<E>> {  
74.       
75. private Node<E> root;  
76.       
77.     BinarySortTree() {  
78. null;  
79.     }  
80.       
81. public void insertNode(E value) {     
82. if (root == null) {  
83. new Node<E>(value);  
84. return;  
85.         }      
86.         Node<E> currentNode = root;  
87. while (true) {  
88. if (value.compareTo(currentNode.value) > 0) {  
89. if (currentNode.right == null) {  
90. new Node<E>(value);  
91. break;  
92.                 }  
93.                 currentNode = currentNode.right;  
94. else {  
95. if (currentNode.left == null) {  
96. new Node<E>(value);  
97. break;  
98.                 }  
99.                 currentNode = currentNode.left;  
100.             }  
101.         }  
102.     }  
103.       
104. public Node<E> getRoot(){  
105. return root;  
106.     }  
107.   
108. /**
109.      * 先序遍历二叉树(递归)
110.      * @param node
111.      */  
112. public void preOrderTraverse(Node<E> node) {  
113. " ");  
114. if (node.left != null)  
115.             preOrderTraverse(node.left);  
116. if (node.right != null)  
117.             preOrderTraverse(node.right);  
118.     }  
119.       
120. /**
121.      * 中序遍历二叉树(递归)
122.      * @param node
123.      */  
124. public void inOrderTraverse(Node<E> node) {  
125. if (node.left != null)  
126.             inOrderTraverse(node.left);  
127. " ");  
128. if (node.right != null)  
129.             inOrderTraverse(node.right);  
130.     }  
131.       
132. /**
133.      * 后序遍历二叉树(递归)
134.      * @param node
135.      */  
136. public void postOrderTraverse(Node<E> node) {  
137. if (node.left != null)  
138.             postOrderTraverse(node.left);  
139. if (node.right != null)  
140.             postOrderTraverse(node.right);  
141. " ");  
142.     }  
143.       
144. /**
145.      * 先序遍历二叉树(非递归)
146.      * @param root
147.      */  
148. public void preOrderTraverseNoRecursion(Node<E> root) {  
149. new LinkedList<Node<E>>();  
150. null;  
151.         stack.push(root);  
152. while (!stack.isEmpty()) {  
153.             currentNode = stack.pop();  
154. " ");  
155. if (currentNode.right != null)  
156.                 stack.push(currentNode.right);  
157. if (currentNode.left != null)  
158.                 stack.push(currentNode.left);  
159.         }  
160.     }  
161.       
162. /**
163.      * 中序遍历二叉树(非递归)
164.      * @param root
165.      */  
166. public void inOrderTraverseNoRecursion(Node<E> root) {  
167. new LinkedList<Node<E>>();  
168.         Node<E> currentNode = root;  
169. while (currentNode != null || !stack.isEmpty()) {  
170. // 一直循环到二叉排序树最左端的叶子结点(currentNode是null)  
171. while (currentNode != null) {  
172.                 stack.push(currentNode);  
173.                 currentNode = currentNode.left;  
174.             }  
175.             currentNode = stack.pop();  
176. " ");  
177.             currentNode = currentNode.right;  
178.         }     
179.     }  
180.       
181. /**
182.      * 后序遍历二叉树(非递归)
183.      * @param root
184.      */  
185. public void postOrderTraverseNoRecursion(Node<E> root) {  
186. new LinkedList<Node<E>>();  
187.         Node<E> currentNode = root;  
188. null;  
189. while (currentNode != null || !stack.isEmpty()) {  
190. // 一直循环到二叉排序树最左端的叶子结点(currentNode是null)  
191. while (currentNode != null) {  
192.                 stack.push(currentNode);  
193.                 currentNode = currentNode.left;  
194.             }  
195.             currentNode = stack.pop();  
196. // 当前结点没有右结点或上一个结点(已经输出的结点)是当前结点的右结点,则输出当前结点  
197. while (currentNode.right == null || currentNode.right == rightNode) {  
198. " ");  
199.                 rightNode = currentNode;  
200. if (stack.isEmpty()) {  
201. return; //root以输出,则遍历结束  
202.                 }  
203.                 currentNode = stack.pop();  
204.             }  
205. //还有右结点没有遍历  
206.             currentNode = currentNode.right;  
207.         }  
208.     }  
209.       
210. /**
211.      * 广度优先遍历二叉树,又称层次遍历二叉树
212.      * @param node
213.      */  
214. public void breadthFirstTraverse(Node<E> root) {  
215. new LinkedList<Node<E>>();  
216. null;  
217.         queue.offer(root);  
218. while (!queue.isEmpty()) {  
219.             currentNode = queue.poll();  
220. " ");  
221. if (currentNode.left != null)  
222.                 queue.offer(currentNode.left);  
223. if (currentNode.right != null)  
224.                 queue.offer(currentNode.right);  
225.         }  
226.     }  
227.       
228. }




2.2、输出结果


先序遍历(递归):35 20 15 16 29 28 30 40 50 45 55 
中序遍历(递归):15 16 20 28 29 30 35 40 45 50 55 
后序遍历(递归):16 15 28 30 29 20 45 55 50 40 35 
先序遍历(非递归):35 20 15 16 29 28 30 40 50 45 55 
中序遍历(非递归):15 16 20 28 29 30 35 40 45 50 55 
后序遍历(非递归):16 15 28 30 29 20 45 55 50 40 35 
广度优先遍历:35 20 40 15 29 50 16 28 30 45 55