您的位置:首页 > 编程语言 > C语言/C++

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

2010-11-21 00:43 441 查看
/************************线索链表的实现*************************/

#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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c++ thread null struct