树的 “前” “中” “后” 遍历

//如果要再写一个树太费时间了,所以博主在这篇博客只给出核心代码并赋予GIF演示动画,望大家好好理解以对树的三种遍历方式有更为深刻的理解

 因为递归调用函数是有开销的,而且递归的次数受堆栈大小的限制,所以本篇博客不会
介绍用递归的方式来遍历树.  而是使用 栈 来遍历树.首先让我们来了解什么是栈?

栈是存放数据对象的一种特殊容器,栈中的元素始终遵循后进先出的顺序

前序遍历(博主上篇已经写过了,所以直接套用上篇的代码):
前序遍历的主要思想就是:
根节点最先入栈,最先出栈
右子节点先入栈后处理;
左子节点后入栈先处理.

 Btree tmp;SqStack stack;InitStack(stack);PushStack(stack, *root);   //根节点进栈while (!(IsEmpty(stack))) {  //栈为空,所有节点均已处理 PopStack(stack, tmp);     //要遍历的节点    printf("- %d -", tmp.data);       //打印要便利的节点的值if (tmp.rchild != NULL) {PushStack(stack, *(tmp.rchild)); //右子节点先入栈,后处理     }if (tmp.lchild != NULL) {PushStack(stack, *(tmp.lchild)); //左子节点后入栈,接下来先 处理    }}

前序遍历演示

void inOrder(BinTree *root)  //非递归中序遍历{stack<BinTree*> s;BinTree *p=root;while(p!=NULL||!s.empty()){while(p!=NULL){s.push(p);p=p->lchild;}if(!s.empty()){p=s.top();cout<<p->data<<"";s.pop();p=p->rchild;}}
}

一开始我们 BinTree *p=root;这样就能执行我们的第一个while循环
当跳出第一个while()循环时,就代表我们的中序遍历已经结束了。

  1. 第二个while在p不为空时执行: 在while循环下,将根节点先入栈,左子节点后入栈,然后继续判断p是否为空再决定是否继续如果满足那么左子节点再继续入栈(因为根节点在最前面所以现在入栈的就只有左子节点了,不会存在根节点反复入栈的情况)。那么while循环完的时候,我们的节点p此时一定为NULL; 如果现在出栈的话我们一定能保证出战的元素使我们要出的第一个节点!!!
  2. 出栈以及后续操作 if 语句 : 在步骤1操作之后,根节点以及最左边的节点将会全部入栈。此时我们现在的p为NULL;这样我们是无法进行后续操作的,那么我们应该如何做呢???
    其实很简单只需要让我们的 p 只想现在的栈顶元素,再将数据输出到控制台,再将这个元素在栈中出栈即可。因为左子节点以及用过了,所以现在我们就执行 p=p->rchile 那么此时又会存在两种情况
    (1)存在右子节点------->即p不为空,那么又会进入到步骤1;知道变成第二种情况。
    (2)不存在右子节点--------> 那么在执行操作2(即继续出栈,向上查找)

gif演示:

后序遍历:

void postOrder3(BinTree *root)     //非递归后序遍历
{stack<BinTree*> s;BinTree *cur;                      //当前结点BinTree *pre=NULL;                 //前一次访问的结点s.push(root);while(!s.empty()){cur=s.top();if((cur->lchild==NULL&&cur->rchild==NULL)||(pre!=NULL&&(pre==cur->lchild||pre==cur->rchild))){cout<<cur->data<<"";  //如果当前结点没有孩子结点或者孩子节点都已被访问过s.pop();pre=cur;}else{if(cur->rchild!=NULL)s.push(cur->rchild);if(cur->lchild!=NULL)   s.push(cur->lchild);}}
}

对于后序遍历的理解:
首先定义两个可以指向树的指针
cur :指向当前节点
pre 指向上一个节点

现将根节点入栈(这一个会实现根节点最后出栈)

如果打while都已经跳出来了的话那么就说明已经完成后序遍历(因为我们先把根节点压进了栈,所以第一次是不会跳出我们的大循环的)

cur=s.top();将cur指向我们的栈顶(随着栈顶元素不断出栈,cur的指向会不断更改)

if(…) //如果当前结点没有孩子结点或者孩子节点都已被访问过(第一次循环的时候是不会进入这条语句的所以不要纠结最 孩子节点都已被访问过这句话!!!)
cout 想控制台打印元素,然后出栈
pre =cur; 这样就能实现pre指向上一个结点的功能了(也许会有人问,现在不是 pre=cur他们应该是指向一个结点的啊!!! 为什么要说 cur是指向当前节点 pre 是指向上一个结点啊? 因为在if结束了之后 cur就会指向新的栈顶元素!!!)

else(即在if判断不成立时进入else语句!!) 即当前节点存在孩子节点或者孩子节点还未被访问完!!
这里的思想就类似于前序遍历的思想了,只是没有前序遍历的 右节点存在,右节点入栈之后,左节点存在,左节点入栈,接着先入栈的后处理,后入栈的先处理的思想马上出站,而是要在满足我们的if条件才会进行出栈

gif演示:

