非递归遍历二叉树
这一部分内容并不难,可就是找不到完整的可实现代码教程,书上也只是粗略带过,不死心的我决定编程实现一下,也算是对我数据结构树遍历这一部分的检验。
查错排错还是花了不少时间,不多赘述,代码如下:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define elemtype char
#define maxsize 50
typedef struct node //二叉树结构体
{
elemtype tdata;
struct node *lchild,*rchild;
}node,*tree;
typedef struct stack //栈结构体,栈内数据为树的结点
{
node *sdata[maxsize];
int top;
}stack;
void initstack(stack &S){ //栈初始化
S.top=-1;
}
tree createtree(tree &T) //建立二叉树
{
elemtype a;
scanf("%c",&a);
fflush(stdin);
if(a=='#')
{
T=NULL;
}
else
{
T=(tree)malloc(sizeof(node));
T->tdata=a;
T->lchild=createtree(T->lchild);
T->rchild=createtree(T->rchild);
}
return T;
}
int stackempty(stack S) //判断栈空
{
if(S.top==-1) return 1;
else return 0;
}
void push(stack &S,node *a) //入栈,忽略栈满的情况
{
S.sdata[++S.top]=a;
}
void pop(stack &S,node *&a) //一定要加取地址符!!!不然每次读取的都是空结构体!!!搞了我俩小时!!!!!
{ //在遍历时判断栈空,此处忽略不写
a=S.sdata[S.top--];
}
node *gettop(stack s,node *a) //读栈顶元素
{
a=s.sdata[s.top];
return a;
}
void inorder(tree T) //中序
{
stack s;
initstack(s);
tree p=T;
while(p||!stackempty(s))
{
if(p)
{
push(s,p);
p=p->lchild;
}
else
{
pop(s,p);
printf("%c",p->tdata);
p=p->rchild;
}
}
}
void preorder(tree T) //先序
{
stack s;
initstack(s);
tree p=T;
while(p||!stackempty(s))
{
if(p)
{
printf("%c",p->tdata);
push(s,p);
p=p->lchild;
}
else
{
pop(s,p);
p=p->rchild;
}
}
}
void postorder(tree T) //后序,与中序先序稍有不同,解法很妙
{
stack s;
initstack(s);
tree p=T;
tree r=NULL;
while(p||!stackempty(s))
{
if(p)
{
push(s,p);
p=p->lchild;
}
else
{
p=gettop(s,p); //先读取栈顶元素
if(p->rchild&&p->rchild!=r) //若该元素右孩子存在且右孩子没被访问过
{
p=p->rchild; //往右遍历
push(s,p);
p=p->lchild; //再向左遍历
}
else
{
pop(s,p); //否则将结点出栈
printf("%c",p->tdata); //访问
r=p; //r指向最近访问的元素
p=NULL; //p为空,不然不为空会走到第一个if再次入栈
}
}
}
}
void freetree(tree &t) //用完就释放,养成好习惯,栈因为和其他不共用内存,不需要我们删除
{
while(t!=NULL) //递归遍历释放内存
{
freetree(t->lchild);
freetree(t->rchild);
free(t);
}
}
void main()
{
tree t;
printf("请输入二叉链表:\n");
t=createtree(t);
printf("先序遍历序列为:");
preorder(t);
printf("\n中序遍历序列为:");
inorder(t);
printf("\n后序遍历序列为:");
postorder(t);
freetree(t);
}
编译结果
建立如图二叉树(建难一点,序列看的直观):因为数据建的char型,所以读不出二位数10,改用0代替
结果如下:
**总结:**程序要用到树和栈,算是比较考验基本功的一道题,网上我能查到的方法,大都直接把栈用数组代替写到遍历的函数里了,本人更推荐那种写法,而本文就算是较基础且直白的写法吧。
希望能够帮到正在准备考研或工作的读者。