线索二叉树

有n个结点的二叉树必然有n+1个空链域。(n个结点的二叉树有n-1个链域)
线索二叉树中的规定:
1.如果结点有左孩子,让其lchild指向左孩子;否则,让其lchild指向其前驱
2.如果结点有右孩子,让其rchild指向右孩子;否则,让其rchild指向其后继

这样就需要在原有的二叉树结点结构上,增加两个域
lchild
ltag
data
rtag
rchild

定义:
    typedef enum{Link,Thread}PointerTag;
    typedef struct BiThrNode
    {
          TElemType dat;
          struct BiThrNode *lchild, *rchild;
          PointerTag LTag,RTag;
    }BiThrNode, *BiThrTree;
 在二叉树的线索链表上添加一个头结点,并令其lchild指向二叉树的头结点,rchild指向遍历访问的最后一个结点。

 线索二叉树的遍历:找到序列的第一个结点,依次找结点后继直至其后继为空为止。
  
 线索二叉树的中序遍历:
//中序遍历,先遍历结点的左子树,然后尽力遍历其带后继线索的结点,直到没有后继线索,转入其右子树
 Status InOrderTraverse_Thr(BiThrTree T,Status (*Visit)(TElemType e))
 {
     p =  T->lchild;
     while(p != T)
     {
       //访问其左子树为空的结点
      while(p -> lTag == Link)
 {
  p = p-> lchild;
        visit(p);
 }
       //访问后继结点,只要有后继,放心遍历,直到没有后继标记,即rtag== link,
       //那么就需要指向它的右子树
       while(p->RTag == Thread && p != T){ p = p->rchild; visit(p);}
      
       p = p->rchild;
     }
     return OK;
 }
  中序线索化:
  线索化过程实际上就是在遍历的过程中修改空指针的过程。
  附设全局指针pre始终指向刚刚访问过的结点。
 
  Status InOrderThreading(BiThrTree &Thrt, BiThrTree T)
  {
      //初始化头结点
      Thrt  = (BiThrTree)malloc(sizeof(BiThrNode));
      if(Thrt)  exti(OVERFLOW);
   
      Thrt -> LTag = Link;
      Thrt -> RTag = Thread; Thrt ->rchild = Thrt;

      if(!T) Thrt->lchild =Thrt;
      else
      {
           //头结点指向根节点
      Thrt->lchild = T;
           pre = Thrt;
          
           InThreading(T);//在InThreading中pre会改变,只要把它定义为全局的静态变量

           pre -> RTag = Thread;  pre->rchild = Thrt;
           Thrt->rchil = pre;
      }  
  }

void InThreading(BiThrTree p)
{
 if(p)
 {
    InThreading(p->lchild);
      if(!p->lchild)    {p->LTag = Thread; p->lchild = pre;}
      if(!pre->rchild)  {pre->RTag = Thread; pre->rchild = p;}
      InThreading(p->rchild);
 }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值