二叉树利用堆栈实现遍历的非递归算法
二叉树的遍历有三种不同的遍历方法,分别是前序遍历、中序遍历以及后序遍历
遍历的实现我们在上一篇博客中已经用递归的方法实现了,那么可不可以不用递归实现呢,答案是可以的
在这一篇博客中我们会利用堆栈将遍历改为非递归
下面先附上实现的代码
#include "stdio.h"
#include "stdlib.h" typedef struct tree
{ char data; struct tree *lchild; struct tree *rchild; }*Ptree; typedef Ptree ElementType;typedef struct SNode *Stack;
struct SNode{ ElementType Data; struct SNode *Next;
}; Stack CreateStack();
//判断是否空
int IsEmpty(Stack S);
//Push操作
void Push(ElementType item,Stack S);
//Pop操作
ElementType Pop(Stack S); //树的建立Ptree createTree() ;//先序遍历
void preOrder(Ptree t);
//中序遍历
void intOrder(Ptree t);
//后序遍历
void postOrder(Ptree t); //利用栈先序遍历二叉树
void PreOderTraversal(Ptree BT);
//利用栈中序遍历二叉树
void InOderTraversal(Ptree BT);//利用栈后序遍历
void PostOderTraversal(Ptree BT);
//利用双栈法后序遍历
void PostOderTraversal2(Ptree BT);void main()
{ Ptree t; printf("先序创建二叉树,用空格代表虚结点:\n");t=createTree(); printf("前序遍历:");preOrder(t) ;printf("\n");printf("利用堆栈前序遍历:");PreOderTraversal(t);printf("\n");printf("\n");printf("中序遍历:");intOrder(t) ;printf("\n");printf("利用堆栈中序遍历:");InOderTraversal(t);printf("\n");printf("\n");printf("后序遍历:");postOrder(t) ;printf("\n");printf("利用堆栈后序遍历:");PostOderTraversal(t);printf("\n");printf("利用双栈法后序遍历:");PostOderTraversal2(t);system("pause");
}//堆栈的建立
Stack CreateStack(){ Stack S; S=(Stack)malloc(sizeof(struct SNode)); S->Next=NULL; return S;
}
//判断是否空
int IsEmpty(Stack S){ return(S->Next==NULL);
}
//Push操作
void Push(ElementType item,Stack S){ struct SNode *TmpCell; TmpCell=(struct SNode *)malloc(sizeof(struct SNode)); TmpCell->Data=item; TmpCell->Next=S->Next; S->Next=TmpCell;
} //Pop操作
ElementType Pop(Stack S){ struct SNode *FirstCell; ElementType TopElem; if(IsEmpty(S)){ printf("堆栈空\n"); return NULL; }else{ FirstCell=S->Next; S->Next=FirstCell->Next; TopElem=FirstCell->Data; free(FirstCell); return TopElem; }
} Ptree createTree() //树的建立{ char ch; Ptree t; ch=getchar(); //输入二叉树数据if(ch==' ') //判断二叉树是否为空t=NULL; else { t=(Ptree)malloc(sizeof(Ptree)); //二叉树的生成t->data=ch; t->lchild=createTree(); t->rchild=createTree(); } return t; } void preOrder(Ptree t) //先序遍历 { if(t) { printf("%c",t->data); preOrder(t->lchild); preOrder(t->rchild); } } void intOrder(Ptree t) //中序遍历
{ if(t) { intOrder(t->lchild); printf("%c",t->data); intOrder(t->rchild); } } void postOrder(Ptree t) //后序遍历 { if(t) { postOrder(t->lchild); postOrder(t->rchild); printf("%c",t->data); } } //利用栈先序遍历void PreOderTraversal(Ptree BT){Ptree T=BT;Stack S=CreateStack();while(T||!IsEmpty(S)){while(T){ printf("%c",T->data);Push(T,S);T=T->lchild;}T=Pop(S);T=T->rchild;}};//利用栈中序遍历void InOderTraversal(Ptree BT){Ptree T=BT;Stack S=CreateStack();while(T||!IsEmpty(S)){while(T){Push(T,S);T=T->lchild;}T=Pop(S);printf("%c",T->data);T=T->rchild;}};//利用栈后序遍历void PostOderTraversal(Ptree BT){Ptree T=BT;Ptree TempT=NULL;//Temp记录被检查的节点的右儿子Stack S=CreateStack();while(T||!IsEmpty(S)){while(T){Push(T,S);T=T->lchild;}T=Pop(S);Push(T,S);//相当于返回了栈顶元素// 当前节点的右孩子如果为空或者已经被访问,则访问当前节点 if(T->rchild==NULL||T->rchild==TempT){printf("%c",T->data);TempT=T;Pop(S);T=NULL;}// 否则访问右孩子 elseT=T->rchild; }};//利用双栈法后序遍历
void PostOderTraversal2(Ptree BT) // 后序遍历的非递归 双栈法
{ Ptree T=BT; // 指向当前要检查的节点 Stack S1=CreateStack();Stack S2=CreateStack(); Push(T,S1); while(!IsEmpty(S1)) // 栈空时结束 { T = Pop(S1);Push(T,S2); if(T->lchild)Push(T->lchild,S1); if(T->rchild) Push(T->rchild,S1); } while(!IsEmpty(S2)) { printf("%c", Pop(S2)->data); }
}
其中栈的后序非递归遍历参考了一篇网上的博客,用了两种方法实现了后序遍历
下面是一个具体实现的例子
树是这样的,如下
A
B C
D F G I
E H
前序输入的时候是
ABD##FE###CG#H##I##
执行的结果如下
我只有一个感受。。好厉害。。。
二叉树利用堆栈实现遍历的非递归算法相关推荐
- 二叉树中序遍历的非递归算法
根据二叉树的先序遍历结果创建一棵二叉树,即先创建根结点,然后再创建左子树,最后创建右子树,对于左右子树的创建也遵循根左右的原则,所以对于左右子树的创建可以递归调用本函数,此问题是典型的需要用递归算法求 ...
- 二叉树后序遍历的非递归算法
二叉树的后序遍历的非递归算法与二叉树的先序和中序遍历的非递归算法相比稍微复杂一点. 大致思路是:如果当前结点左右子树均为空,则可以访问当前结点,或者左右子树不均为空,但是前一个访问的结点是当前结点的左 ...
- 数据结构 | 二叉树 先根、中根、后根遍历的非递归算法
上期文章: 数据结构 | 树与二叉树 参考教材:<数据结构>,刘大有 编程语言: C++ 目录 (一)二叉树的存储结构 (二)二叉树的遍历 先根遍历非递归算法 中根遍历非递归算法 后根遍历 ...
- [转载]二叉树先序、中序、后序三种遍历的非递归算法
本贴给出二叉树先序.中序.后序三种遍历的非递归算法,此三个算法可视为标准算法. 1.先序遍历非递归算法 #define maxsize 100 typedef struct { Bitree Elem ...
- 二叉树遍历的非递归算法
大一下半期数据结构 知识点 递归算法虽然简单,但一般而言,其执行效率并不高.对于二叉树的遍历操作,可以仿照递归算法执行过程中工作栈的状态变化得到非递归算法. 一.前序遍历非递归算法 二叉树前序遍历非递 ...
- 数据结构-二叉树(统计二叉树的结点个数递归与非递归算法)
文章目录 思路 Java 实现 思路 求结点个数为什么能用递归? 二叉树求结点个数,从根结点开始,求二叉树结点个数,对于根结点就是求左右子树所有结点数之和再加一,对于左右子树又是如此计算,这样的形式满 ...
- 后序遍历的非递归算法python_二叉树后序遍历(递归与非递归)算法C语言实现...
二叉树后序遍历的实现思想是:从根节点出发,依次遍历各节点的左右子树,直到当前节点左右子树遍历完成后,才访问该节点元素. 图 1 二叉树 如图 1 中,对此二叉树进行后序遍历的操作过程为: 从根节点 1 ...
- 二叉树创建,递归遍历,非递归遍历
二叉树 博主是一个大一刚刚放暑假的大学生,大学我们只学习了c语言,现在这么卷只学c语言肯定不够,所以博主打算从零开始恶补c++顺便写文章记录一下,另外博主这个暑假还想记录一些算法基础内容欢迎关注哦.这 ...
- 二叉树的先序遍历(非递归)
虽然递归简单理解,但是用递归内存开销大,耗时长,性能往往不如非递归方式 所以这里通过栈,用非递归方法实现二叉树的先序遍历 二叉树的存储结构定义: typedef struct node{int dat ...
最新文章
- centos 7安装 navicat
- 不使用第三个变量交换两个变量的值
- 隐藏oracle数据库,如何隐藏Oracle密码
- springMVC注解中@RequestMapping中常用参数value params 以及@RequestParam 详解
- 消息分发的同步均衡策略
- 如何才能成为一个高效工作的软件工程师?
- 文本文件中,如何判断有效换行?
- 【Qt5】评标专家库随机选5人小软件
- 小米路由器3c 虚拟服务器,小米路由器怎么设置_小米路由器3c设置教程-WIFI之家...
- Excel 条件格式实现甘特图
- 计算机四级考试全国通过率,大学英语四级多少分算过 通过率是多少
- KNN算法以及R语言的实现
- Rational License Key Error的永久解决办法
- C++ protected 解析
- Redis基本数据类型,redis官网
- 冰雪之城鸿蒙碎片,冰雪之城地图推荐:
- Win11-GTX3060-配置Pytorch GPU
- VBA运行将多个excel的矩阵类型数据转为向量数据
- CS1503号错误是什么
- 机器越“智能”,数据标注员越容易被淘汰?丨曼孚科技