C语言数据结构:非递归遍历二叉树

非递归遍历二叉树

这一部分内容并不难,可就是找不到完整的可实现代码教程,书上也只是粗略带过,不死心的我决定编程实现一下,也算是对我数据结构树遍历这一部分的检验。
查错排错还是花了不少时间,不多赘述,代码如下:

#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代替
在这里插入图片描述
结果如下:
在这里插入图片描述
**总结:**程序要用到树和栈,算是比较考验基本功的一道题,网上我能查到的方法,大都直接把栈用数组代替写到遍历的函数里了,本人更推荐那种写法,而本文就算是较基础且直白的写法吧。
希望能够帮到正在准备考研或工作的读者。

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

事多做话少说

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值