树的遍历总结 (包括递归,非递归2种解法),轻松理解后序遍历

参考大神的神作:http://blog.csdn.net/fightforyourdream/article/details/16843303 

对于后序遍历,我们理解为将右节点为先的先序遍历翻转,会思考上简单很多,就是用右节点为先的先序遍历做,再用第二个栈进行翻转,就是后序遍历。

/*
     * 3. 前序遍历,中序遍历,后序遍历: preorderTraversalRec, preorderTraversal, inorderTraversalRec, postorderTraversalRec 
     * (https://en.wikipedia.org/wiki/Tree_traversal#Pre-order_2)
     * */
    public static void preorderTraversalRec(TreeNode root) {
        if (root == null) {
            return;
        }
        
        System.out.print(root.val + " ");
        preorderTraversalRec(root.left);
        preorderTraversalRec(root.right);
    }
    
    /*
     * 前序遍历,Iteration 算法. 把根节点存在stack中。
     * */
    public static void preorderTraversal(TreeNode root) {
        if (root == null) {
            return;
        }
        
        Stack
   
   
    
     s = new Stack
    
    
     
     ();
        s.push(root);
        
        while (!s.isEmpty()) {
            TreeNode node = s.pop();
            System.out.print(node.val + " ");
            if (node.right != null) { //
                s.push(node.right);
            }
            
            // 我们需要先压入右节点,再压入左节点,这样就可以先弹出左节点。 
            if (node.left != null) {
                s.push(node.left);
            }                       
        }
    }
    
    /*
     * 中序遍历
     * */
    public static void inorderTraversalRec(TreeNode root) {
        if (root == null) {
            return;
        }
        
        inorderTraversalRec(root.left);
        System.out.print(root.val + " ");
        inorderTraversalRec(root.right);
    }
    
    /** 
     * 中序遍历迭代解法 ,用栈先把根节点的所有左孩子都添加到栈内, 
     * 然后输出栈顶元素,再处理栈顶元素的右子树 
     * http://www.youtube.com/watch?v=50v1sJkjxoc 
     *  
     * 还有一种方法能不用递归和栈,基于线索二叉树的方法,较麻烦以后补上 
     * http://www.geeksforgeeks.org/inorder-tree-traversal-without-recursion-and-without-stack/ 
     */  
    public static void inorderTraversal(TreeNode root) {
        if (root == null) {
            return;
        }
        
        Stack
     
     
      
       s = new Stack
      
      
       
       ();
        
        TreeNode cur = root;
        
        while(true) {
            // 把当前节点的左节点都push到栈中.
            while (cur != null) {
                s.push(cur);
                cur = cur.left;
            }
            
            if (s.isEmpty()) {
                break;
            }
            
            // 因为此时已经没有左孩子了,所以输出栈顶元素 
            cur = s.pop();
            System.out.print(cur.val + " ");
            
            // 准备处理右子树  
            cur = cur.right;            
        }
    }
    
    // 后序遍历
    /*
     *      1  
           / \  
          2   3  
         / \   \  
        4   5   6
        
        if put into the stack directly, then it should be:
        1, 2, 4, 5, 3, 6 in the stack.
        when pop, it should be: 6, 3, 5, 4, 2, 1
        
        if I 
     * */
    
    public static void postorderTraversalRec(TreeNode root) {
        if (root == null) {
            return;
        }
        
        postorderTraversalRec(root.left);
        postorderTraversalRec(root.right);
        System.out.print(root.val + " ");
    }
    
    /** 
     *  后序遍历迭代解法 
     *  http://www.youtube.com/watch?v=hv-mJUs5mvU 
     *  http://blog.csdn.net/tang_jin2015/article/details/8545457
     *  从左到右的后序 与从右到左的前序的逆序是一样的,所以就简单喽! 哈哈
     *  用另外一个栈进行翻转即可喽 
     */ 
    public static void postorderTraversal(TreeNode root) {
        if (root == null) {
            return;
        }
        
        Stack
       
       
         s = new Stack 
        
          (); Stack 
         
           out = new Stack 
          
            (); s.push(root); while(!s.isEmpty()) { TreeNode cur = s.pop(); out.push(cur); if (cur.left != null) { s.push(cur.left); } if (cur.right != null) { s.push(cur.right); } } while(!out.isEmpty()) { System.out.print(out.pop().val + " "); } } /* * 分层遍历二叉树(按层次从上往下,从左往右)迭代 * 其实就是广度优先搜索,使用队列实现。队列初始化,将根节点压入队列。当队列不为空,进行如下操作:弹出一个节点 * ,访问,若左子节点或右子节点不为空,将其压入队列 * */ public static void levelTraversal(TreeNode root) { if (root == null) { return; } Queue 
           
             q = new LinkedList 
            
              (); q.offer(root); while (!q.isEmpty()) { TreeNode cur = q.poll(); System.out.print(cur.val + " "); if (cur.left != null) { q.offer(cur.left); } if (cur.right != null) { q.offer(cur.right); } } } public static void levelTraversalRec(TreeNode root) { ArrayList 
              
              
                > ret = new ArrayList 
                
                
                  >(); levelTraversalVisit(root, 0, ret); System.out.println(ret); } /** * 分层遍历二叉树(递归) * 很少有人会用递归去做level traversal * 基本思想是用一个大的ArrayList,里面包含了每一层的ArrayList。 * 大的ArrayList的size和level有关系 * * http://discuss.leetcode.com/questions/49/binary-tree-level-order-traversal#answer-container-2543 */ public static void levelTraversalVisit(TreeNode root, int level, ArrayList 
                  
                  
                    > ret) { if (root == null) { return; } // 如果ArrayList的层数不够用, 则新添加一层 // when size = 3, level: 0, 1, 2 if (level >= ret.size()) { ret.add(new ArrayList 
                   
                     ()); } // visit 当前节点 ret.get(level).add(root.val); // 将左子树, 右子树添加到对应的层。 levelTraversalVisit(root.left, level + 1, ret); levelTraversalVisit(root.right, level + 1, ret); } 
                    
                   
                  
                 
                
               
              
             
            
           
          
         
       
      
      
     
     
    
    
   
   
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值