前序遍历,中序遍历,后序遍历二叉树 ( 递归非递归方法 )

 /** 
     * 前序遍历递归解法:  
     * (1)如果二叉树为空,空操作  
     * (2)如果二叉树不为空,访问根节点,前序遍历左子树,前序遍历右子树 
     */ 
    public static void preorderTraversalRec(TreeNode root) {  
        if (root == null) {  
            return;  
        }  
        System.out.print(root.val + " ");  
        preorderTraversalRec(root.left);  
        preorderTraversalRec(root.right);  
    }  
       
    /** 
     *  前序遍历迭代解法1:用一个辅助stack,总是把右孩子放进栈 
     *  http://www.youtube.com/watch?v=uPTCbdHSFg4 
     */ 
    public static void preorderTraversal(TreeNode root) {  
        if(root == null){  
            return;  
        }  
           
        Stack<TreeNode> stack = new Stack<TreeNode>();      // 辅助stack  
        stack.push(root);  
           
        while( !stack.isEmpty() ){  
            TreeNode cur = stack.pop();     // 出栈栈顶元素  
            System.out.print(cur.val + " ");  
               
            // 关键点:要先压入右孩子,再压入左孩子,这样在出栈时会先打印左孩子再打印右孩子  
            if(cur.right != null){  
                stack.push(cur.right);  
            }  
            if(cur.left != null){  
                stack.push(cur.left);  
            }  
        }  
    }  

前序遍历迭代法2:
while(root!=null){
  while(root!=null){
    systom.out.print(root);
    stack.push(root);
    root=root.left;
}
root=stack.pop();
while(root.right==null){
  root=stack.pop();
}
root=root.right;
}

/** * 中序遍历递归解法 * (1)如果二叉树为空,空操作。 * (2)如果二叉树不为空,中序遍历左子树,访问根节点,中序遍历右子树 */ 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<TreeNode> stack = new Stack<TreeNode>(); TreeNode cur = root; while( true ){ while(cur != null){ // 先添加一个非空节点所有的左孩子到栈 stack.push(cur); cur = cur.left; } if(stack.isEmpty()){ break; } // 因为此时已经没有左孩子了,所以输出栈顶元素 cur = stack.pop(); System.out.print(cur.val + " ");
       每个节点的下一个节点是这个节点的右节点的最左节点,右节点没有左节点就是右节点,没有右节点就是栈中弹出的节点) cur
= cur.right; // 准备处理右子树 } } /** * 后序遍历递归解法 * (1)如果二叉树为空,空操作 * (2)如果二叉树不为空,后序遍历左子树,后序遍历右子树,访问根节点 */ 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 * */ public static void postorderTraversal(TreeNode root) { if (root == null) { return; } Stack<TreeNode> s = new Stack<TreeNode>(); // 第一个stack用于添加node和它的左右孩子 Stack<TreeNode> output = new Stack<TreeNode>();// 第二个stack用于翻转第一个stack输出
(从s弹出一个加入output,并把弹出的左右加入s,循环。)

s.push(root);
while( !s.isEmpty() ){ // 确保所有元素都被翻转转移到第二个stack TreeNode cur = s.pop(); // 把栈顶元素添加到第二个stack output.push(cur); if(cur.left != null){ // 把栈顶元素的左孩子和右孩子分别添加入第一个stack s.push(cur.left); } if(cur.right != null){ s.push(cur.right); } } while( !output.isEmpty() ){ // 遍历输出第二个stack,即为后序遍历 System.out.print(output.pop().val + " "); } } /** * 分层遍历二叉树(按层次从上往下,从左往右)迭代 * 相当于广度优先搜索,使用队列实现。队列初始化,将根节点压入队列。当队列不为空,进行如下操作:弹出一个节点 * ,访问,若左子节点或右子节点不为空,将其压入队列 */ public static void levelTraversal(TreeNode root) { if (root == null) { return; } LinkedList<TreeNode> queue = new LinkedList<TreeNode>(); queue.push(root); while (!queue.isEmpty()) { TreeNode cur = queue.removeFirst(); System.out.print(cur.val + " "); if (cur.left != null) { queue.add(cur.left); } if (cur.right != null) { queue.add(cur.right); } } }

 

posted @ 2015-04-03 15:11  无天666  阅读(416)  评论(0编辑  收藏  举报