【C++】非递归实现二叉树的前中后序遍历

简介: 【C++】非递归实现二叉树的前中后序遍历

👉二叉树的前序遍历👈


前序遍历的顺序是根、左子树、右子树。那么首先访问的一定是左路节点,再来访问左路节点的右子树。而访问左路节点的右子树又可以看成一个子问题,那么就能像递归访问整棵树了。


思路:

想定义一个栈st、一个vector v和一个TreeNode* cur,cur初始化为root。

当cur不为空或者st不为空时,while继续。while循环里做一下操作:左路节点入栈的同时尾插到v中,那么左路节点就访问完了。然后取出栈顶节点top,将cur置为top->right,这样就可以转化成子问题去访问左路节点的右子树了。

cur不为空表示要访问一棵树,st不为空表示还有左路节点的右子树没有访问。两个同时为空时,while循环结束,得到正确的前序遍历。

注:一个节点出栈意味着这个节点及其左子树已经访问完了,还剩右子树没有访问。


8448a4c704784db0a9ba8a932d3af556.png

class Solution 
{
public:
    vector<int> preorderTraversal(TreeNode* root) 
    {
        stack<TreeNode*> st;
        vector<int> v;
        TreeNode* cur = root;
        // cur 不为空表示要访问一棵树
        // st 不为空表示还有右子树没有访问
        while(cur || !st.empty())
        {
            // 开始访问整棵树
            // 1.访问左路节点
            while(cur)
            {
                v.push_back(cur->val);
                st.push(cur);
                cur = cur->left;
            }
            // 转化成子问题:访问左路节点的右子树
            TreeNode* top = st.top();
            st.pop();
            cur = top->right;   // 子问题访问右子树
        }
        return v;
    }
};


f8f3cb8fef7846fe99cefc2a56eec70d.png


👉二叉树的中序遍历👈


中序遍历的顺序是左子树、根、右子树。首先,和中序遍历一样的是左路节点入栈,入栈的同时不能访问该节点,即不能将节点的值尾插到vector中。当左路节点出栈时,表示当前节点的左子树已经访问完了,开始访问当前节点及其右子树。


class Solution 
{
public:
    vector<int> inorderTraversal(TreeNode* root) 
    {
        stack<TreeNode*> st;
        vector<int> v;
        TreeNode* cur = root;
        while(cur || !st.empty())
        {
            // 1.左路节点入栈
            while(cur)
            {
                st.push(cur);
                cur = cur->left;
            }
            // 2.当左路节点出栈时,表示左子树已经访问过了,应该
            // 访问这个节点和它的右子树
            TreeNode* top = st.top();
            st.pop();
            v.push_back(top->val);  // 访问这个节点
            cur = top->right;   // 转化成子问题访问右子树
        }
        return v;
    }
};

b6207e09aa4b420e9678182573f604d3.png


👉二叉树的后序遍历👈


后序遍历的顺序是左子树、右子树、根,需要将左子树和右子树访问完了,才能访问根。如果栈顶节点为空或者栈顶节点的右子树已经访问过了,就可以访问栈顶节点了。为了知道是否已经访问过栈顶节点的右子树,我们可以通过prev来记录上一次访问的节点。当prev等于top->right时,表示栈顶节点的右子树已经访问过了,可以弹出栈顶节点并访问它。


4849d797230e42df9909c7cd33f69ffe.png

class Solution 
{
public:
    vector<int> postorderTraversal(TreeNode* root) 
    {
        vector<int> v;
        stack<TreeNode*> st;
        TreeNode* cur = root;
        TreeNode* prev = nullptr;
        while(cur || !st.empty())
        {
            // 左路节点入栈
            while(cur)
            {
                st.push(cur);
                cur = cur->left;
            }
            TreeNode* top = st.top();   // 取栈顶节点但不pop
            // 栈顶节点右子树为空或者上一次访问的节点是top右子树的根,说明右子树已经访问过了
            // 可以访问栈顶节点,否则转换成子问题访问top的右子树
            if(top->right == nullptr || top->right == prev)
            {
                st.pop();
                v.push_back(top->val);
                prev = top;
                cur = nullptr;  // cur为空表示弹出的栈顶节点没有右子树或者右子树已经访问过了
            }
            else
                cur = top->right;
        }
        return v;
    }
};


