数据结构之二叉树的遍历

二叉树的遍历是指按照某条搜索路径访问树中的每个节点,使得每个节点的均只被访问一次。由二叉树的递归定义,遍历一棵二叉树便要决定对根节点、左子树和右子树的访问顺序。常见的遍历次序有先序遍历、中序遍历和后序遍历。其中序指的是根节点在何时被访问。

  1. 先序遍历(PreOrder):若二叉树非空,则先访问根节点,再访问左子树,最后访问右子树。

  2. 中序遍历(InOrder):若二叉树非空,则先访问左子树,再访问根节点,最后访问右子树。

  3. 后序遍历(PostOder):若二叉树非空,则先访问左子树,再访问右子树,最后访问根节点。

节点结构如下:

 1 /**
 2  * 二叉树节点结构
 3  * Created by Administrator on 2017/5/2 0002.
 4  */
 5 public class TreeNode {
 6     public int val;
 7     public TreeNode left;
 8     public TreeNode right;
 9     public TreeNode(int x){
10         this.val = x;
11     }
12 }

自定义节点处理函数:

1 /*对每个节点进行处理*/
2 public static void process(int v){
3     System.out.println(v);
4 }

先序遍历

1 /*递归形式*/
2 public static void preOrder(TreeNode root){
3         if(root == null){
4             return;
5         }
6         process(root.val);
7         preOrder(root.left);
8         preOrder(root.right);
9     }
 1 //非递归形式,借助栈
 2     public static void preOrder2(TreeNode root) {
 3 
 4         if (root == null) {
 5             return;
 6         }
 7 
 8         Stack<TreeNode> stack = new Stack<>();
 9 
10         while (root != null || !stack.isEmpty()) {
11             while (root != null) {
12                 print(root.val);
13                 stack.push(root);
14                 root = root.left;
15             }
16 
17             if (!stack.isEmpty()) {
18                 root = stack.peek();
19                 stack.pop();
20                 root = root.right;
21             }
22         }
23     }

中序遍历

 1 /*递归形式*/
 2 public static void inOrder(TreeNode root){
 3     if(root == null){
 4         return;
 5     }
 6     if(root.left != null){
 7         inOrder(root.left);
 8     }
 9     process(root.val);
10     if(root.right != null){
11         inOrder(root.right);
12     }    
13 }
 1 /*非递归形式*/
 2 public static void inOrder(TreeNode root){
 3     if(root == null){
 4         return;
 5     }
 6     Stack<TreeNode> st = new Stack<TreeNode>();
 7     st.push(root);
 8     TreeNode tmp;
 9     while (!st.empty()){
10         tmp = st.peek();
11         while (tmp != null){
12             st.push(tmp.left);
13             tmp = tmp.left;
14         }
15         if(tmp == null){
16             st.pop();
17         }
18         if(!st.empty()) {
19             tmp = st.pop();
20             process(tmp.val);
21             st.push(tmp.right);
22         }
23     }
24 }

后序遍历

 1 /*递归形式*/
 2 public static void postOrder(TreeNode root){
 3     if(root == null){
 4         return;
 5     }
 6     if(root.left != null){
 7         postOrder(root.left);
 8     }
 9     if(root.right != null){
10         postOrder(root.right);
11     }
12     process(root.val);
13 }
 1 /*后序非递归形式*/
 2 public static void postOrder(TreeNode root){
 3    if (root == null) {
 4             return;
 5         }
 6 
 7         Stack<TreeNode> stack = new Stack<>();
 8         TreeNode node = root;
 9         //最后访问的节点
10         TreeNode lastVisit = root;
11         while (node != null || !stack.isEmpty()) {
12 
13             //左子树入栈
14             while (node != null) {
15                 stack.push(node);
16                 node = node.left;
17             }
18 
19             //查看当前栈顶元素
20             node = stack.peek();
21 
22             //如果其右子树也为空,或者右子树已经访问
23             //则可以直接输出当前节点的值
24             if (node.right == null || node.right == lastVisit) {
25                 print(node.val);
26                 stack.pop();
27                 lastVisit = node;
28                 node = null;
29             } else {
30                 //否则遍历右子树
31                 node = node.right;
32             }
33         }
34 }

 

posted @ 2017-05-03 21:55  凌风1205  阅读(248)  评论(0编辑  收藏  举报
//一下两个链接最好自己保存下来,再上传到自己的博客园的“文件”选项中