二叉树的非递归遍历

二叉树的三种遍历非递归实现 二叉树的遍历实现 阅读详情

题目:二叉树的非递归遍历(前、中、后)

对于二叉树,有前序、中序以及后序三种遍历方法。

因为树的定义本身就是递归定义,因此采用递归的方法去实现树的三种遍历不仅容易理解而且代码很简洁。

而对于树的遍历若采用非递归的方法,就要采用栈去模拟实现。

思路标签:

  • 栈的实现

解答:

1. 先序遍历

对于任一结点P:

  • (1) 访问结点P,并将结点P入栈;
  • (2) 将P的左孩子置为当前的结点P;判断结点P的左孩子是否为空,若为空,则取栈顶结点并进行出栈操作,并将栈顶结点的右孩子置为当前的结点P。
  • (3) 直到P为NULL并且栈为空,则遍历结束。
void preOrder2(BinTree *root)     //非递归前序遍历 
{
    stack<BinTree*> s;
    BinTree *p=root;
    while(p!=nullptr||!s.empty())
    {
        while(p!=nullptr)
        {
            cout<<p->data<<" ";
            s.push(p);
            p=p->lchild;
        }
        if(!s.empty())
        {
            p=s.top();
            s.pop();
            p=p->rchild;
        }
    }
}
2. 中序遍历

对于任一结点P:

  • (1) 将P入栈并将P的左孩子置为当前的P,若不为空,然后对当前结点P再进行相同的处理;
  • (2) 若其左孩子为空,则访问该栈顶元素并进行出栈操作,然后将当前的P置为栈顶结点的右孩子;
  • (3) 直到P为nullptr 并且栈为空,则遍历结束。
void inOrder2(BinTree *root)      //非递归中序遍历
{
    stack<BinTree*> s;
    BinTree *p=root;
    while(p!=nullptr||!s.empty())
    {
        while(p!=nullptr)
        {
            s.push(p);
            p=p->lchild;
        }
        if(!s.empty())
        {
            p=s.top();
            cout<<p->data<<" ";
            s.pop();
            p=p->rchild;
        }
    }    
}
3. 后序遍历

思路一:

对于任一结点P:

  • (1) 为每个节点增加一个标志是否是第一次出现的栈顶的标志,如果第一次出现栈顶,则修改标志,不进行出栈操作;
  • (2) 第二次出现在栈顶的元素则直接进行访问并出栈;
  • (3) 直到P为空或者栈为空,则访问完毕。
typedef struct node
{
    char data;
    struct node *lchild,*rchild;
}BinTree;

typedef struct node1
{
    BinTree *btnode;
    bool isFirst;
}BTNode;

void postOrder2(BinTree *root)    //非递归后序遍历
{
    stack<BTNode*> s;
    BinTree *p=root;
    BTNode *temp;
    while(p!=nullptr||!s.empty())
    {
        while(p!=nullptr)              //沿左子树一直往下搜索,直至出现没有左子树的结点 
        {
            BTNode *btn=(BTNode *)malloc(sizeof(BTNode));
            btn->btnode=p;
            btn->isFirst=true;
            s.push(btn);
            p=p->lchild;
        }
        if(!s.empty())
        {
            temp=s.top();
            s.pop();
            if(temp->isFirst==true)     //表示是第一次出现在栈顶 
             {
                temp->isFirst=false;
                s.push(temp);
                p=temp->btnode->rchild;    
            }
            else                        //第二次出现在栈顶 
             {
                cout<<temp->btnode->data<<" ";
                p=nullptr;
            }
        }
    }    
}

思路二:

对于任一结点P:

  • (1) 要保证根结点在左孩子和右孩子访问之后才能访问,因此对于根结点P,先将其入栈。
  • (2) 如果P不存在左孩子和右孩子,则可以直接访问它;或者P存 在左孩子或者右孩子,但是访问的前一个节点是其左孩子或者右孩子,证明其左孩子和右孩子都已被访问过了,则同样可以直接访问该结点。
  • 若非上述两种情况,则将P的右孩子和左孩子依次入栈,保证了 每次取栈顶元素的时候,左孩子在右孩子前面被访问,左孩子和右孩子都在根结点前面被访问。
