二叉树后序遍历(非递归)

二叉树后续非递归遍历(很多人的盲区?) 大家好,我是Johngo! 今天有在校的粉丝想要C语言实现的树的后续遍历的详细讲解,今天就来看看。 后面给到了所有的代码,可以直接运行! 二叉树后序遍历 二叉树的遍历方式主要由先序遍历、中序遍历和后续遍历,还后就是层次遍历 感受完前两篇的遍历方式,本节来看看后序遍历 后序遍历过程 a. 先序遍历其左子树; b. 先序遍历其右子树; c. 访问根节点; 然后就是一直递归下去,在访问到节点的时候,可以进行节点的相关处理,比如说简单的访问节点值 下图是一棵二叉树,我们来手动模拟一下后序遍历过程 按照上述后序遍历 阅读详情
原文地址为: 二叉树后序遍历(非递归)


二叉树的递归遍历算法就不用说了;在非递归算法中,后序遍历难度大,很多书上只给出思想或者几段无法直接调试的代码,甚至有些书上是错的,当时我在研究的过程中,就是按着书上错误的代码绕了好半天,几预抓狂。好在最终摸索出来了,不禁感叹很多出书人的水平真是......   这里将直接可以在编译器里调试的代码贴出来(在DEV-C++编译器中编译通过)

 

这里我们约定:空的节点用空格表示,按照前序遍历来创建树!

   1 // main.cpp

  2    #include  < iostream >
  3    using   namespace  std;
  4  typedef  struct  node {
  5           char  data;
  6           struct  node  * lchild;
  7           struct  node  * rchild;
  8          }BiNode, * BiTree;
  9  typedef  struct  node1{
 10          BiTree data[ 30 ];      // 默认30个元素 ,这里需要一个辅助堆栈!!!
 11           int  top;
 12          }Stack;
 13          
 14  void  createTree(BiTree  & T)    // 先序递归创建树,这里注意参数的类型,T的类型是 "*&" ,如果是 "**" 代码稍加改动就OK...
 15  {
 16        char  ch;
 17       cin. get (ch). get ();       //过滤输入流中每次回车产生的回车符
 18        if  (ch == '   ' ) T = NULL;     //这里首先判断是不是空格,如果是,则为该节点赋NULL
 19        else {
 20              T = (BiTree)malloc( sizeof (BiNode));
 21              T -> data = ch;
 22              createTree(T -> lchild);
 23              createTree(T -> rchild);
 24            }
 25  }
 26  void  initstack(Stack  *& st)
 27  {
 28       st = (Stack  * )malloc( sizeof (Stack));
 29       st -> top =- 1 ;
 30  }
 31  bool  isempty(Stack  * st)
 32  {
 33       return  st -> top ==- 1 ;
 34  }
 35  bool  isfull(Stack  * st)
 36  {
 37       return  st -> top == 19 ;
 38  }
 39  void  push(Stack  * st,BiTree T)
 40  {
 41        if  ( ! isfull(st))
 42        st -> data[ ++ st -> top] = T;     //栈顶指针始终指向堆栈最上面可用的一个元素,因此入栈时候,先要将指针加1,然后再执行入栈操作!
 43        else  cout << " 已满 " << endl;
 44  }
 45  BiTree pop(Stack  * st)
 46  {
 47        if  ( ! isempty(st))  return  st -> data[st -> top -- ];
 48  }
 49  BiTree gettop(Stack  * st)
 50  {
 51          if  ( ! isempty(st))  return  st -> data[st -> top];   //出栈时,先取出栈顶指针指向的元素,然后再将指针减1,使其指向栈中下一个可用元素!
 52  }
 53  void  preOrderNoRe(BiTree T)           // 前序遍历
 54  {
 55     Stack  * st;
 56     initstack(st);
 57     BiTree p;
 58     p = T;
 59        while  (p != NULL ||! isempty(st))
 60       {
 61              while  (p != NULL)
 62             {
 63                   cout << p -> data << "    " ;
 64                   push(st,p);
 65                   p = p -> lchild;
 66             }
 67              if  ( ! isempty(st))
 68             {
 69                         p = pop(st);
 70                         p = p -> rchild;
 71             }
 72             
 73       }
 74  }
 75  void  inOrderNoRe(BiTree T)       //中序遍历
 76  {
 77     Stack  * st;
 78     initstack(st);
 79     BiTree p;
 80     p = T;
 81        while  (p != NULL ||! isempty(st))
 82       {
 83              while  (p != NULL)
 84             {
 85                   push(st,p);
 86                   p = p -> lchild;
 87             }
 88              if  ( ! isempty(st))
 89             {
 90                         p = pop(st);
 91                         cout << p -> data << "    " ;
 92                         p = p -> rchild;
 93             }
 94             
 95       }
 96  }
 97  void  postOrderNoRe(BiTree T)          //后序遍历
 98  {
 99       BiTree p;
100       Stack  * st;
101       initstack(st);
102       p = T;
103        int  Tag[ 20 ];       // 栈,用于标识从左(0)或右(1)返回 
104        while  (p != NULL  ||   ! isempty(st))
105       {
106              while  (p != NULL)
107             {
108                   push(st,p);
109                   Tag[st -> top] = 0 ;
110                   p = p -> lchild;
111             }
112              while  ( ! isempty(st) && Tag[st -> top] == 1 )
113             {
114                   p = pop(st);
115                   cout << p -> data << "    " ;
116             }
117              if  ( ! isempty(st))
118             {
119                              Tag[st -> top] = 1 ;    // 设置标记右子树已经访问 
120                              p = gettop(st);
121                              p = p -> rchild;
122             }
123              else   break ;
124       }
125  }
126  int  main()
127  {
128      cout << " Enter char one by one                      hicjiajia " << endl;
129      BiNode  * T;
130      createTree(T);
131      cout << endl;
132      
133      cout << " preOrderNoRe:   " ;preOrderNoRe(T);cout << endl;
134      cout << " inOrderNoRe:    " ;inOrderNoRe(T);cout << endl;
135      cout << " postOrderNoRe:  " ;postOrderNoRe(T);cout << endl; 
136      system( " pause " );
137       return   0 ;
138  }

 运行结果如图:

 


