二叉树的线索化(中序)

目的:

利用链表存储二叉树,其中能够表示出中序遍历二叉树时节点的前驱和后继信息

而当结点的左右子树存在时,其前驱和后继就分别是左孩子,右孩子。

故只需要给左右子树为空的节点加信息就好啦

那就共用左右孩子lchild ,rchild指针,附加一个标志tag来表示其lchid,rchild指向的是左孩子右孩子,还是前驱和后继

链表的数据结构

typedef struct BiThrNode
{                
    char data;                        
    struct BiThrNode *lchild,*rchild;
    int LTag,RTag;
}BiThrNode,*BiThrTree;

下面就是将其线索化了

而我们要给出其遍历时的前驱和后继,那就得自己先走一遍,边走边放线索不是?

所以算法最基本框架是中序遍历

void InThreading(BiThrTree p)
{
 if(p)
  {
   InThreading(p->lchild);     


   cout<<p->data;

                              
   InThreading(p->rchild);                           
   }
}

而对于我们要遍历的每个节点,得知道它的前驱和后继,一个节点来遍历肯定不够啊

所以用两个节点

一个在前, pre  表示p可能的前驱

一个在后,p     p是pre可能的后继

初始时,pre为NULL  p为根节点

当p递归到它左孩子不存在时,pre就排上用场了,p->lchild=pre  Tag置为1

当pre的右节点不存在时,p就派上用场  pre->rchild=p  Tag置为1

然后p一步步遍历,pre跟在它后面,每次判断一下p的左节点是否存在,pre的右节点是否存在

存在的话就老老实实指向左右孩子,不存在就动用前驱后继

利用线索进行遍历

1.找到第一个节点

2.输出该节点,然后一直找它后继,输出

3.后继不存在时就说明该节点它的右节点存在,访问右节点

由于我们已经知道了后继信息,遍历时就让它自己跟着后继一步一步来就行了

                                                                      后继信息

完整代码

#include<iostream>
using namespace std;

typedef struct BiThrNode
{                
    char data;                        
    struct BiThrNode *lchild,*rchild;
    int LTag,RTag;
}BiThrNode,*BiThrTree;

BiThrNode *pre=new BiThrNode;

void CreateBiTree(BiThrTree &T)
{    
    char ch;
    cin >> ch;
    if(ch=='#')  T=NULL;            
    else
    {                            
        T=new BiThrNode;
        T->data=ch;                    
        CreateBiTree(T->lchild);
        CreateBiTree(T->rchild);    
    }                                
}                                

void InThreading(BiThrTree p)
{
 if(p)
  {
   InThreading(p->lchild);                     
   if(!p->lchild)
   {                                           
     p->LTag=1;
 p->lchild=pre;                                 
     

;                             
   } 
   else
     p->LTag=0;
   if(!pre->rchild)
    {                                                
     
pre->RTag=1;                                   
pre->Rchild=p;                             
    }
   else
     pre->RTag=0;
   pre=p;

;                                           
   InThreading(p->rchild);                           
   }
}

void InOrderTraverse_Thr(BiThrTree T)
{ 
   BiThrTree p;
   p=T;                                     
   while(p)                                        
   {                                                
     while(p->LTag==0)                            
       
     p=p->lchild;                            
     cout<<p->data;                              
     while(p->RTag==1)
     {
       

p=p->rchild;                            
       cout<<p->data;                              
     }
     
p=p->rchild;
   }
}                                                    

int main()
{
    pre->RTag=1;
    pre->rchild=NULL;
    BiThrTree tree;
    CreateBiTree(tree);
    InThreading(tree);
    InOrderTraverse_Thr(tree);
    return 0;
}

小白第一次写博客,水平问题定有疏漏,如有错误恳请指正

  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值