二叉树的遍历

二叉树说明

二叉树是一种非常重要的数据结构,很多其它数据结构都是基于二叉树的基础演变而来的。对于二叉树,有深度遍历和广度遍历,深度遍历有前序、中序以及后序三种遍历方法, 广度遍历即我们平常所说的层次遍历。因为树的定义本身就是递归定义,因此采用递归的方法去实现树的三种遍历不仅容易理解而且代码很简洁,而对于广度遍历来说, 需要其他数据结构的支撑,比如堆了。

前序遍历

遍历方式:根结点 —> 左子树 —> 右子树
下面展示 代码片.

// 二叉树结构实体
public class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;

    public TreeNode() {
    }

    TreeNode(int x) { val = x; }

    public TreeNode(int val, TreeNode left, TreeNode right) {
        this.val = val;
        this.left = left;
        this.right = right;
    }
}

    /**
     * 前序遍历(递归)
     * @param root
     * @param endList
     * @return
     */
    public static List<Integer> inorderTraversal5(TreeNode root,List<Integer> endList) {

        if(null != root){
            endList.add(root.val);
            inorderTraversal(root.left,endList);
            inorderTraversal(root.right,endList);
        }
        return endList;
    }

    /**
     * 二叉树前序遍历(迭代)
     * @param root
     * @param endList
     * @return
     */
    public static List<Integer> inorderTraversal2(TreeNode root,List<Integer> endList) {
        Deque<TreeNode> stack = new ArrayDeque<>();
        TreeNode pNode = root;
        while (null != pNode || !stack.isEmpty()){
            if(pNode != null){
                endList.add(pNode.val);
                stack.push(pNode);
                pNode = pNode.left;
            }else {
                TreeNode node = stack.pop();
                pNode = node.right;
            }
        }
        return endList;
    }

中序遍历

遍历方式:左子树—> 根结点 —> 右子树
下面展示 代码片.


    /**
     * 中序遍历(递归)
     * @param root
     * @param endList
     * @return
     */
    public static List<Integer> inorderTraversal(TreeNode root,List<Integer> endList) {

        if(null != root){
            inorderTraversal(root.left,endList);
            endList.add(root.val);
            inorderTraversal(root.right,endList);
        }
        return endList;
    }

    /**
     * 二叉树中序遍历(迭代)
     * @param root
     * @param endList
     * @return
     */
    public static List<Integer> inorderTraversal1(TreeNode root,List<Integer> endList) {
        Deque<TreeNode> stack = new ArrayDeque<>();
        TreeNode pNode = root;
        while (null != pNode || !stack.isEmpty()){
            if(pNode != null){
                stack.push(pNode);
                pNode = pNode.left;
            }else {
                TreeNode node = stack.pop();
                endList.add(node.val);
                pNode = node.right;
            }
        }
        return endList;
    }

后序遍历

遍历方式:左子树 —> 右子树 —> 根结点
下面展示 代码片.


    /**
     * 后序遍历
     * @param root
     * @param endList
     * @return
     */
    public static List<Integer> inorderTraversal4(TreeNode root,List<Integer> endList) {

        if(null != root){
            inorderTraversal(root.left,endList);
            inorderTraversal(root.right,endList);
            endList.add(root.val);
        }
        return endList;
    }
        /**
     * 二叉树后序遍历
     * @param root
     * @param endList
     * @return
     */
    public static List<Integer> inorderTraversal3(TreeNode root,List<Integer> endList) {
        Deque<TreeNode> stack = new ArrayDeque<>();
        TreeNode pNode = root;
        TreeNode pre = null;
        while (null != pNode || !stack.isEmpty()){
            while (null != pNode){
                stack.push(pNode);
                pNode = pNode.left;
            }
            if(!stack.isEmpty()){
                pNode = stack.pop();
                if(pNode.right == null || pre == pNode.right){
                    endList.add(pNode.val);
                    pre = pNode;
                    pNode = null;
                }else {
                    stack.push(pNode);
                    pNode = pNode.right;
                }
            }
        }
        return endList;
    }

总结

1.递归的缺点:
操作耗时,因为牵涉到大量的入栈出栈操作;
有可能导致线程栈溢出,因为递归调用占用了线程栈很大的空间。
2.递归转非递归
首先,我们要自己模拟一个栈;
然后,找到边界条件;
最后,朝着边界条件的方向缩小问题规模;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值