转载请注明本文地址: 二叉树后序遍历(非递归)
C/C++ 二叉树的非递归遍历(前序、中序、后序非递归遍历) 二叉树的非递归遍历C/C++实现: 非递归先序遍历代码: void PreOrderTraversal (struct tree* root) { //非递归先序遍历 struct tree* temp = root; while (temp != NULL || S.top > 0) { while (temp != NULL) { ... 阅读详情

相关推荐

二叉树非递归后序遍历C++

我们可以发现二叉树的后序遍历=镜像二叉树的先序遍历的反向输出。于是需要: 1.得到镜像二叉树 2.非递归的先序遍历镜像二叉树 3.将节点的访问结果存储在栈中,利用先入后出的特点将输出结果的顺序反向 class Tree { public: TreeNode* invertTree(TreeNode* root) { if (root == nullptr) return nullptr; TreeNode* left = invertTree(root->left); TreeNo

sakumashirayuki的博客 636

二叉树:后序遍历非递归算法

分析:后序遍历是三种遍历中最难的一种,后序遍历的特点为左右根,并且也需要借助一个栈来完成,如图,虚线表示p,q最开始的位置,用r指向最近访问过的结点。首先从根节点开始,沿着根的左孩子,将左孩子依次进行入栈。当D入栈之后,由于D没有右孩子,所以将D出栈,此时r指向D。 D出栈之后读栈顶元素B,p指向B,发现B有右孩子,然后将右孩子E入栈。 然后判断栈顶元素E,E没有右孩子了,所以将E出栈,此时r指向E。 然后判断栈顶元素B,B的两个孩子都已经操作过了,所以B出栈,p指向A,判断栈顶元素A,A有右孩子,右孩

花间半盘棋 2万+

LCD驱动芯片——BL55072A驱动程序

初始化子程序: START 0x7C; I2C子地址 0xEA;ICSET,软件复位芯片 0xC0;MODSET,关显示 0xF0;BLKCTL,关闪烁 0xA3;DISCTL,80Hz Line inversion,High Power mode 0xE8;ICSET,清复位bit1 STOP 显示刷新子程序: START 0x7C;I2C子地址 0xF0;BLKCTL,关闪烁 0xA3;DISCTL,80Hz Line inversion,High Power mode 0xE8或0xEC;ICSE

love421的博客 3175

二叉树遍历之后序遍历(非递归、递归)入门详解

二叉树后序遍历不如先序遍历简单,是相对最复杂的一种遍历方法。访问结点的次序是:“左—>右—>根”,也就是首先访问左子树,之后访问右子树,最后访问树根。对于左、右子树而言,其访问的次序依然是“左—>右—>根”。也就是说,对于每一棵子树,都是最后访问树根。...

sunnyoldboy博客 3万+

用C++手把手教你连接SimNow期货模拟盘:从CTP API封装到第一个订单(附完整代码)

本文详细介绍了如何使用C++连接SimNow期货模拟盘,从CTP API的基础架构解析到实现第一个订单的完整流程。内容涵盖CTP API的封装、SimNow环境配置、交易通道实现、行情接收与处理等核心环节,并提供完整代码示例,帮助开发者快速掌握量化交易中的期货模拟盘连接技术。

weixin_27215337的博客 330

三级等保网络拓扑图实战:从零搭建符合标准的医院安全架构

本文详细阐述了如何从零开始设计并搭建符合三级等保标准的医院网络安全架构。文章基于“一个中心,三重防护”的核心框架,深入解析了医院网络分区设计、安全域划分、关键安全设备选型与配置等实战要点,并提供了绘制专业网络拓扑图的技巧与等保测评准备指南,旨在帮助医院IT人员系统化地构建既合规又实用的纵深防御体系。

weixin_29326909的博客 504

Leetcode145 二叉树的后序遍历

给你一棵二叉树的根节点root,返回其节点值的后序遍历 知识点:栈 栈是一种仅支持在表尾进行插入和删除操作的线性表,这一端被称为栈顶,另一端被称为栈底。元素入栈指的是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;元素出栈指的是从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。 思路: 既然二叉树的前序遍历和中序遍历都可以使用栈来代替递归,那后序遍历是否也可以呢?答案是可以的,但是会比前二者复杂一点点。 根据后序遍历“左右中”的顺序,那么后序遍历...

neverSaynever_的博客 690

HFSS 3D LAOUT PCB 裁剪,差分线,过孔仿真和优化

我本身不是做天线设计的,所以HFSS这个软件给我主要还是做PCB级别的高速信号完整性仿真,一般2.5D的仿真软件无法对过孔和跨平面进行仿真。所以要借助三维电磁软件进行。今天就针对PCB进行裁剪。为什么要裁剪?以为如果把整个PCB一起仿真的话,应该要好几个月吧。所以为了加快仿真速度,必须进行裁剪仿真。①candence的PCB可以直接导入。那么先导入brd文件,file-import-candence结果如下②点击cutout,选中要仿真的net和参考平面。这里最好选creat new不然会把原文件覆盖掉。注

gjatwfn的专栏 1万+

二叉树后序遍历的非递归算法

二叉树后序遍历的非递归算法:结点要入两次栈,出两次栈;为了区别同一个结点的两次出栈,设置标志flag,当结点进、出栈时,其标志flag也同时进、出栈。

lobale的博客 1999

实战指南:基于华为Ascend NPU的大模型W8A8量化调优与精度提升

本文提供了一份基于华为Ascend NPU进行大模型W8A8量化的实战调优指南。详细介绍了从环境搭建、使用msmodelslim框架进行基础量化,到通过离群值抑制、校准集优化和量化回退等关键技术提升精度的全流程。旨在帮助开发者在华为NPU硬件上实现模型推理的显著加速,同时有效控制精度损失。

weixin_29227425的博客 271

Kile5报错—> ARM-Compiler ‘Default Compiler Version 5‘ which is not available安装使用Compiler Version 5 的办法

Kile5报错—> ARM-Compiler ‘Default Compiler Version 5‘ which is not available安装使用Compiler Version 5 的办法

weixin_72050316的博客 1183

二叉树的后序遍历非递归算法

1. 对于树的遍历我们最常用的三种遍历方法分别是前序遍历、中序遍历和后序遍历,使用的方法是深度优先遍历树的每一个节点,这些遍历方法都是使用递归函数来进行实现的,在数据量大的情况下是比较低效的,原因在于系统帮助我们调用了一个栈并且做了诸如保护现场和恢复现场等复杂的操作,才使得遍历可以使用非常简单的代码来实现,所以我们可以模仿系统中调用的栈自己可以来写一下栈,模仿其中的过程就可以完成对于三种遍历算法的...

二哈 4万+

主成分分析(Principal Component Analysis,PCA)

主成分分析1.主成分分析1.1 降维(Dimensionality Reduction)1.2 均值(Mean)1.3 方差(Variance)1.4 协方差(Covariance)1.5 协方差矩阵(Covariance Matrix)1.6 线性变换(Linear Transformation)1.7 主成分分析(PCA)1.8 PCA和SVD的关系 1.主成分分析 关于PCA的介绍:用最直观的方式告诉你:什么是主成分分析PCA 笔记来源:Principal Component Analysis (PC

一个搬运知识的笨小孩 3230

二叉树,二叉树的归先序遍历,中序遍历,后序遍历,递归和非递归实现

1)递归序,3次见面,第一次见面打印叫先序遍历,第二次见面打印叫中序遍历,第三次见面打印叫后序遍历 2)非递归实现中,先序和后序是相反的,但是中序遍历挺难理解,但是核心思想也就是先去左树,再打印头,然后再去右树。 3)笔试求AC,可以不考虑空间复杂度,但是面试既要考虑时间复杂度最优,也要考虑空间复杂度最优。

weixin_46838716的博客 7748

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

二叉树非递归后序遍历

/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ /*后...

发现问题,并解决问题,批判性思维 8399

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

非递归后序遍历二叉树总结

前言 关于之前写的非递归遍历二叉树的一份代码由于当时图省事几乎没有注释,导致今天再次看代码时比较费劲。这份代码是纯C写的,设计到许多栈、指针的操作,可读性不高,于是现在通过这份博客对于非递归后序遍历二叉树进行一个总结回顾。以及完善当时的部分注释。文章链戳这里 正文 进入正题,关于遍历二叉树常用的方法是递归遍历。优点是代码量小,逻辑精炼,可读性高。而对于递归实际上在底层的汇编代码中,是开辟了一个系...

小胡同的诗 1106

【二叉树Java】二叉树遍历前序中序后序遍历的非递归写法

二叉树遍历的非递归写法

liuwanqing233333的博客 3133

二叉树的非递归后序遍历

第四章-二叉树的非递归后序遍历 ‘’’ 注意: 1.本博客仅供参考交流使用,请读者务必自行实践,切勿生搬硬套 2.由于笔者水平有限,若文中有错误或者可以改进之处,欢迎在评论区指出 题目 ‘’’ Description 给定一组输入数据,要求按照该输入数据构造一颗二叉树并且使用非递归的后序遍历算法遍历该二叉树。PS:不能使用递归后序遍历算法,必须是非递归。 Input 按照满二叉树的对应位置(即将输...

沃沃头同学的博客 653

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

根左子树 右子树2)中序:左子树根右子树3)后序:左子树 右子树根可以看出,这三种遍历方式的本质区别在于什么时候访问根节点,下面将介绍一种很厉害的思想,对于前中后序的非递归实现,它可以是通解。

记录代码路上的点滴思考。 1209

设计并实现基于后序线索二叉树的后序遍历的非递归算法。(c++)

设计并实现基于后序线索二叉树的后序遍历的非递归算法。 一、二叉树的创建 我们使用二叉链表得方式进行二叉树存数。每个结构有一个数据域,存放结点的数据,还有两个左右指针,以及两个标志。当标志为0时表示指向孩子,标志为1时,指向线索。 二叉树的创建根据扩展线序序列创建的。当左右孩子为空时,以“.”来代替。 代码如下: template<class T>//创建二叉树 void xstree<T>::create(tbnode<T>*& t) { T x;

qq_46020030的博客 2334

非递归实现二叉树的后序遍历,详解

若栈顶结点的标志flag=1,则表明栈顶结点的左子树已遍历完毕,将flag修改为2,并遍历栈顶结点的右子树;若栈顶结点的标志flag=2,则表明栈顶结点的右子树也遍历完毕,输出栈顶结点。2.如果当前结点为空,就返回上一个结点,如果此时右结点为空就表示这是个叶子结点,我们就可以直接输出它的data。4.如果右结点不为空,就更新当前结点的flag为2,入栈,然后进入它的右节点。,当flag为2时也可以输出当前结点,这时输出的结点不是叶子结点,是已经被遍历过一次的结点。二叉树后序遍历的非递归算法。

2301_79431343的博客 2242

非递归后序遍历二叉树总结(2种方法)

算法 非递归后序遍历二叉树总结(2种方法) @author:Jingdai @date:2020.12.04 传送门 非递归先序遍历二叉树 非递归中序遍历二叉树 方法1 非递归用栈来辅助遍历,后序遍历是第三次遇到该节点再遍历,但是栈只能给我们提供遇到两次的判断方法,第一次是入栈时,第二次是出栈时,它们分别对应着二叉树的先序和中序遍历。所以我们需要利用一些技巧来辅助我们判断,这也是后序遍历二叉树比先序和中序稍微复杂一点的原因。 看着代码进行分析。 public static void postOrde

qq_41512783的博客 7391
上一篇: 算法总结系列之六: 桶排序(Bucket Sort)
下一篇: Python基本语法,python入门到精通[二]
dearbaba_8520
博客等级 码龄9年 406粉丝 4原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值