希望大家能通过本篇博客掌握 树的三中遍历方式.

谢谢观看。?

数据结构与算法之树的遍历相关推荐

  1. 《数据结构与算法》——树与二叉树之遍历总结

    <数据结构与算法>--树与二叉树之遍历总结 树与二叉树部分计划分为三次进行复习总结,第一次为基本概念和二叉树的遍历,第二次内容为线索二叉树以及树和森林,第三次为树与二叉树的应用. 目录 & ...

  2. 数据结构与算法--B树原理及实现

    B树 前几篇文中讨论的数据结构我们都是假设所有的数据都存储在计算机的主存中.可说总要那么海量的数据需要通过个中数据结构去存储,我们不可能有这么多内存区存放这些数据.那么意味着我们需要将他们放磁盘.所以 ...

  3. 数据结构与算法——AVL树类的C++实现

    关于AVL树的简单介绍能够參考: 数据结构与算法--AVL树简单介绍 关于二叉搜索树(也称为二叉查找树)能够參考:数据结构与算法--二叉查找树类的C++实现 AVL-tree是一个"加上了额 ...

  4. 数据结构与算法(3)——树(二叉、二叉搜索树)

    前言:题图无关,现在开始来学习学习树相关的知识 前序文章: 数据结构与算法(1)--数组与链表(https://www.jianshu.com/p/7b93b3570875) 数据结构与算法(2)-- ...

  5. 高级数据结构与算法 | AVL树 (高度平衡树)

    文章目录 AVL树 实现思路 数据结构 查找 平衡因子 旋转 右旋 左旋 右左双旋 左右双旋 插入 删除 AVL树的验证 中序遍历 平衡判断 AVL树的性能 完整代码实现 AVL树 AVL树是最先发明 ...

  6. 数据结构与算法:树与二叉树python实现

    最近复习一遍数据结构与算法,做一些笔记,大家可以一起复习. 一.树的一些容易混淆的定义: 结点层:根结点的层定义为1:根的孩子为第二层结点,依此类推: 树的深度(或高度):树中最大的结点层: 满二叉树 ...

  7. 数据结构和算法——kd树

    一.K-近邻算法 K-近邻算法是一种典型的无参监督学习算法,对于一个监督学习任务来说,其 m m个训练样本为: {(X(1),y(1)),(X(2),y(2)),⋯,(X(m),y(m))} \lef ...

  8. 高级数据结构与算法 | B树、B+树、B*树

    文章目录 搜索结构 B树 B树的插入 B树的遍历 B树的性能 B+树 B+树的插入 B+树的遍历 B*树 B*树的插入 总结 搜索结构 如果我们有大量的数据需要永久存储,就需要存储到硬盘之中,但是硬盘 ...

  9. 数据结构与算法图解——树

    文章目录 7. 树 7.1 树的逻辑结构 7.1.1 例题 7.2 树的基本术语 7.2.1 例题 7.3 二叉树的性质 7.3.1 性质1 7.3.2 性质2 7.3.3 性质3 7.3.4 性质4 ...

最新文章

  1. bzoj3600 没有人的算术
  2. 最新曝光的iPhone大漏洞:传文件会泄露个人隐私,2年多了苹果知而不改
  3. 一致性hash算法 - consistent hashing
  4. 统计学习导论:基于R应用——第二章习题
  5. java配置文件报错_java使用spring框架配置文件时遇到的错误——Referenced file contains errors...
  6. 部门选择控件源代码公布
  7. 为前端工程之崛起而编程!
  8. 一些TC内置的环境环境变量(注意字母必须大写,且只能在TC内用)
  9. 蓝桥杯.历届试题: 核桃数量
  10. mysql数据库文件结构同步,[数据库的表同步mysql]MySQL表结构同步
  11. 【gloomyfish】【原创】数据分析之 – 散点图
  12. 安卓MediaCodec编码aac
  13. 用python做餐厅点餐系统
  14. HTTP 503 Service Temporarily Unavailable
  15. React Native微信分享
  16. 每天盯着桌面,送你几个4k、8k壁纸资源的网站,请收好
  17. JAVA从零开始开发区块链技术
  18. overleaf怎么输入中文_【LATEX】在线latex排版工具Overleaf-制作中文简历-详细教程...
  19. 区块链实战(一)实现简单的区块与区块链交易
  20. Hologres INSERT ON CONFLICT

热门文章

  1. pytest使用入门
  2. 南非醉茄提取物行业调研报告 - 市场现状分析与发展前景预测
  3. 弹簧式止回阀行业调研报告 - 市场现状分析与发展前景预测(2021-2027年)
  4. meteor 结合mysql_Meteor: 关于Template实例(instance)和数据(data)
  5. docker下gitlab安装配置使用
  6. React Ant Design UI 图片上传组件 代码片段
  7. 从入门到入土:基于Python采用TCP协议实现通信功能的程序
  8. 微软想通了?Windows 11恢复一键改变默认浏览器功能
  9. 从高量到高质,私域流量的变革与发展
  10. 漫画:应用程序被拖慢?罪魁祸首是 Log4j!