【总结】二叉树的前、中、后序遍历的递归实现与非递归JAVA实现

一、二叉树的前序遍历

1、递归实现1:Traverse

public List<Integer> preorderTraversal(TreeNode root) {
        // write your code here
        List<Integer> list = new ArrayList<>();
        
        preorderTraversal(root , list);
        
        return list;
    }
    
    public void preorderTraversal(TreeNode root , List<Integer> list){
        if(root == null)
            return;
        
        list.add(root.val);
        preorderTraversal(root.left , list);
        preorderTraversal(root.right , list);
    }

2、递归实现2:Divide & Conquer

/**
 * Definition of TreeNode:
 * public class TreeNode {
 *     public int val;
 *     public TreeNode left, right;
 *     public TreeNode(int val) {
 *         this.val = val;
 *         this.left = this.right = null;
 *     }
 * }
 */

public class Solution {
    /**
     * @param root: A Tree
     * @return: Preorder in ArrayList which contains node values.
     */
    public List<Integer> preorderTraversal(TreeNode root) {
        // write your code here
        List<Integer> list = new ArrayList<>();
        
        if(root == null)
            return list;
            
        //Divide
        List<Integer> left = preorderTraversal(root.left);
        List<Integer> right = preorderTraversal(root.right);
        
        //Conquer
        list.add(root.val);
        list.addAll(left);
        list.addAll(right);
        
        return list;
    }
}

3、非递归实现1

  • 利用栈实现循环先序遍历二叉树

  • * 这种实现类似于图的深度优先遍历(DFS)

  • * 维护一个栈,将根节点入栈,然后只要栈不为空,出栈并访问,接着依次将访问节点的右节点、左节点入栈。

  • * 这种方式应该是对先序遍历的一种特殊实现(看上去简单明了),但是不具备很好的扩展性,在中序和后序方式中不适用

public List<Integer> preorderTraversal(TreeNode root) {
        // write your code here
        List<Integer> list = new ArrayList<>();
        if(root == null)
            return list;
            
        Stack<TreeNode> stack = new Stack<>();
        stack.push(root);
        
        while(!stack.isEmpty()){
            TreeNode node = stack.pop();
            list.add(node.val);
            
            //注意这里先压右栈,再压左栈,与前序遍历相反
            if(node.right != null)
                stack.push(node.right);
            if(node.left != null)
                stack.push(node.left);
        }
        
        return list;
    }

4、非递归实现2

* 利用栈模拟递归过程实现循环先序遍历二叉树

* 这种方式具备扩展性,它模拟递归的过程,将左子树点不断的压入栈,直到null,然后处理栈顶节点的右子树

/**
 * Definition of TreeNode:
 * public class TreeNode {
 *     public int val;
 *     public TreeNode left, right;
 *     public TreeNode(int val) {
 *         this.val = val;
 *         this.left = this.right = null;
 *     }
 * }
 */

public class Solution {
    /**
     * @param root: A Tree
     * @return: Preorder in ArrayList which contains node values.
     */
    public List<Integer> preorderTraversal(TreeNode root) {
        // write your code here
        List<Integer> list = new ArrayList<>();
        Stack<TreeNode> stack = new Stack<>();
        
        while(root != null || !stack.isEmpty()){
            //将二叉树左半部分先访问再入栈
            while(root != null){
                list.add(root.val);
                stack.push(root);
                root = root.left;
            }
            root = stack.pop();
            root = root.right;//如果是null,出栈并处理右子树
        }
        
        return list;
    }
}

二、二叉树的中序遍历

1、递归实现1:Traverse

public List<Integer> inorderTraversal(TreeNode root) {
        // write your code here
        List<Integer> list = new ArrayList<>();
        
        inorderTraversal(root , list);
        
        return list;
    }
    
    public void inorderTraversal(TreeNode root , List<Integer> list){
        if(root == null)
            return;
        
        inorderTraversal(root.left , list);
        list.add(root.val);
        inorderTraversal(root.right , list);
    }

2、递归实现2:Divide & Conquer

/**
 * Definition of TreeNode:
 * public class TreeNode {
 *     public int val;
 *     public TreeNode left, right;
 *     public TreeNode(int val) {
 *         this.val = val;
 *         this.left = this.right = null;
 *     }
 * }
 */

