先序线索化.docx
《先序线索化.docx》由会员分享,可在线阅读,更多相关《先序线索化.docx(7页珍藏版)》请在冰豆网上搜索。
![先序线索化.docx](https://file1.bdocx.com/fileroot1/2022-11/25/0b40ecf8-9f8d-4dcd-bf5b-8f07e30fe511/0b40ecf8-9f8d-4dcd-bf5b-8f07e30fe5111.gif)
先序线索化
南通大学数据结构实践课
实验报告册
姓名:
耿智
班级:
软件工程092
学号:
0913063042
实验名称:
先序线索化
指导老师:
丁卫平
南通大学杏林学院
2011年6月16日
1.程序设计简介
本实验程序用于验证二叉树的先序线索化及先序线索二叉树先序遍历算法,为了查看线索结果,增加了线索显示功能。
设计时综合考虑到中序线索化需求,采用设计一个基类,然后在此基础上生成所需的对象。
2.源程序
#include"Base.cpp"
template
classCPreThreading:
publicCThr
{
boolIsThreaded;
public:
CPreThreading(){IsThreaded=false;}
voidPre_ThreadBiTree();//生成先序线索二叉树
voidPre_Thread(BiThrNode*p,BiThrNode**h);//先序线索
voidPre_TraThrBiTree();//遍历先序线索二叉树
voidShowPreTree();//显示线索化后的信息
};
template
voidCPreThreading:
:
Pre_ThreadBiTree()
{//生成先序线索二叉链表
BiThrNode*bt,*q=NULL;
bt=BT;//根结点
Pre_Thread(bt,&q);
}
//--------------------------------------------------------------------------------
template
voidCPreThreading:
:
Pre_TraThrBiTree()
{
if(IsThreaded==false){cout<<"请先线索化!
"<cout<<"\n--------------------------------------------------"<cout<<"遍历先序线索二叉树得:
";
BiThrNode*p;
if(BT==NULL)return;//二叉链表为空
cout<data<<'';//输出根结点的值
p=BT->lchild;//沿左子树
if(p==NULL)p=BT->rchild;//左子树为空则沿右子树
while(p!
=NULL)
{
cout<data<<'';//输出当前结点的值
while(p->lflag==0)//沿左链访问直到左标志非0
{
p=p->lchild;
cout<data<<'';
}
p=p->rchild;
}
cout<<"\n--------------------------------------------------"<}
//--------------------------------------------------------------------------------
template
voidCPreThreading:
:
Pre_Thread(BiThrNode*bt,BiThrNode**h)
{
BiThrNode*p,*q;//定义两个结点指针变量
if(bt!
=NULL)//bt指向的结点不空
{
p=bt->lchild;
q=bt->rchild;
//若当前访问的结点的左指针为空,则将上次访问的结点赋给左指针域,并置标志域
if((*h!
=NULL)&&(p==NULL))
{
bt->lchild=*h;
bt->lflag=1;
}
//若上次访问的结点的右指针为空
//则将访问过的结点指针赋给当前结点的右指针域,并置标志域为1
if((*h!
=NULL)&&((*h)->rchild==NULL))
{
(*h)->rchild=bt;
(*h)->rflag=1;
}
*h=bt;//记下当前访问的结点
Pre_Thread(p,h);//访问左子树
Pre_Thread(q,h);//访问右子树
}
IsThreaded=true;
}
//--------------------------------------------------------------------------------
template
voidCPreThreading:
:
ShowPreTree()
{
if(IsThreaded==false){cout<<"请先线索化!
"<cout<<"\n--------------------------------------------------"<cout<<"下面显示的是先序线索化以后的结果:
"<BiThrNode*p;
if(BT==NULL)return;//二叉链表为空。
if(BT->lflag==1)//如果标志域为1,输出它的前驱。
cout<<"值为:
"<data<<"结点的前驱是:
"<lchild->data<if(BT->rflag==1)//如果标志域为1,输出它的后继。
cout<<"值为:
"<data<<"结点的后继是:
"<rchild->data<p=BT->lchild;//沿左子树。
if(p==NULL)p=BT->rchild;//左子树为空则沿右子树。
while(p!
=NULL)
{
if(p->lflag==1)//如果标志域为1,输出它的前驱。
cout<<"值为:
"<data<<"结点的前驱是:
"<lchild->data<if(p->rflag==1)//如果标志域为1,输出它的后继。
cout<<"值为:
"<data<<"结点的后继是:
"<rchild->data<while(p->lflag==0)//沿左链访问直到左标志非0
{
p=p->lchild;
if(p->lflag==1)//如果标志域为1,输出它的前驱。
cout<<"值为:
"<data<<"结点的前驱是:
"<lchild->data<if(p->rflag==1)//如果标志域为1,输出它的后继。
cout<<"值为:
"<data<<"结点的后继是:
"<rchild->data<}
p=p->rchild;
}
cout<<"--------------------------------------------------"<}
//--------------------------------------------------------------------------------
voidmain()
{
intopr;//操作变量
CPreThreadingTr;//创建一个int模板类型的对象
do{
system("cls");
cout<<"----------菜单---------------"<cout<<"--*1:
创建二叉树*--"<cout<<"--*2:
先序线索化二叉树*--"<cout<<"--*3:
先序线索化二叉树先序遍历*--"<cout<<"--*4:
显示先序线索信息*--"<cout<<"--*5:
退出操作*--"<cout<<"--------------------------------"<cout<<"请选择操作[]";
cout<<"\b\b";
cin>>opr;
switch(opr)
{
case1:
if(Tr.GetRoot())Tr.DeleteNode();//释放之前创建的对象的所有结点空间
Tr.CreateBiTree(-1);//创建二叉树
system("pause");
break;
case2:
Tr.Pre_ThreadBiTree();//先序线索化二叉树
cout<<"线索化完成!
"<system("pause");
break;
case3:
Tr.Pre_TraThrBiTree();//先序遍历二叉树
system("pause");
break;
case4:
Tr.ShowPreTree();//显示线索化之后的标志域信息
system("pause");
break;
case5:
cout<<"结束运行,Bye-Bye!
"<break;
default:
cout<<"选择不合理,请重选!
"<break;
}
}while(opr!
=5);
}
3.程序运行
4.调试感想
在线索化二叉树时,如果像书上把二叉树和线索二叉树的存储结构分开,则二叉树中的数据域不能传递到线索二叉树中(两个类型的指针不能互相赋值)。
比较两种存储结构发现,线索二叉树比二叉树多了两个标志域LTag,Rtag。
于是两种存储结构合并为BiThrNode,并在建立二叉树时把LTag,Rtag均设置为Link。