非递归实现二叉树遍历

简介: 非递归实现二叉树遍历

Traversal

注意stack弹出的顺序决定是如何遍历


先序

思路

  1. 取二叉树根节点入栈
  2. pop栈顶数据Top
  3. 先入Top右,再入Top

重复2、3步骤,直到栈为空


实现

void PreOrderUnRecur(Node* root)
{
    if(root != null)
    {
        stack<Node*> cons;
        cons.push(root);
        while(!cons.empty())
        {
            Node* Top = cons.top();
            cons.pop();
            cout << Top->value << " ";
            if(Top->right) cons.push(Top->right);
            if(Top->left) cons.push(Top->left);
        }
    }
}


后序

思路

使用两个栈 conshelp

  1. 根节点入栈cons
  2. pop数据Tophelp
  3. 先入Top左,再入Top右,均入cons

重复步骤2、3,直到cons没有数据,依次拿出help中的数据


实现

void PostOrderUnRecur(Node* root)
{
    if(root != null)
    {
        stack<Node*> cons;
        stack<Node*> help;
        cons.push(root);
        while(!cons.empty())
        {
            Node* Top = cons.top();
            cons.pop();
            help.push(Top);
            if(Top->left) cons.push(Top->left);
            if(Top->right) cons.push(Top->right);
        }
        while(!help.empty())
        {
            Node* val = help.top();
            help.pop();
            cont << val->value << " ";
        }
    }
}


总结

栈入数据的顺序是和弹出时的顺序是相反的。

弹出的顺序即决定是先序遍历还是后续遍历

先序遍历 -- -- 头左右 -- -- 要求入栈顺序:头右左

后序遍历 -- -- 左右头 -- -- 要求入栈顺序:头左右 -- -- 得到出栈顺序:头右左 -- -- help反转出栈顺序


中序

思路

首先根节点的所有左节点入栈

  • pop节点Top,把Top节点的右子树的左节点入栈

重复上面的步骤,直到栈为空


实现

void InOrderUnRecur(Node* root)
{
    if(root != nullptr)
    {
        stack<Node*> cons;
        Node* cur = root;
        while(!cons.empty() || cur != nullptr)
        {
            if(cur == nullptr)
            {
                Node* Top = cons.top();
                cons.pop();
                cout << Top->value <<" ";
                cur = Top->right;
            }
            else
            {
                cons.push(cur);
                cur = cur->left;
            }
        }
    }
}


总结

对于一个节点Node和它的左节点LNode、右节点RNode,出栈的顺序: LNode -> Node -> RNode,也可以说是处理这个节点的顺序

目录
相关文章
打印全部异常堆栈、ExceptionUtils.getFullStackTrace这样最快
打印全部异常堆栈、ExceptionUtils.getFullStackTrace这样最快
528 0
|
Unix 应用服务中间件 Linux
1-Nginx介绍及安装(源码安装)
1-Nginx介绍及安装(源码安装)
254 4
|
SQL Java Serverless
实时计算 Flink版操作报错合集之在写入SLS(Serverless Log Service)时出现报错,该如何排查
在使用实时计算Flink版过程中,可能会遇到各种错误,了解这些错误的原因及解决方法对于高效排错至关重要。针对具体问题,查看Flink的日志是关键,它们通常会提供更详细的错误信息和堆栈跟踪,有助于定位问题。此外,Flink社区文档和官方论坛也是寻求帮助的好去处。以下是一些常见的操作报错及其可能的原因与解决策略。
|
存储 前端开发 JavaScript
react的useRef用什么作用
react的useRef用什么作用
223 1
|
关系型数据库 MySQL 分布式数据库
PolarDB 并行查询问题之保证与MySQL的兼容性如何解决
PolarDB 并行查询问题之保证与MySQL的兼容性如何解决
136 1
|
存储 JSON API
Transformers 4.37 中文文档(十一)(1)
Transformers 4.37 中文文档(十一)
278 1
|
存储 安全 算法
什么是数字签名?
【8月更文挑战第24天】
1001 0
|
存储 并行计算 数据处理
蓝易云 - 香港站群服务器1C,4C,8C,16C的配置介绍
以上是对服务器CPU核心数量的基本解释,但实际的服务器配置还会包括其他因素,如内存大小、存储类型和网络带宽等。这些因素都会影响服务器的性能和适用场景。
888 2
|
小程序 UED 开发者
微信小程序如何分包管理
微信小程序如何分包管理
|
存储 消息中间件 Linux
xenomai内核解析--实时IPC概述
本文介绍了在Xenomai实时内核下,实时任务与非实时任务如何进行通讯
340 0
xenomai内核解析--实时IPC概述