五分钟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 为例,后序遍历的过程如下: 从根节点 1 开始,遍历该节点的左子树(以 ...

  2. 后序遍历的非递归算法python_二叉树后序遍历(递归与非递归)算法C语言实现...

    二叉树后序遍历的实现思想是:从根节点出发,依次遍历各节点的左右子树,直到当前节点左右子树遍历完成后,才访问该节点元素. 图 1 二叉树 如图 1 中,对此二叉树进行后序遍历的操作过程为: 从根节点 1 ...

  3. sdut 2137 数据结构实验之求二叉树后序遍历和层次遍历

    数据结构实验之求二叉树后序遍历和层次遍历 Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic Discuss Problem Descr ...

  4. Java 二叉树后序遍历(递归/非递归)

    Java 二叉树后序遍历(递归/非递归) 简介: 遍历是对树的一种最基本的运算,所谓遍历二叉树,就是按一定的规则和顺序走遍二叉树的所有结点,使每一个结点都被访问一次,而且只被访问一次. 设L.D.R分 ...

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

    原文地址为: 二叉树后序遍历(非递归) 二叉树的递归遍历算法就不用说了:在非递归算法中,后序遍历难度大,很多书上只给出思想或者几段无法直接调试的代码,甚至有些书上是错的,当时我在研究的过程中,就是按着 ...

  6. 数据结构实验之求二叉树后序遍历和层次遍历

    数据结构实验之求二叉树后序遍历和层次遍历 Description 已知一棵二叉树的前序遍历和中序遍历,求二叉树的后序遍历和层序遍历. Input 输入数据有多组,第一行是一个整数t (t<100 ...

  7. 数据结构之 二叉树---求二叉树后序遍历和层次遍历(先建树,再遍历)

    数据结构实验之求二叉树后序遍历和层次遍历 Time Limit: 1000MS Memory limit: 65536K 题目描述 已知一棵二叉树的前序遍历和中序遍历,求二叉树的后序遍历. 输入 输入 ...

  8. 验证二叉树后序遍历序列是否符合要求

    验证二叉树后序遍历序列是否符合要求 @(算法学习) 给定一个后续遍历序列,立马知道树根是最后一个序列,那么如何切分左右子树呢? 比树根小的数都在左子树,比根大的都在右子树. 再递归验证,即,对左右子树 ...

  9. 已知二叉树后序遍历序列是DABEC 中序遍历列是 DEBAC ,它的前序遍历序列是

    已知二叉树后序遍历序列是DABEC 中序遍历列是 DEBAC ,它的前序遍历序列是: ----C ---/ --E -/-\ D---B -----\ ------A 我知道答案思念是这个....我想 ...

最新文章

  1. Java范例集锦(一)
  2. 开源中国 Chrome 插件,你的好帮手~
  3. 馒头,国庆节快乐啊!!~~~!
  4. CodeForces - 1373E Sum of Digits(贪心)
  5. java把对象转成json_java 把对象 对象转换成json字符串 | 学步园
  6. 学术工业界大佬联合打造:ML产品落地流程指南
  7. Magento教程 9:如何上传商品?
  8. 小学生通用计算机在线使用,Win7电脑可以使用一起小学软件的方法
  9. SLAM_SLAM中一般是如何求解相机的运动的?
  10. 提示缺少msvcpNNN.dll怎么办
  11. vdbench的作用_Vdbench----文件系统IO,一致性校验,常见问题
  12. 5V转±12V无变压器双boost电路
  13. 超好用笔记软件Typora安装教程
  14. uniapp开发的H5网页,以表单形式调起微信H5支付
  15. npm安装依赖报错 unable to resolve dependency tree....
  16. Spark面试精选题(03)
  17. qt 嵌入式linux 环境变量设置
  18. 苏州软件类企业在高新技术企业认定中的要点分析
  19. PDF尺寸怎么调整?两个实用途径
  20. 安装Linux win双系统 无法正常启动 读不出U盘

热门文章

  1. STM32F103C8T6引脚功能分布
  2. Python的第三方库fileType
  3. Spring Data Jpa的@Temporal注解
  4. IDEA安装“Translation”插件
  5. 某学校新买了一批计算机,2020年度初中信息技术考试选择题.doc
  6. java 1.7 可变参数,JDK1.7新特性(2):异常和可变长参数处理
  7. java用户登录记住密码_java项目中登陆时记住密码
  8. java word另存为_Java 网页html转为word并保存为doc文件
  9. mysql binlog备份_MySQL mysqldump + mysqlbinlog 备份和还原
  10. echarts横轴展示不全使用滚动条(dataZoom)的方法