void postOrder3(BinTree *root)     //非递归后序遍历
{
    stack<BinTree*> s;
    BinTree *cur;                      //当前结点 
    BinTree *pre=nullptr;                 //前一次访问的结点 
    s.push(root);
    while(!s.empty())
    {
        cur=s.top();
        if((cur->lchild==nullptrL&&cur->rchild==nullptr)||
           (pre!=nullptr&&(pre==cur->lchild||pre==cur->rchild)))
        {
            cout<<cur->data<<" ";  //如果当前结点没有孩子结点或者孩子节点都已被访问过 
            s.pop();
            pre=cur; 
        }
        else
        {
            if(cur->rchild!=nullptr)
                s.push(cur->rchild);
            if(cur->lchild!=nullptr)    
                s.push(cur->lchild);
        }
    }    
}
二叉树的非递归遍历和层次遍历详解 二叉树非递归遍历非递归的后序遍历二叉树 //非递归的后续遍历二叉树 void HXprint(Tree *tree){ Stack s = initStack(); //初始化一个下面使用的栈 treeNode *p = tree; //新建一个遍历指针 treeNode *r=NULL; //辅助变量 cout<<"-------"<<endl; while(p||!isEmpty(s)){ //当遍历变量和栈同时为空时 表示遍历完成 阅读详情

相关推荐

非递归遍历二叉树

1.先序遍历从递归说起void preOrder(TNode* root){    if (root != NULL)    {        Visit(root);        preOrder(root->left);        preOrder(root->right);    }}递归算法非常的简单。先访问跟节点,然后访问左节点,

重剑无锋 5万+

6-1 栈及二叉树的非递归遍历(c++)

6-1 栈及二叉树的非递归遍历(c++) 在这里描述函数接口: #include #define MAXSIZE 100 //顺序栈存储控件的初始分配量 #define OK 1 #define ERROR 0 #define OVERFLOW -1 using namespace std; typedef int Status; typedef char TElemType; typedef struct BiTNode{ TElemType Data; struct BiTNode *lchild,*

qq_63231439的博客 351

二叉树的非递归遍历:先根遍历、中根遍历、后根遍历

