线索二叉树

相关主题
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

#include
#include
#define datatypetbt char
typedef struct thrbitree
{
datatypetbt data;
struct thrbitree *lchild;
struct thrbitree *rchild;
char ltag;
char rtag;
}Thrbitnode,*Thrbitree;
Thrbitree Initiate_Thrbitree()
/*初始化二叉树函数1.先决条件:无2.函数作用:初始化一棵空的带头结点的二叉树,返回头结点的地址*/
{
Thrbitnode *bt;
bt=(Thrbitnode *)malloc(sizeof(Thrbitnode));
bt->lchild=bt;
bt->rchild=bt;
bt->rtag=1;
bt->ltag=1;
return bt;
}
void Precreate_Thrbitree(Thrbitree *T)
/*先序构建二叉树函数1.先决条件:T是子树根结点的地址2.函数作用:以先序遍历序列构造二叉树链表存储的二叉树T*/
{
char ch;
scanf("%c",&ch);
if(ch=='0')
*T=NULL;
else
{
(*T)=(Thrbitnode *)malloc(sizeof(Thrbitnode));
(*T)->data=ch;
(*T)->ltag=0;
(*T)->rtag=0;
Precreate_Thrbitree(&(*T)->lchild);
Precreate_Thrbitree(&(*T)->rchild);
}
}
void Visit_Thrbitree(Thrbitnode *p)
/*访问函数1.先决条件:无2.函数作用:输出一个结点p的数据*/
{
if(p)
printf("%c %x\n",p->data,p);
}
void Intreading_Thrbitree(Thrbitnode *p,Thrbitnode **pre)
/*中序线索化函数1.先决条件:p为树根结点,pre指向p的前驱,即头结点,一般被Inorder_Thrbitree()函数调用;2.函数作用:通过中序遍历进行对二叉树p中序线索化*/
{
if(p)
{
Intreading_Thrbitree(p->lchild,pre);
if(p->lchild==NULL)
{
p->ltag=1;
p->lchild=*pre;
}
if((*pre)->rchild==NULL)
{
(*pre)->rtag=1;
(*pre)->rchild=p;
}
*pre=p;
Intreading_Thrbitree(p->rchild,pre);
}
}
int Inorder_Thrbitree(Thrbitree *T)
/*建立中序线索函数1.先决条件:拥有Intreading_Thrbitree()函数,T为头结点的地址2.函数作用:中序遍历二叉树T,并将其中序线索化,成功返回1*/
{
Thrbitnode *pre;
(*T)->ltag=0;
(*T)->rtag=1;
(*T)->rchild=(*T);
if(!(*T)->lchild)
{
(*T)->ltag=1;
(*T)->lchild=(*T);
}
else
{
pre=(*T);
Intreading_Thrbitree((*T)->lchild,&pre);
pre->rchild=(*T);
pre->rtag=1;
(*T)->rchild=pre;
}
return 1;
}
Thrbitnode *Inprenode_Thrbitree(Thrbitnode *p)
/*中序前驱结点函数1.先决条件:p不为头结点2.函数作用:在中序线索二叉树上寻找结点p的中序前驱结点*/
{
Thrbitnode *pre;
pre=p->lchild;
if(p->ltag!=1)
while(pre->rtag==0)
pre=pre->rchild;
return pre;
}
Thrbitnode *Inpostnode_Thrbitree(Thrbitnode *p)
/*中序后驱结点函数1.先决条件:p不为头结点2.函数作用:在中序线索二叉树上寻找结点p的中序后驱结点*/
{
Thrbitnode *post;
post=p->rchild;
if(p->rtag!=1)
while(post->ltag==0)
post=post->lchild;
return post;
}
int InsertR_Thrbitree(Thrbitnode *s,Thrbitnode *p)
/*线索二叉树右插函数1.先决条件:拥有Visit()和Inpostnode_Thrbitree()函数,s为子树根结点2.函数作用:在中序线索二叉树中插入结点p使其

成为结点s的右孩子,成功返回1*/
{
Thrbitnode *w;
p->rchild=s->rchild;
p->rtag=s->rtag;
p->lchild=s;
p->ltag=1;
s->rchild=p;
s->rtag=0;
if(p->rtag==0)
{
w=Inpostnode_Thrbitree(p);
w->lchild=p;
}
return 1;
}
void Search_Thrbitree(Thrbitree root)
/*遍历中序线索二叉树函数1.先决条件:root为子树根结点,拥有Visit()函数和Inpostnode_Thrbitree()函数2.函数作用:遍历中序线索二叉树root*/
{
Thrbitnode *p,*end;
p=end=root;
while(p->ltag==0)
p=p->lchild;
while(end->rtag==0)
end=end->rchild;
end=end->rchild;
while(p!=end)
{
Visit_Thrbitree(p);
p=Inpostnode_Thrbitree(p);
}
}
int main()
{
Thrbitree bt;
Thrbitnode *address1,*address2,*p;
int choice;
do{
printf("**************************************************************************\n");
printf("1.初始化二叉树 2.先序构建二叉树 3.中序线索化 4.找前驱结点\n");
printf("5.找后继结点 6.右插二叉结点 7.遍历线索二叉树 8.退出\n");
printf("**************************************************************************\n");
printf("请输入选择(1~8):");
scanf("%d",&choice);
getchar();
switch(choice)
{
case 1:if(bt=Initiate_Thrbitree())
printf("初始化成功!\n");
else
printf("初始化失败!\n");break;
case 2:printf("请输入要构建的二叉树的先序序列,以'0'表示空:");
Precreate_Thrbitree(&bt->lchild);
printf("构建成功!\n");
break;
case 3:if(Inorder_Thrbitree(&bt))
printf("二叉树线索化完成.\n");
break;
case 4:printf("请输入地址:");
scanf("%x",&address1);
address2=Inprenode_Thrbitree(address1);
printf("%c %x\n",address2->data,address2);break;
case 5:printf("请输入地址:");
scanf("%x",&address1);
address2=Inpostnode_Thrbitree(address1);
printf("%c %x\n",address2->data,address2);break;
case 6:p=(Thrbitnode *)malloc(sizeof(Thrbitnode));
printf("请输入新增结点的数据:");
scanf("%c",&p->data);
printf("请输入插入地址:");
scanf("%x",&address1);
if(InsertR_Thrbitree(address1,p))
printf("插入成功.\n");;
break;
case 7:Search_Thrbitree(bt->lchild);break;
case 8:printf("谢谢使用!\n");break;
default :printf("输入错误,请重新输入!\n");break;
}
}while(choice!=8);
return 0;
}
/*注意:线索二叉树在线索化之前能用纯二叉树的所有函数.线索二叉树在线索化之后,要用纯二叉树函数,则要把纯二叉树中以NULL为判断标记的
相应的改成ltag,rtag为判断标志,修改是很简单的.当然会改变线索二叉树的线索的有些函数的改动就不是这么简单了.*/

相关文档
最新文档