数据结构 二叉树的后序,层序遍历法(递归与非递归两种实现)

树的生成见上一篇博客

后序遍历:

1.遍历左边节点,到左叶子节点后返回父节点,切换到右子树

2.遍历右边结点,遍历完后回到父节点

记忆:左右根

例子(注意,这里的树和我创建的树不一样!!!):


代码实现:

后序遍历的递归实现

 public static void postOrderRecursion(TreeNode T) {
        if (T == null) {
            return;
        }
        postOrderRecursion(T.lchild);
        postOrderRecursion(T.rchild);
        System.out.print(T.value + " ");
    }

 

后序遍历的非递归实现: 

实现思路:由于是左右中的遍历顺序,当遍历完一个子树后需要判断(若为左子树则切换到右子树,若为右子树则切换到左子树)。新建一个栈来保存结点的状态。当结点不为空时,遍历其左子树直到最左结点,切换到右子树,再遍历右子树中各个结点的左子节点,循环。到了左叶子节点或右子树的叶子节点,则栈二顶部为right,弹出栈一顶部的结点值。

 public static void postOrderNormal(TreeNode T) {
        //后序遍历
        int left = 1;//在辅助栈里表示左节点
        int right = 2;//在辅助栈里表示右节点
        Stack<TreeNode> stack1 = new Stack<>();
        Stack<Integer> stack2 = new Stack<>();//辅助栈,用于判断子节点返回值

        while (T != null || !stack1.isEmpty()) {
            while (T != null) {
                //将节点压住栈1,并在栈2将节点标记为左节点
                //若到了左叶子节点,判断右兄弟,若为空,直接在第二个循环里返回值
                //若有右兄弟,继续判断左子节点,压栈循环
                stack1.push(T);
                stack2.push(left);
                T = T.lchild;
            }

            while (!stack1.isEmpty() && stack2.peek() == right) {
                //如果是右子节点返回父节点,则任务完成,将两个栈顶弹出
                //若没有右子节点,也一样
                stack2.pop();
                System.out.print(stack1.pop().value + " ");
            }

            if (!stack1.isEmpty() && stack2.peek() == left) {
                //如果是从左子节点 返回父节点,则将标记改为右子节点
                stack2.pop();
                stack2.push(right);
                T = stack1.peek().rchild;
            }
        }
    }

总结:

后序遍历比较麻烦,主要原因是需要对子树的状态进行判断,再进行顺序的递归。


层序遍历:

按照树的深度从上到下,从左到右遍历

采用队列实现

先把根节点加到队列(队列的特性,加到队尾,从对头删除)

抛出对头的元素,把他的左右儿子加到队列

一层遍历完后队列中剩下的是这层的下一层的全部结点

例子:

 


代码实现:

 public static void levelOrderNormal(TreeNode T) {
        //add()和remove()方法在失败的时候会抛出异常(不推荐)
        if (T == null) return;
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(T);
        while (!queue.isEmpty()) {

            TreeNode p = queue.poll();//从对头删除并得到元素
            System.out.print(p.value + " ");

            if (p.lchild != null) {
                queue.offer(p.lchild);
            }

            if (p.rchild != null) {
                queue.offer(p.rchild);
            }
        }
    }

结果:

总结:

层序遍历用队列还是很好实现的,只要知道队列的特性就好

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值