非递归方式实现二叉树的前、中、后序遍历

简介: 非递归方式实现二叉树的前、中、后序遍历

二叉树的前序遍历


虽然我们说的是不用递归的方式实现,但是我们的思路还是模拟递归的实现,那么我们如何不用递归来模拟实现递归呢?我们要想模拟递归,我们需要知道实现递归的底层逻辑是什么?递归实际上是通过栈这个数据结构来实现的,我们都知道递归的顺序是先完成后递归的,这也就跟栈先进后出的原理是类似的,所以我们想模拟递归,也需要借用栈这个数据结构。


在知道了原理之后,我们接下来就需要知道怎么样来实现了,因为这里是前序遍历,先遍历根节点,然后是左子树,最后是右子树,所以我们先遍历左子树,并且在遍历的同时我们将遍历的节点存储在栈中并打印,方便我们找到节点的右子树。当我们的root遍历到为null时,就说明左树遍历完了,我们就将栈顶的节点弹出,将root等于弹出节点的右子树,直到root等于null并且栈为空时完成遍历。

1.png

2.png

3.png

节点6的右树也为null,所以我们弹出栈顶的元素,cur = top.right,继续上面操作。

4.png

5.png

6.png

7.png

public void preOrderNor(TreeNode root) {
        if(root == null) {
            return;
        }
        TreeNode cur = root;
        Deque<TreeNode> stack = new ArrayDeque<>();
        while(cur != null || !stack.isEmpty()) {
            while(cur != null) {
                stack.push(cur);
                System.out.println(cur.val);
                cur = cur.left;
            }
            TreeNode top = stack.pop();
            cur = top.right;
        }
    }

二叉树的中序遍历

中序遍历的思路跟前序遍历的思路是一样的,只是打印的顺序不同,我们在从栈中弹出节点的同时打印。

public void inOrderNor(TreeNode root) {
        if(root == null) {
            return;
        }
        Deque<TreeNode> stack = new ArrayDeque<>();
        TreeNode cur = root;
        while(cur != null || !stack.isEmpty()) {
            while(cur != null) {
                stack.push(cur);
                cur = cur.left;
            }
            TreeNode top = stack.pop();
            System.out.println(top.val);
            cur = top.right;
        }
    }

二叉树的后序遍历

后序遍历的思路跟前序和中序的思路是不同的,我们需要判断什么时候该打印,因为是后序遍历,所以我们需要在遍历完右树或者右树为null的时候在遍历根节点。

8.png

9.png

10.png

11.png

12.png

public void postOrderNor(TreeNode root) {
        if(root == null) {
            return;
        }
        TreeNode cur = root;
        TreeNode prev = null;
        Deque<TreeNode> stack = new ArrayDeque<>();
        while(cur != null || !stack.isEmpty()) {
            while(cur != null) {
                stack.push(cur);
                cur = cur.left;
            }
            TreeNode top = stack.peek();
            if(top.right == null || top.right == prev) {
                System.out.println(top.val);
                stack.pop();
                prev = top;
            }else {
                cur = top.right;
            }
        }
    }


相关文章
|
人工智能 搜索推荐 物联网
如何训练个人的Gpt4ALL
如何训练个人的Gpt4ALL
4056 0
如何训练个人的Gpt4ALL
|
7月前
|
自然语言处理 前端开发 Cloud Native
吐血整理Bolt.diy 部署与应用攻略
Bolt.diy 是一款无需代码基础即可创建个性化网站的工具,基于阿里云函数计算 FC 和百炼大模型服务,通过自然语言交互实现全栈开发。用户只需描述需求,Bolt.diy 即可快速生成网站,支持灵活定制与二次开发。部署简单,提供免费试用额度,适合从初学者到专业开发者各类人群。无论是快速原型设计、教育工具开发还是企业级应用,Bolt.diy 均展现出高效与便捷的优势。然而,新手可能需要更多时间熟悉云服务配置与高级功能。
680 3
|
11月前
|
API 网络架构
一文带你了解 Flutter 路由
一文带你了解 Flutter 路由
385 5
|
7月前
|
前端开发 机器人 API
答疑机器人实践:AgentScope多智能体带你玩转多源召回
答疑机器人实践:AgentScope多智能体带你玩转多源召回
335 3
答疑机器人实践:AgentScope多智能体带你玩转多源召回
|
9月前
|
计算机视觉
YOLOv11改进策略【卷积层】| CGblock 内容引导网络 利用不同层次信息,提高多类别分类能力 (含二次创新)
YOLOv11改进策略【卷积层】| CGblock 内容引导网络 利用不同层次信息,提高多类别分类能力 (含二次创新)
401 0
|
SQL 物联网 大数据
TDengine的主要特性有哪些?
【5月更文挑战第13天】TDengine的主要特性有哪些?
370 10
|
关系型数据库 MySQL 数据库
开发者如何使用云数据库RDS
【10月更文挑战第4天】开发者如何使用云数据库RDS
822 1
|
存储 监控 安全
邮件告警通知
【10月更文挑战第20天】
|
网络架构
为什么udp流设置1316字节
为什么udp流设置1316字节
329 0
|
编译器 API C语言
在x86架构汇编语言中函数参数传递的三种约定
在x86架构汇编语言中函数参数传递的三种约定
648 2