线索链表的实现 C++代码实现

/************************线索链表的实现*************************/

#include <iostream>
using namespace std;

/*线索链表的类型定义*/
typedef enum{Child,Thread} Flag;
typedef struct ThrNode
{
       char data;
       struct ThrNode *lchild,*rchild;
       Flag ltag,rtag;
}ThrNode, *ThrTree;

/*建立中序线索链表*/

//先序建立普通的二叉链表
void CreateBiTree(ThrTree &TT)
{
       char ch;
       cin>>ch;
       if(ch=='0')
              TT=NULL;
       else
       {
              TT=new ThrNode;
              TT->data=ch;
              TT->ltag=Child;
              TT->rtag=Child;//刚开始结点的线索标识都初始化为Child。
              CreateBiTree(TT->lchild);
              CreateBiTree(TT->rchild);
       }
}

//普通的二叉链表进行中序线索化
void InThreading(ThrTree &p,ThrTree &pre)
{
       if(p==NULL)
              return;
       InThreading(p->lchild,pre);//对p结点的左子树线索化
       if(!p->lchild)//如果p无左孩子
       {
              p->ltag=Thread;
              p->lchild=pre;//让p的左指针域建立线索,指向前驱
       }
       if(!p->rchild)//如果p无右孩子
       {
              p->rtag=Thread;//因为p的后继还不知道,故右指针域先不建立线索
       }
       if(pre!=NULL)
       {
              if(pre->rtag==Thread)
                     pre->rchild=p;//对pre结点加后继线索
       }
       pre=p;
       InThreading(p->rchild,pre);//对p的右子树线索化
}

//调用上面两个函数建立中序线索链表
void CreateInThrTree(ThrTree &TT)
{
       ThrTree pre;
       ThrTree p;

       CreateBiTree(TT);

       pre=NULL;//pre初始为空
       p=TT;//p初始为头结点
       InThreading(p,pre);
}


/*在中序线索链表上求结点的前驱*/
ThrNode * InThrTreePrior(ThrTree &TT,ThrNode *p)
{
       ThrNode *q;
       if(p->lchild==NULL)
       {
              cout<<"P-Node have not Prior-Node!";//p为第一个结点,第一个结点无前驱
              return NULL;
       }
       else if(p->ltag==Thread)
              q=p->lchild;//p结点的左指针域为前驱线索,该类结点大多为叶结点
       else
       {
              q=p->lchild;
              while(q->rtag==Child)
                     q=q->rchild;//p结点无前驱线索,则p的前驱应是以p为根结点的左子树的最右下结点,
                                 //该类结点大多为各子树的根结点
       }
       return q;
}


/*在中序线索链表上求结点的后继*/
ThrNode * InThrTreeNext(ThrTree &TT,ThrNode *p)
{
       ThrNode *q;
       if(p->rchild==NULL)
       {
              cout<<"P-Node have not Next-Node!";//p为最后一个结点,无后继
              return NULL;
       }
       else if(p->rtag==Thread)
              q=p->rchild;//p结点的右指针域为后继线索,该类结点大多为叶结点
       else
       {
              q=p->rchild;
              while(q->ltag==Child)
                     q=q->lchild;//p结点无后继线索,则p的后继是以p为根结点的右子树的最左下结点,
                                 //这类结点大多是各子树的根结点
       }
       return q;
}


/*中序线索链表上的中序遍历*/
void InOrderThrTree(ThrTree &TT)
{
       ThrNode *p;
       if(TT==NULL)
              return;
       p=TT;
       while(p->ltag==Child)
              p=p->lchild;//先找到第一个结点

       cout<<p->data<<" ";

       while(p->rchild!=NULL)//此处循环的条件是只要p的右指针域不为空,但最后一个结点的右指针域为空
       {
              p=InThrTreeNext(TT,p);//把p的后继赋值给p,此处为线索链表遍历的简洁快速之处
              cout<<p->data<<" ";
       }
       cout<<endl;
}


/*实例应用:寻找某个具体结点的前驱*/
ThrNode * InThrTreePrior_Ex(ThrTree &TT,char x)
{
       ThrNode *p;
       p=TT;
       if(TT==NULL)
              return NULL;

       while(p->ltag==Child)
       p=p->lchild;//先找到第一个结点

       while(p->rchild!=NULL&&p->data!=x)
       {
              p=InThrTreeNext(TT,p);
       }
       p=InThrTreePrior(TT,p);
       return p;

}

void main()
{
       ThrTree TT;
       CreateInThrTree(TT);

       InOrderThrTree(TT);//中序遍历输出结点

       //查找某个具体结点的前驱
       char ch;
       ThrNode *p;
       cout<<"要查找哪个结点的前驱:";

       cin>>ch;

       p=InThrTreePrior_Ex(TT,ch);

       cout<<"结点 "<<ch<<" 的前驱是 "<<p->data<<endl;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值