中序线索化二叉树[C语言实现及注释]

 根据我自己的理解给代码加了注释。

 

/*
中序线索二叉树   2014/11/14 */

#include<stdio.h>
#include<stdlib.h>
typedef struct BiTrNoDe{
     char data;
     struct BiTrNoDe *lchild;
     struct BiTrNoDe *rchild;
     unsigned ltag : 1;     //LINK是1      此处也可以用枚举类型或者宏定义去写 
     unsigned rtag : 1;    //threading是0 
}BiTrNode,*BiThre;
                //-----------------------------------------------------------
BiThre pre;        //声明这个指向前驱的pre ,给予其全局变量。 
                  //比如 DBAECF这个中序表示法   B的前驱就是D,同理A便是B的后继 
                 //-----------------------------------------------------------
void InitBiTree(BiThre *T);                   //创建一个二叉树 
void InorderThread(BiThre *p,BiThre T);       //为了弄出一个头指针 
void Inthreading(BiThre T);                  //中序线索后二叉树 
void InorderTraverse(BiThre T);                //遍历二叉树 
int main(void)
{
 BiThre T = NULL,P = NULL;//创建2个结构体的指针,分别是T和P 
 InitBiTree(&T);   //取指针的指针是为了操作这个指针。 
 InorderThread( &P,T); //操作完毕后的指针可以直接拿来用 
 InorderTraverse(P);
 return 0;
}

//用前序递归创建一颗树 
void InitBiTree(BiThre *T)
{
     char c;
     scanf("%c",&c);
     if(' ' == c)
     {
      *T = NULL;
     }
     else{
          *T = (BiTrNode*)malloc(sizeof(BiTrNode));
          (*T)->data = c;
          (*T)->ltag = 1;
          (*T)->rtag = 1;
          InitBiTree(&(*T)->lchild);
          InitBiTree(&(*T)->rchild);
    }
}

void InorderThread(BiThre *p,BiThre T)
{
     *p = (BiTrNode*)malloc(sizeof(BiTrNode));
     if(!*p)exit(-1);    //生成失败就退出
     (*p)->ltag = 1;        //------------------------------------------
     (*p)->rtag = 0;        //设置它的左tag为LINK,右为thread 
                        //------------------------------------------
     (*p)->rchild = (*p);    
 
 
     if( T )         //这个T是创建的那棵树的根.如果它不是空树 
     {
          (*p)->lchild = T;
           pre = (*p );           //这个pre是指向的p,在下面执行的过程中使最左边的那个结点指向p 
           Inthreading(T);
           pre->rchild=*p;        // -------------------------------------------------------------------
           pre->rtag= 0;          //  这3步表示结束后把p指向最右边那个结点,然后把最后边的节点指给pre。 
        (*p)->rchild= pre;  //---------------------------------------------------------------------
   
     }
     else{
          (*p)->rchild = (*p);
     }
 
}
  
//递归遍历并线索化。 
void Inthreading(BiThre T)
{
     if( T )           //如果不为空的就执行,当他空的的时候递归也就结束开始返回了。             
     {
          Inthreading(T->lchild);   //搜索到左边的最后一个节点
  
          if(!T->lchild){     //指向前驱 
               T->ltag = 0;
             T->lchild = pre;
          }
          if(!pre->rchild){       //指向后继 
            pre->rtag = 0;
               pre->rchild = T;
        }
           pre = T;
          Inthreading(T->rchild);   //和上面的同理 
     }
 
}
 
void InorderTraverse(BiThre T)  //这里形参写的不好应该写P ,这个函数里出现的T全是P的意思。。 
{
     BiThre p;
     p = T->lchild;
 
     while(p != T)
     {
          while(p->ltag == 1)
          {
               p = p->lchild;
          }
          printf("%c",p->data);
          while(p->rtag == 0 && p->rchild!=T)//搜索他的后继,直到没有后继 
          {
               p = p->rchild;
               printf("%c",p->data);
          }
          p = p->rchild; //指到"根"的右子树 
     }
}

 

转载于:https://www.cnblogs.com/You0/p/4178248.html

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值