二叉树递归I_非递归-递归O

来源:互联网 发布:大众软件官方 编辑:程序博客网 时间:2024/05/18 01:37

#include <stdio.h>
#include <stdlib.h>

typedef struct Tnode
{
 char data;             //值域.
 struct Tnode *lchild;  //指针域.
 struct Tnode *rchild;
}  *Bitree;

/*
 用递归创建二叉树.
 出现的问题是:不能使其带参数即 :Bitree Creat1(Bitree T);
*/
Bitree Creat1()
{
 Bitree T;
 char ch;
 scanf("%c",&ch);
 if(ch==' ')      //递归结束条件:即当遇到空时退栈.
  T=NULL;
 else
 {
  T=(Bitree)malloc(sizeof(struct Tnode));   //当输入不为空时分配空间.
  T->data=ch;            //赋值,即将输入传值给结点.
  T->lchild=Creat1();    //输入顺序为:先左子树,退栈后再右子树.
  T->rchild=Creat1();
 }
 return T;      //最后返回整个树.
}

/*
 递归遍历链表.
*/
void Visitorder1(Bitree T)
{
 if(T!=NULL)       //当不为空时执行,也是本函数的退栈条件.
 {
 // printf("%c",T->data); //递归先序输出,即当第一次遇到此结点时.
  Visitorder1(T->lchild); //先遍历左子树.
  //printf("%c",T->data );  //递归中序输出,即当第二次遇到此结点时.
  Visitorder1(T->rchild); //左子树结束后再遍历右子树.
    printf("%c",T->data); //递归后序输出,即当第三次遇到此结点时.
 }
}

/*
 非递归遍历链表.
 此程序不能实现 后序遍历.
 遍历原理:当相遇第一次就打印时为先序,当第二次相遇时打印为中序.
*/
void Visitorder2(Bitree T)
{
 Bitree s[100];  //此数组用于存储非空结点.
 int top;  //用于标识栈顶.
 Bitree p;  //定义中间变量,用于接收T.
 top = -1;  //对栈进行初始化.
 
 p=T;

 while(p!=NULL||top>-1)   //遍历结束条件.
 {
  while(p!=NULL)       //退栈条件.
  {
   printf("%c",p->data); //非递归先序输出,即当第一次遇到此结点时.
   top++;    //前进一个结点.
   s[top]=p;           //存储此结点.
   p=p->lchild;  //先遍历左子树.
  }

  if(top>-1)    //退栈结束条件.
  {
   p=s[top];           //返回到上一个结点.
   top--;    //出一次栈.
   //   printf("%c",p->data);  //非递归中序输出,即第二次遇到该结点时.
   p=p->rchild;   //遍历右子树.
  }
 }
}

/*
 用非递归后序遍历二叉树.
 此函数是对上面的函数的补充.
*/
void Posorder(Bitree T)
{
 struct
 {
  Bitree pp;   //用于存储结点.
  int tag;     //表示相遇的次数.
 }ss[100];         //表示结点的数组.
 
 int top;        //栈标识.
 Bitree p;       //中间变量,用于接收T.
 top=-1;   //对栈进行初始化.

 p=T;

 while(p!=NULL||top>-1)  //遍历结束条件.
 {
  while(p!=NULL)      //左子树遍历结束条件.
  {
   top++;          //下一个结点.
   ss[top].tag=0;  //第一次遇到此结点时初始化为0.
   ss[top].pp=p; //存储此结点.
   p=p->lchild;    //进入下一个左子树.
  }
   
  if(top>-1)   //退栈结束条件.
   if(ss[top].tag==0) 
   {
    ss[top].tag=1;   //再次相遇时记为1.
    p=ss[top].pp;    //退到上一个结点.
    p=p->rchild; //进入右子树.
   }
   else        //此处表示:ss[top].tag==1;
   {
    p=ss[top].pp;    //退到上一个结点.
    printf("%c",p->data);  //打印.
    top--;    //退一次栈.
    /*
     删除掉已经遍历三次的结点,其结果是回到:if(top>-1)而不是while(p!=NULL).
     造成的结果是打印退栈后的结点.如果不清楚的话,画出栈,实际演示一遍.
    */
    p=NULL;      
   }
 }
}  
 

/*
 主函数.
*/
main()
{
 Bitree T;
 T=(Bitree)malloc(sizeof(struct Tnode));
 
 T=Creat1();  //创建二叉树.

 Visitorder1(T);  //递归遍历二叉树.
 printf("/n");
 Visitorder2(T);  //非递归遍历二叉树.
 printf("/n");
 Posorder(T);     //后序非递归遍历二叉树.
 printf("/n");
}
 

原创粉丝点击