二叉树的非递归遍历 二叉树的三种遍历方式也可以通过非递归的方法借助栈来实现。 通过控制节点的出栈和入栈先后顺序来实现对树的不同方式的遍历。 非递归先根遍历二叉树 当栈不为空或者当前节点为不为空,执行操作: 从根节点开始,依次访问树中最左端的节点并入栈,当节点为空停止入栈。 取栈顶元素为当前节点并出栈,如果当前节点有右子树,则遍历其右子树。 void PreorderPrint(...

SanFancsgo的博客 8315

数据结构-----二叉树的非递归遍历

一、先序遍历(非递归)1.编程思路:        二叉树的非递归先序遍历相对与对栈 的一波操作:先判断根节点是否为空,若为空直接返回,不为空将进入以下判断,将根节点入栈,进入循环体;取栈顶元素,进行访问并对栈做出栈操作;(访问包括先将其右孩子入栈,再将其左孩子入栈,如孩子为空,则不进行入栈操作),以此方法进行循环,直至栈内无元素结束。原二叉树图:思维图如下所示:2.程序代码实现://非递归的先序...

cyd_csdn的博客 226

二叉树遍历,栈实现二叉树的非递归遍历

另见求树高 http://blog.youkuaiyun.com/Justme0/article/details/7694704 /******************************************************************** created: 2014/05/11 23:13 filename: main.c author: Just

Tham 在思索中前行! 1892

二叉树的4种非递归遍历

二叉树的4种非递归遍历,你知道吗?

! 2031

详解二叉树的非递归遍历

本文转载自:http://blog.youkuaiyun.com/zhangxiangdavaid/article/details/37115355 前言   对于二叉树的递归遍历比较简单,所以本文主要讨论的是非递归版。其中,中序遍历的非递归写法最简单,后序遍历最难。 节点的定义: //Binary Tree Node typedef struct node { int data; ...

编程随笔与杂谈 10万+

循环卷积和线性卷积(矩阵视角)

矩阵视角的循环卷积核线性卷积

shengsong 3578

二叉树遍历非递归算法

•三种遍历​ • 先序遍历: 根节点–>左子树–>右子树​ • 中序遍历: 左子树–>根节点–>右子树​ • 后序遍历: 左子树–>右子树–>根节点•两类算法​ • 递归算法(具体看我上一篇文章)​ ♥直观,易读​ ♥效率低下​ • 非递归算法​ ♥ 如果一个算法可以使用递归或循环来进行完成,在不影响代码阅读的情况下,可以使用循环,来降低复杂度。下面介绍二叉树的遍历,把用。

qq_57484399的博客 6183

【清华大学软院】15-19年推免试题历年整理

整理的题目为清软预推免机试(外校)硕士机考题目。 年代 题目1 题目2 题目3 2019 质因数分解 二叉搜索树 区间DP(折叠字符串) 2018 日期转换 高精度模拟 区间DP(戳气球) 2017 进制素数 被遗漏的数字 DP(收集苹果) 2016 大数运算 DP DFS 2015 进制素数: http://acm.hdu.edu.cn/showproblem.php?pid=1230 2017年题目(这个是找的最准确的题目): 1题见【链接】 2题见【链接】

云端筑梦师 2255

S32K144(14)ADC

1、简介 开发板S32K144+S32DS+JLINK,裸机版的程序编写 S32K14x包含两个12位ADC模块,ADC0和ADC1 应用程序可能需要ADC的连续采样(4K采样/秒),这可能对CPU有相当大的负载。虽然使用可编程延迟块(PDB)来触发ADC可能会减少一些CPU负载,但当ADC以非常高的速率采样或PDB被绕过时,ADC支持DMA请求功能以获得更高的性能。ADC可以在转换完成时触发DMA(通过DMA请求)。TRGMUX会根据不同的应用需求,使用软件为用户提供更灵活的DMA触发方案,例如,可

朗朗上口就行啦的博客 1万+

二叉树遍历的一些非递归算法

非递归的二叉树遍历等算法C语言

m0_66120913的博客 1万+

从理论到实践:TRL去嵌入校准在国产矢量网络分析仪上的应用全解析

本文全面解析了TRL去嵌入校准技术在国产矢量网络分析仪上的应用实践,从核心算法到工程实现。详细介绍了TRL校准的数学原理、国产VNA的程控接口开发、校准件质量评估及测量不确定度控制策略,帮助工程师掌握高频器件测量的关键技术。

tech5的博客 1012

二叉树的非递归遍历及层次遍历

二叉树的基本操作请看:http://blog.youkuaiyun.com/sysu_arui/article/details/7865876 前面简答介绍了二叉树的基本操作,包括二叉树的建立,销毁,递归遍历,以及其他一些常见的递归算法,现在集中讨论一下二叉树的层次遍历和非递归遍历。 二叉树的层次遍历要用到队列,前序、中序和后序非递归遍历要用到栈,这里我就不自己写队列和栈了,直接使用C++标准库中的容器适

arui的专栏 1万+

SAP 人力资源工资配置项3---工资项配置

工资项设置

xiouluoyang的专栏 1万+

Trae IDE项目开发全流程深度技巧与最佳实践

2026年AI开发新范式:Trae AI IDE深度解析 摘要 2026年,AI已成为软件开发的核心驱动力。字节跳动推出的AI原生IDE——Trae,从根本上重塑了开发体验,将AI作为第一公民而非附加功能。Trae通过深度集成大型语言模型和创新交互模式,解决了现代开发中的重复劳动、信息过载等核心痛点。 报告全面剖析了Trae的核心功能: 智能代码生成:支持上下文感知续写、自然语言驱动生成和多模态输入转换 对话式AI助手:提供侧边栏和行内对话模式,支持代码解释、Bug修复、重构建议等 Builder/SOLO

公众号:AI前沿侦探 159

二叉树三种非递归遍历

二叉树三种非递归遍历王道书思想方法实现

qq_52526050的博客 3394

DCM07-诊断服务EcuReset ($11 )的配置和实现

文章目录1 诊断服务EcuReset ($11 )1.1 概述1.2 诊断模式声明组1.3 代码实现1.4 配置参数 传送门 ==>> AutoSAR实战系列300讲「糖果Autosar」总目录 1 诊断服务EcuReset ($11 ) 1.1 概述 该服务实现了 ECU 内的复位功能,协议的具体理论讲解请参考「FlashBootloader03【电控单元复位服务($11)】」。在接收到UDS 服务 0x11 的请求时,DCM 模块应触发 ModeDeclarationGroupPrototy

2064

二叉树的中序非递归遍历

二叉树的中序非递归遍历 中序遍历的非递归算法描述如下: 从根节点开始检索,如果当前节点不为空,则将当前节点入栈,让当前节点成为其左孩子节点,再继续上一步的操作 加入当前节点为空了,说明其父节点已经没有左孩子了,那么将栈顶元素出栈并输入 判断栈顶元素是否有右孩子,如果有右孩子,则停止依次继续出栈的操作,并检索它的右孩子,重复第一步;如果没有右孩子,则继续将栈顶元素出栈 当栈为空,并且当前节点为空时,遍历完成,退出; #include<stdio.h> #include<stdlib.h&

weixin_45863060的博客 8773

UNet 改进(39):结合残差连接与CBAM注意力机制的unet模型

本文提出了一种改进的UNet架构,通过融合残差连接和CBAM注意力机制来增强医学图像分割性能。该网络保留UNet的U形结构,但将基础模块替换为ResidualBlock和CBAM的组合:残差块通过快捷连接解决梯度消失问题,CBAM模块结合通道和空间注意力机制突出重要特征。整体架构采用编码器-解码器设计,包含5个下采样和上采样阶段,通过跳跃连接融合多尺度特征。实验表明,这种改进显著提升了原始UNet的性能,特别适用于需要精细边界的医学图像分割任务。

2401_82355416的博客 1021

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

上一篇: 十大排序算法及其实现(C++ & Python)
下一篇: 二叉树的层次遍历 & 深度
大树先生的博客
博客等级 码龄9年 2692粉丝 200原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值