a5bac6be2fb447c0b2c38ff018de6c73.png


👉总结👈


本篇的非递归实现二叉树的前中后序遍历都差不多是一个思路,左路节点先入栈。最大的区别就是栈顶节点的访问时机不同。那么以上就是本篇博客的全部内容了,如果大家觉得有收获的话,可以点个三连支持一下!谢谢大家!💖💝❣️










相关文章
|
6天前
|
C++
二叉树进阶面试题(精华总结)【C++版本】
二叉树进阶面试题(精华总结)【C++版本】
|
6天前
|
存储 编译器 数据库
【C/C++ 数据结构 】线索二叉树全解析:从数学原理到C++实现
【C/C++ 数据结构 】线索二叉树全解析:从数学原理到C++实现
59 0
|
6天前
|
算法 C++ 开发者
【C/C++ 数据结构 】二叉树基本性质:对于任何一颗二叉树T,若其终端结点为n0 ,那么度数为2的结点数为n2。则n0=n2+1...
【C/C++ 数据结构 】二叉树基本性质:对于任何一颗二叉树T,若其终端结点为n0 ,那么度数为2的结点数为n2。则n0=n2+1...
20 0
|
6天前
|
设计模式 中间件 程序员
【C/C++ 奇异递归模板模式 】C++中CRTP模式(Curiously Recurring Template Pattern)的艺术和科学
【C/C++ 奇异递归模板模式 】C++中CRTP模式(Curiously Recurring Template Pattern)的艺术和科学
27 3
|
6天前
|
C++
C++ 递归与面向对象编程基础
C++ 递归是函数自我调用的技术,用于简化复杂问题。以递归求和为例,`sum` 函数通过不断调用自身累加数字直到 `k` 为 0。递归需谨慎,避免无限循环和资源浪费。面向对象编程(OOP)将程序划分为交互对象,具有属性和方法,提升代码复用、维护和扩展性。C++ OOP 基本概念包括类、对象、属性和方法。通过创建类和对象,利用点语法访问成员,实现代码组织。
24 0
|
6天前
|
开发工具 对象存储 Android开发
对象存储oss使用问题之C++使用OSS SDK时遍历OSS上的文件时崩溃如何解决
《对象存储OSS操作报错合集》精选了用户在使用阿里云对象存储服务(OSS)过程中出现的各种常见及疑难报错情况,包括但不限于权限问题、上传下载异常、Bucket配置错误、网络连接问题、跨域资源共享(CORS)设定错误、数据一致性问题以及API调用失败等场景。为用户降低故障排查时间,确保OSS服务的稳定运行与高效利用。
34 0
|
6天前
|
存储 C++
二叉树的操作(C++实现)
二叉树的操作(C++实现)
|
6天前
|
存储 C++
【C++练级之路】【Lv.14】二叉搜索树(进化的二叉树——BST)
【C++练级之路】【Lv.14】二叉搜索树(进化的二叉树——BST)
【C++练级之路】【Lv.14】二叉搜索树(进化的二叉树——BST)
|
6天前
|
存储 算法 数据管理
C++中利用随机策略优化二叉树操作效率的实现方法
C++中利用随机策略优化二叉树操作效率的实现方法
78 1
|
6天前
|
算法 C++ 开发者
【C/C++ 数据结构 】二叉树基本性质:具有n个结点的完全二叉树的深度为[log2n]+1或者[log2(n+1)]...
【C/C++ 数据结构 】二叉树基本性质:具有n个结点的完全二叉树的深度为[log2n]+1或者[log2(n+1)]...
16 0