public class Solution {
    /**
     * @param root: A Tree
     * @return: Inorder in ArrayList which contains node values.
     */
    public List<Integer> inorderTraversal(TreeNode root) {
        // write your code here
        List<Integer> list = new ArrayList<>();
        
        if(root == null)
            return list;
            
        List<Integer> left = inorderTraversal(root.left);
        List<Integer> right = inorderTraversal(root.right);
        
        list.addAll(left);
        list.add(root.val);
        list.addAll(right);
        
        return list;
    }
    
}

3、非递归实现

  1. 利用栈模拟递归过程实现循环中序遍历二叉树

  2. * 思想和二叉树前序遍历非递归实现2相同,只是访问的时间是在左子树都处理完直到null的时候出栈并访问。

/**
 * Definition of TreeNode:
 * public class TreeNode {
 *     public int val;
 *     public TreeNode left, right;
 *     public TreeNode(int val) {
 *         this.val = val;
 *         this.left = this.right = null;
 *     }
 * }
 */

public class Solution {
    /**
     * @param root: A Tree
     * @return: Inorder in ArrayList which contains node values.
     */
    public List<Integer> inorderTraversal(TreeNode root) {
        // write your code here
        List<Integer> list = new ArrayList<>();
        Stack<TreeNode> stack = new Stack<>();
        
        while(root != null || !stack.isEmpty()){
            //将二叉树左半部分压栈
            while(root != null){
                stack.push(root);
                root = root.left;
            }
            root = stack.pop();
            list.add(root.val);
            root = root.right;//如果是null,出栈并处理右子树
        }
        
        return list;
    }
    
}

三、二叉树的后序遍历

1、递归实现1:Traverse

/**
 * Definition of TreeNode:
 * public class TreeNode {
 *     public int val;
 *     public TreeNode left, right;
 *     public TreeNode(int val) {
 *         this.val = val;
 *         this.left = this.right = null;
 *     }
 * }
 */

public class Solution {
    /**
     * @param root: A Tree
     * @return: Postorder in ArrayList which contains node values.
     */
    public List<Integer> postorderTraversal(TreeNode root) {
        // write your code here
        List<Integer> list = new ArrayList<>();
        
        postorderTraversal(root , list);
        
        return list;
    }
    
    private void postorderTraversal(TreeNode root , List<Integer> list){
        if(root == null)
            return;
            
        postorderTraversal(root.left , list);
        postorderTraversal(root.right , list);
        list.add(root.val);
    }
}

2、递归实现2:Divide & Conquer

/**
 * Definition of TreeNode:
 * public class TreeNode {
 *     public int val;
 *     public TreeNode left, right;
 *     public TreeNode(int val) {
 *         this.val = val;
 *         this.left = this.right = null;
 *     }
 * }
 */

public class Solution {
    /**
     * @param root: A Tree
     * @return: Postorder in ArrayList which contains node values.
     */
    public List<Integer> postorderTraversal(TreeNode root) {
        // write your code here
        List<Integer> list = new ArrayList<>();
        
        if(root == null)
            return list;
            
        List<Integer> left = postorderTraversal(root.left);
        List<Integer> right = postorderTraversal(root.right);
        
        list.addAll(left);
        list.addAll(right);
        list.add(root.val);
        
        return list;
    }

}

3、非递归实现。这里由于根最后访问,需要特殊记录根节点,如果直接套用之前的模拟栈算法比较麻烦。但我们观察到后序遍历为“左右根”,如果倒序“根右左”,则只需要在前序遍历基础上稍加更改即可。所以实现思路是:先遍历根右,再遍历左,最后将得到的结果反向就好了。

/**
 * Definition of TreeNode:
 * public class TreeNode {
 *     public int val;
 *     public TreeNode left, right;
 *     public TreeNode(int val) {
 *         this.val = val;
 *         this.left = this.right = null;
 *     }
 * }
 */

public class Solution {
    /**
     * @param root: A Tree
     * @return: Postorder in ArrayList which contains node values.
     */
    public List<Integer> postorderTraversal(TreeNode root) {
        // write your code here
        List<Integer> res = new ArrayList<>();
        Stack<TreeNode> stack = new Stack<>();
        
        while (root != null || !stack.isEmpty()) {
            //将二叉树右半部分先访问再入栈
            while (root != null) {
                res.add(root.val);
                stack.push(root);
                root = root.right;
            }
            
            root = stack.pop();
            root = root.left;
        }
        
        Collections.reverse(res);
        return res;
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值