数据结构线索二叉树实验报告.docx
《数据结构线索二叉树实验报告.docx》由会员分享,可在线阅读,更多相关《数据结构线索二叉树实验报告.docx(15页珍藏版)》请在冰点文库上搜索。
数据结构线索二叉树实验报告
线索二叉树应用实验
实验报告
实验目的
(1)掌握线索二叉树的有关知识。
(2)掌握求解线索二叉树中结点前趋和后继的算法以及以相应次序遍历线索二叉树的算法。
(3)掌握二叉树的线索化算法的设计。
实验运行环境
VisualC++
实验任务
线索二叉树是为了快速求解二叉树中结点在指定次序下的前驱和后继,而将二叉链表中空的左右孩子指针分别改为指向其前驱和后继结点而得到的结构,反映了运算对数据结构的设计的影响。
因此,首先要了解线索二叉树的结构特点,其中原本为空的指针被修改为前驱和后继指针,使得对左右子树和线索的判断发生了变化。
利用线索可以实现某些次序下的前驱和后继。
本实验期望能理解线索二叉树的结构特点,实现各前驱和后接算法的求解,并掌握将二叉树转换为线索二叉树的算法,即线索化算法。
为使实验程序简洁直观,下面的部分实验程序中的一些功能实现仍以调用库函数程序"btrechar.h"中的函数的形式给出,并假设该库函数中定义了线索二叉树的相关功能,如显示线索二叉树等。
实验内容
第一题:
按先序次序遍历先序线索二叉树。
实验测试数据基本要求:
第一组数据:
full41.cbt
第二组数据:
letter.cbt
实验准备:
1:
将二叉树的根结点的指针传给函数。
2:
判断当前结点是否为先序遍历的最后一个结点,若是则访问完该结点后结束,否则进入3。
2:
判断当前结点是否有左子树,若有的话访问完该结点后访问它的左子树,否则访问它的右子树,返回2。
第二题:
按中序次序遍历中序线索二叉树。
实验测试数据基本要求:
第一组数据:
full41.cbt
第二组数据:
letter.cbt
实验准备:
1:
将二叉树的根结点的指针传给函数。
2:
判断当前结点是否为中序遍历的最后一个结点,若是则访问完该结点后结束,否则进入3。
3:
对于当前结点,先访问该结点的前驱结点并进入第二步,其次访问该结点并进入第二步最后访问该结点的后继结点并进入2。
第三题:
将值为x的结点作为先序线索二叉树T的左子树的(先序)最后一个结点的右孩子插入进去。
实验测试数据基本要求:
第一组数据:
full41.cbt
第二组数据:
letter.cbt
实验准备:
1:
将先序线索二叉树的根结点的指针传给函数。
2:
判断当前结点是否为要找的结点P,若是则建立一个新的结点,将新结点作为P的右孩子,并根据新建的结点修改前驱后继关系,否则进入3。
3:
指针指向该结点先序遍历的后继,返回2。
第四题:
按中序次序线索化二叉树。
实验测试数据基本要求:
第一组数据:
full41.cbt
第二组数据:
letter.cbt
实验准备:
1:
设立两个指针pre与t分别代表前驱结点与当前结点。
2:
按照中序访问的顺序,对于访问到的每一个结点进行如下的操作。
3:
判断当前结点是否为空,若是则结束,否则进入第四步。
4:
对于当前结点如果它的左孩子为空,则将该结点前驱线索化,
如果它的前驱指针pre指向的结点的右孩子为空,则将pre指向的结点后继线索化,
如果对于当前结点如果它的右孩子为空,则将该结点的rchild置为1,将t赋值给pre。
5:
将t指向它在中序中的后继,返回到3。
第五题:
按后序次序线索化二叉树。
实验测试数据基本要求:
第一组数据:
full41.cbt
第二组数据:
letter.cbt
实验准备:
1:
设立两个指针pre与t分别代表前驱结点与当前结点。
2:
按照后序访问的顺序,对于访问到的每一个结点进行如下的操作。
3:
判断当前结点是否为空,若是则结束,否则进入4。
4:
对于当前结点如果它的左孩子为空,则将该结点前驱线索化,
如果它的前驱指针pre指向的结点的右孩子为空,则将pre指向的结点后继线索化,
如果对于当前结点如果它的右孩子为空,则将该结点的rchild置为1,将t赋值给pre。
5:
将t指向它在后序中的后继,返回到3。
实验测试数据
实验程序
#include
usingnamespacestd;
intm;
structtbnode
{
chardata;
tbnode*lchild,*rchild;
intltag,rtag;
};
tbnode*pre=NULL;//初始化前驱指针
classtbtree{
public:
tbtree();
intheight(tbnode*p);
voidprepare_tree(tbnode*&p);//初始化二叉树
voidfirst_tree(tbnode*p);//先序线索化
voidsecond_tree(tbnode*p);//中序线索化
voidthird_tree(tbnode*p);//后序线索化
voidfirst_first_tree(tbnode*p);//先序编历先序线索化二叉树
voidsecond_second_tree(tbnode*p);//中序编历中序线索化二叉树
tbnode*&get_root(){returnroot;}
tbnode*prepare(tbnode*p)
{
if(p->ltag==0)returnp->lchild;
elsereturnp->rchild;
}
tbnode*start(tbnode*p)
{
if(p->rtag==1)
returnp->rchild;
else
{
tbnode*q=p->rchild;
while(q->ltag!
=1)
q=q->lchild;
returnq;
}
}
private:
tbnode*root;
};
tbtree:
:
tbtree()
{
root=newtbnode;
root=NULL;
}
inttbtree:
:
height(tbnode*p)//求二叉树的高度函数
{
intch_1,ch_2;
if(p==NULL)return(0);
else
{
ch_1=height(p->lchild);
ch_2=height(p->rchild);
if(ch_1>ch_2)return(ch_1+1);
else
returnch_2;
}
}
voidtbtree:
:
prepare_tree(tbnode*&p)//初始化二叉树
{
chara;
cin>>a;
if(a=='.')p=NULL;
else{
p=newtbnode;
p->data=a;
prepare_tree(p->lchild);
prepare_tree(p->rchild);
}
}
voidtbtree:
:
first_tree(tbnode*p)//先序次序线索化二叉树
{
if(p!
=NULL){
if(p->lchild==NULL){
p->ltag=1;
p->lchild=pre;
}
elsep->ltag=0;
if(pre!
=NULL&&pre->rtag==1)pre->rchild=p;
if(p->rchild==NULL)p->rtag=1;
elsep->rtag=0;
}
cout<data;
pre=p;
if(p->ltag==0)first_tree(p->lchild);
if(p->rtag==0)first_tree(p->rchild);
}
voidtbtree:
:
second_tree(tbnode*p)//中序次序线索化二叉树
{
if(p!
=NULL){
second_tree(p->lchild);
if(pre!
=NULL&&pre->rtag==1)pre->rchild=p;
if(p->lchild==NULL){
p->lchild=pre;
p->ltag=1;
}
elsep->ltag=0;
if(p->rchild==NULL)p->rtag=1;
elsep->rtag=0;
cout<data;
pre=p;
if(p->rtag==0)second_tree(p->rchild);
}
}
voidtbtree:
:
third_tree(tbnode*p)
{
if(p!
=NULL){
third_tree(p->lchild);
third_tree(p->rchild);
if(pre!
=NULL&&pre->rtag==1)pre->rchild=p;
if(p->lchild==NULL){
p->ltag=1;
p->lchild=pre;
}
if(p->rchild==NULL)p->rtag=1;
elsep->rtag=0;
cout<data;
pre=p;
}
}
voidtbtree:
:
first_first_tree(tbnode*p)//先序编历先序线索化二叉树
{
while(p!
=NULL){
cout<data;
p=prepare(p);
}
}
voidtbtree:
:
second_second_tree(tbnode*p)//中序编历中序线索化二叉树
{
while(p->ltag!
=1)p=p->lchild;
while(p!
=NULL){
cout<data;
p=start(p);
}
}
intmain()
{
tbtreeT;
intchoice;
{
cout<cout<<"数据结构实验四--线索二叉树应用实验"<cout<cout<<"第1题:
按先序次序遍历先序线索二叉树"<cout<<"第2题:
按中序次序遍历中序线索二叉树"<cout<<"第3题:
将值为x的结点作为先序线索二叉树T的左子树的(先序)"<cout<<"最后一个结点的右孩子插入进去"<cout<<"第4题:
按中序次序线索化二叉树"<cout<<"第5题:
按后序次序线索化二叉树"<cout<<"退出程序:
0"<cout<cout<<"请选择一道题"<cin>>choice;
switch(choice)
{
case1:
{
cout<<"此操作是按先序次序遍历先序线索二叉树"<cout<cout<<"输入所建立二叉树的元素"<cout<tbnode*p;
T.prepare_tree(p);
T.first_tree(p);
cout<T.first_first_tree(p);
break;
}
case2:
{
cout<<"此操作是按中序次序遍历先序线索二叉树"<cout<cout<<"输入所建立二叉树的元素"<cout<tbnode*p;
T.prepare_tree(p);
T.second_tree(p);
T.second_second_tree(p);
break;
}
case3:
{
cout<<"此操作是将值为x的结点作为先序线索二叉树T"<cout<<"的左子树的(先序)最后一个结点的右孩子插入进去"<cout<<"输入所建立二叉树的元素"<cout<tbnode*p;
T.prepare_tree(p);
T.first_tree(p);
T.first_first_tree(p);
cout<<"请输入所要插入的值:
"<cin>>choice;
T.first_first_tree(p);
break;
}
case4:
{
cout<<"按中序次序线索化二叉树"<cout<cout<<"输入所建立二叉树的元素"<tbnode*p;
T.prepare_tree(p);
T.second_tree(p);
break;
}
case5:
{
cout<<"按后序次序线索化二叉树"<cout<cout<<"输入所建立二叉树的元素"<tbnode*p;
T.prepare_tree(p);
T.third_tree(p);
break;
}
case0:
{
cout<<"EXIT"<break;
}
default:
{cout<<"输入错误,请重新输入"<}
}
return0;
}