c++ stack 遍历_五分钟C语言数据结构 之 二叉树后序遍历(非递归很重要)
五分钟C语言实现常见数据结构
今天的内容分享的是二叉树后序遍历
DP问题,欢迎关注
动态规划一篇就够了 全网最详细, 逐步理解, 万字总结 - Johngo的文章 - 知乎 https://zhuanlan.zhihu.com/p/130743652
二叉树后序遍历后序遍历过程递归实现非递归实现
二叉树后序遍历
二叉树的遍历方式主要由先序遍历、中序遍历和后续遍历,还后就是层次遍历
感受完前两篇的遍历方式,本节来看看后序遍历
后序遍历过程
a. 先序遍历其左子树;
b. 先序遍历其右子树;
c. 访问根节点;
然后就是一直递归下去,在访问到节点的时候,可以进行节点的相关处理,比如说简单的访问节点值
下图是一棵二叉树,我们来手动模拟一下后序遍历过程
按照上述后序遍历的过程,得到后序遍历序列:
H I D E B F G C A
递归实现
二叉树的后序遍历利用上述的递归思想进行C语言代码实现:
树形结构按照上述树形结构进行初始化
# include <stdio.h>
# include <string.h>
# include <stdlib.h>
# define ElementType char//结点结构体
typedef struct BinTNode{ElementType data; struct BinTNode * left; struct BinTNode * right;
}BinTNode, *BinTree;// 初始化树形结构
BinTNode * CreateBiTree(BinTNode *T){T=(BinTNode*)malloc(sizeof(BinTNode));T->data='A';T->left=(BinTNode*)malloc(sizeof(BinTNode));T->left->data='B';T->right=(BinTNode*)malloc(sizeof(BinTNode));T->right->data='C';T->left->left=(BinTNode*)malloc(sizeof(BinTNode));T->left->left->data='D';T->left->right=(BinTNode*)malloc(sizeof(BinTNode));T->left->right->data='E';T->left->right->left=NULL;T->left->right->right=NULL; T->left->left->left=(BinTNode*)malloc(sizeof(BinTNode));T->left->left->left->data='H';T->left->left->left->left=NULL;T->left->left->left->right=NULL;T->left->left->right=(BinTNode*)malloc(sizeof(BinTNode));T->left->left->right->data='I';T->left->left->right->left=NULL;T->left->left->right->right=NULL;T->right->left=(BinTNode*)malloc(sizeof(BinTNode));T->right->left->data='F';T->right->left->left=NULL;T->right->left->right=NULL;T->right->right=(BinTNode*)malloc(sizeof(BinTNode));T->right->right->data='G';T->right->right->left=NULL;T->right->right->right=NULL;return T;
}// 遍历过程中,输出节点值
void printElement(BinTNode * T){printf("%c ",T->data);
}//先序遍历
void PostOrderTraverse(BinTNode * T){if (T) {PostOrderTraverse(T->left); //递归访问左孩子PostOrderTraverse(T->right); //递归访问右孩子printElement(T); //输出节点值}// 当节点为空的时候,返回return;
}int main() {BinTNode * Tree;Tree = CreateBiTree(Tree); // 初始化树形结构printf("后序遍历: ");PostOrderTraverse(Tree); // 先序递归进行printf("n"); // 最后换行return 0;
}
运行结果:
后序遍历: H I D E B F G C A
非递归实现
相比于之前的先序遍历和中序遍历非递归实现,后序遍历的非递归算法与之前有所不同,后续遍历需要先访问左右子结点后,才能访问该结点,而这也是非递归的难点所在。
考虑了几种实现的方案,这里我给出我认为比较清晰的一个方案供大家参考:借助两个栈(S1和S2)来进行操作
看下面伪代码:
初始化S1的top元素是树的根结点;while(top1 != -1) {将栈顶元素push到S2;if(栈顶元素有孩子结点){按照孩子结点的左右顺序push进S1;} }循环逐个弹出S2的栈顶元素
伪代码可能看了之后有些不太好懂,但是还算看着清晰吧,下面借助图,一定会思路清晰的(长图发放):
有了这个思路就应该会很清晰了,下面按照上述思路用C语言实现:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define ElementType char
int top_S1 = -1; //定义栈S1 top下标
int top_S2 = -1; //定义栈S2 top下标// 结点结构体
typedef struct BinTNode{ElementType data; struct BinTNode * left; struct BinTNode * right;
}BinTNode, *BinTree;// 初始化树形结构
BinTNode * CreateBiTree(BinTNode *T) {T=(BinTNode*)malloc(sizeof(BinTNode));T->data='A';T->left=(BinTNode*)malloc(sizeof(BinTNode));T->left->data='B';T->right=(BinTNode*)malloc(sizeof(BinTNode));T->right->data='C';T->left->left=(BinTNode*)malloc(sizeof(BinTNode));T->left->left->data='D';T->left->right=(BinTNode*)malloc(sizeof(BinTNode));T->left->right->data='E';T->left->right->left=NULL;T->left->right->right=NULL; T->left->left->left=(BinTNode*)malloc(sizeof(BinTNode));T->left->left->left->data='H';T->left->left->left->left=NULL;T->left->left->left->right=NULL;T->left->left->right=(BinTNode*)malloc(sizeof(BinTNode));T->left->left->right->data='I';T->left->left->right->left=NULL;T->left->left->right->right=NULL;T->right->left=(BinTNode*)malloc(sizeof(BinTNode));T->right->left->data='F';T->right->left->left=NULL;T->right->left->right=NULL;T->right->right=(BinTNode*)malloc(sizeof(BinTNode));T->right->right->data='G';T->right->right->left=NULL;T->right->right->right=NULL;return T;
}// 栈S1 - 进栈push
void push_S1(BinTNode** stack,BinTNode * elem) {stack[++top_S1] = elem;
}// 栈S2 - 进栈push
void push_S2(BinTNode** stack,BinTNode * elem) {stack[++top_S2] = elem;
}//栈S1 - 弹栈pop
void pop_S1(){if (top_S1 == -1) {return ;}top_S1--;
}//栈S2 - 弹栈pop
void pop_S2(){if (top_S2 == -1) {return ;}top_S2--;
}// 遍历过程中,输出结点值
void printElement(BinTNode* elem) {printf("%c ",elem->data);
}//获取栈顶元素
BinTNode * getTop_S1(BinTNode** stack){return stack[top_S1];
}//获取栈顶元素
BinTNode * getTop_S2(BinTNode** stack){return stack[top_S2];
}//非递归遍历 - 左右根
void PostOrderTraverse(BinTNode * Tree) {BinTNode * S1[30]; // 辅助栈BinTNode * S2[30];BinTNode * T = Tree; // 定义临时指针BinTNode * Temp;push_S1(S1, T); // 初始化S1的top元素是树的根结点while(top_S1 != -1) {T = getTop_S1(S1); // S1的栈顶元素弹出 pop_S1(); // 栈顶元素弹栈push_S2(S2, T);if(T->left != NULL || T->right != NULL) { // 栈顶元素有孩子结点if(T->left != NULL)push_S1(S1, T->left);if(T->right != NULL)push_S1(S1, T->right); }}// 逐个弹出S2的元素while(top_S2 != -1) {printElement(getTop_S2(S2));pop_S2();}
}int main() {BinTNode * Tree;Tree = CreateBiTree(Tree);printf("看到这样就对了: H I D E B F G C An");printf("后序遍历:t");PostOrderTraverse(Tree);printf("n");return 0;
}
运行结果
看到这样就对了: H D I B E A F C G
中序遍历: H D I B E A F C G
DP问题,欢迎关注
动态规划一篇就够了 全网最详细, 逐步理解, 万字总结 - Johngo的文章 - 知乎 https://zhuanlan.zhihu.com/p/130743652
后续会将更多的数据结构用C语言代码实现,欢迎大家关注!
作者:Johngo
计算广告,广告收入占到互联网收入的80%以上,一起研究流量变现,欢迎大家的加入
c++ stack 遍历_五分钟C语言数据结构 之 二叉树后序遍历(非递归很重要)相关推荐
- (数据结构)二叉树后序遍历
二叉树后序遍历 二叉树后序遍历的实现思想是: 访问当前节点的左子树 访问当前节点的右子树 访问根节点 图 1 二叉树 以上图 1 为例,后序遍历的过程如下: 从根节点 1 开始,遍历该节点的左子树(以 ...
- 后序遍历的非递归算法python_二叉树后序遍历(递归与非递归)算法C语言实现...
二叉树后序遍历的实现思想是:从根节点出发,依次遍历各节点的左右子树,直到当前节点左右子树遍历完成后,才访问该节点元素. 图 1 二叉树 如图 1 中,对此二叉树进行后序遍历的操作过程为: 从根节点 1 ...
- sdut 2137 数据结构实验之求二叉树后序遍历和层次遍历
数据结构实验之求二叉树后序遍历和层次遍历 Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic Discuss Problem Descr ...
- Java 二叉树后序遍历(递归/非递归)
Java 二叉树后序遍历(递归/非递归) 简介: 遍历是对树的一种最基本的运算,所谓遍历二叉树,就是按一定的规则和顺序走遍二叉树的所有结点,使每一个结点都被访问一次,而且只被访问一次. 设L.D.R分 ...
- 二叉树后序遍历(非递归)
原文地址为: 二叉树后序遍历(非递归) 二叉树的递归遍历算法就不用说了:在非递归算法中,后序遍历难度大,很多书上只给出思想或者几段无法直接调试的代码,甚至有些书上是错的,当时我在研究的过程中,就是按着 ...
- 数据结构实验之求二叉树后序遍历和层次遍历
数据结构实验之求二叉树后序遍历和层次遍历 Description 已知一棵二叉树的前序遍历和中序遍历,求二叉树的后序遍历和层序遍历. Input 输入数据有多组,第一行是一个整数t (t<100 ...
- 数据结构之 二叉树---求二叉树后序遍历和层次遍历(先建树,再遍历)
数据结构实验之求二叉树后序遍历和层次遍历 Time Limit: 1000MS Memory limit: 65536K 题目描述 已知一棵二叉树的前序遍历和中序遍历,求二叉树的后序遍历. 输入 输入 ...
- 验证二叉树后序遍历序列是否符合要求
验证二叉树后序遍历序列是否符合要求 @(算法学习) 给定一个后续遍历序列,立马知道树根是最后一个序列,那么如何切分左右子树呢? 比树根小的数都在左子树,比根大的都在右子树. 再递归验证,即,对左右子树 ...
- 已知二叉树后序遍历序列是DABEC 中序遍历列是 DEBAC ,它的前序遍历序列是
已知二叉树后序遍历序列是DABEC 中序遍历列是 DEBAC ,它的前序遍历序列是: ----C ---/ --E -/-\ D---B -----\ ------A 我知道答案思念是这个....我想 ...
最新文章
- Java范例集锦(一)
- 开源中国 Chrome 插件,你的好帮手~
- 馒头,国庆节快乐啊!!~~~!
- CodeForces - 1373E Sum of Digits(贪心)
- java把对象转成json_java 把对象 对象转换成json字符串 | 学步园
- 学术工业界大佬联合打造:ML产品落地流程指南
- Magento教程 9:如何上传商品?
- 小学生通用计算机在线使用,Win7电脑可以使用一起小学软件的方法
- SLAM_SLAM中一般是如何求解相机的运动的?
- 提示缺少msvcpNNN.dll怎么办
- vdbench的作用_Vdbench----文件系统IO,一致性校验,常见问题
- 5V转±12V无变压器双boost电路
- 超好用笔记软件Typora安装教程
- uniapp开发的H5网页,以表单形式调起微信H5支付
- npm安装依赖报错 unable to resolve dependency tree....
- Spark面试精选题(03)
- qt 嵌入式linux 环境变量设置
- 苏州软件类企业在高新技术企业认定中的要点分析
- PDF尺寸怎么调整?两个实用途径
- 安装Linux win双系统 无法正常启动 读不出U盘
热门文章
- STM32F103C8T6引脚功能分布
- Python的第三方库fileType
- Spring Data Jpa的@Temporal注解
- IDEA安装“Translation”插件
- 某学校新买了一批计算机,2020年度初中信息技术考试选择题.doc
- java 1.7 可变参数,JDK1.7新特性(2):异常和可变长参数处理
- java用户登录记住密码_java项目中登陆时记住密码
- java word另存为_Java 网页html转为word并保存为doc文件
- mysql binlog备份_MySQL mysqldump + mysqlbinlog 备份和还原
- echarts横轴展示不全使用滚动条(dataZoom)的方法