二叉树c++实现实验报告.docx
《二叉树c++实现实验报告.docx》由会员分享,可在线阅读,更多相关《二叉树c++实现实验报告.docx(17页珍藏版)》请在冰豆网上搜索。
二叉树c++实现实验报告
HUNANUNIVERSITY
实验报告
题目BST
学生姓名
学生学号
专业班级
指导老师
完成日期2013.05.03
1、需求分析
(1)使用二叉树(BST)来实现。
(2)二叉树使用链式结构(二叉链表)实现。
(3)实现BST的构建,查找两个功能。
(4)输入输出要求:
输入:
8//BST的节点个数
34,76,45,18,26,54,92,65//8个数据
45//查找45
输出:
查找成功3//返回成功和查找时比较的次数
34//查找34
输出:
查找成功1//返回成功和查找时比较的次数
100//查找100
输出:
查找不成功3//返回成功和查找时比较的次数
2、概要设计
抽象数据类型
输入的数值都为int类
每个节点都有左右两个指针,左指针指向左孩子,右指针指向右孩子,若没有子孩子,指针为空。
算法的基本思想
此代码为参照书上的bst的类模版写成的。
因此还编写了其他非此次实验要求的函数。
书上没有insert函数,所以自己补了两个函数:
BinNode*inserthelp(BinNode*subroot,constint&val);boolinsert(constint&e)。
每个步骤都是由两个函数构成,为了解决公有私有的问题,并且由于需要递归,解决输入根节点的问题。
美观实用。
程序的流程
程序由三个模块组成:
(1)输入模块:
输入想建立的树的个数,再依次输入数的元素。
(2)建树输出模块:
利用链表建立一颗BST树,分别由前序和中序输出,确定一颗二叉树。
(3)查找模块:
输入想要查找的数值,屏幕输出查找结果和比较次数。
3、详细设计
物理数据类型
1.用链表表达各个数据元素之间的关系,左边的小的数据,右边的放大的数据
算法的具体步骤
输入函数的步骤分析
BinNode*inserthelp(BinNode*subroot,constint&val)
{
if(subroot==NULL)//Emptytree:
createnode
returnnewBinNode(val,NULL,NULL);
if(KEComp:
:
lt(val,subroot->val()))//Insertonleft
{
subroot->setright(inserthelp(subroot->right(),val));
}
else
{
subroot->setleft(inserthelp(subroot->left(),val));
}
returnsubroot;//Returnsubtreewithnodeinserted
}
比较类的具体内容:
classKEComp{
public:
staticboollt(constintk,inte)
{returnk>e;}
staticbooleq(constintk,inte)
{returnk==e;}
staticboolgt(constintk,inte)
{returnk};
注:
此类是用于比较,并不是必须使用,由于在后面的调试中便于检查,在查找函数中并没有用此类。
查找函数的具体步骤分析:
boolfindhelp(BinNode*subroot,constint&k,int&e,inttimes)const
{
if(subroot==NULL)returnfalse;//如果为空树
elseif(k>subroot->val())
{
times++;
e=subroot->val();
returnfindhelp(subroot->right(),k,e,times);
}
elseif(kval())//如果查找的值小于树根结点
{
times++;
e=subroot->val();
returnfindhelp(subroot->left(),k,e,times);
}
else//如果查找的值大于等于树根结点
{
times++;
cout<<"Times:
"<returntrue;
}
}
算法的时空分析
后序遍历的时间代价为Θ(n)
空间代价为每一个数值有两个指针,若为叶节点则两个指针为空。
输入和输出的格式
输出:
Pleaseinputanumber:
输入:
(想建立的树的数值个数)
输出:
Pleaseinputamenbers:
输入:
依次输入每个元素的值
输出:
前序输出中序输出
输出:
Pleaseinputanumberyouwanttosearch:
输入:
(想要查找的数值)
输出:
查找结果和查找次数
五、测试结果
六、用户使用说明(可选)
1、按提示输入,只能输入整数型的数。
2、Times表示比较次数,Success!
表示查找成功,Fail!
表示查找失败。
七、实验心得(可选)
1.
这次试验的优点是在不断地调试和运行之后终于实现了这个代码,完成了c++创建BST的全部过程,让我的这个小组对如何建树的了解有人更加深入的认识,完成了BST的所有的基本操作,但是缺点在于这次试验的代码的输出没有直观的按照树的形式输出,在树的查找函数中没有用比较类,这一点在前面也有提到。
2.
本次实现要求我们建造二叉树并且完成查找的功能。
我们组在不断地讨论,修改和完善之后终于用c++完成了以上两个功能。
在讨论的过程中,对二叉树的基本概念有了更深的认识,不断编出了程序,更是加深了自己对课本知识的理解。
但是,补充的两条功能:
插入和删除,我们未能完成,这也是我们这次实验的不足之处,希望我们能在学有余力的情况下,对选作内容有所涉猎吧。
3.
在做二叉查找树这个实验的时候,我的思路的这样的,在建树的过程中:
首先是将第一个输入的数字默认为根节点,然后所有输入的数字、按照二叉查找树的特征进行一系列的比较,然后确定他们正确的位置,以链式的结构存储,然后通过前序与中序遍历的方式输出其形式(前序与中序确定以唯一的二叉树);在查找的过程中,从二叉查找树本身的特点入手,没查找一个结点,计数器加1,如果找到该结点,输出计数器的数值,显示查找成功,否则也输出查找次数,显示查找不成功;
思路想的非常迅速,并且自我感觉良好,但是真正编程实现的时候遇到的麻烦不止一点两点,首先是对二叉树的构造还不是非常的熟练,然后运用二叉查找树的性质去查找某数值时又废了些时候,再就是需要建的类太多,写的函数太多,感觉好乱。
看来我写函数比较多程序的能力还没有锻炼出来。
一多就乱,这方面需要加强。
最终我是在室友的帮助下一起完成的,虽然自己尽的力不多,但是却从中收获很多。
7、附录(可选)
#include
usingnamespacestd;
/*******************************BinNode************************************************/
classBinNode{
private:
intit;
BinNode*lc;
BinNode*rc;
public:
BinNode(){lc=rc=NULL;}
BinNode(inte,BinNode*l=NULL,BinNode*r=NULL)
{
it=e;
lc=l;
rc=r;
}
~BinNode(){}
int&val(){returnit;}//
voidsetVal(const&e){it=e;}//
BinNode*left(){returnlc;}//
voidsetleft(BinNode*b){lc=(BinNode*)b;}//
BinNode*right(){returnrc;}//
voidsetright(BinNode*b){rc=(BinNode*)b;}//
boolisLeaf(){return(lc==NULL)&&(rc==NULL);}//
};
/********************************KEComp****************************************************/
classKEComp{
public:
staticboollt(constintk,inte)
{returnk>e;}
staticbooleq(constintk,inte)
{returnk==e;}
staticboolgt(constintk,inte)
{returnk};
/*******************************BST*******************************************************/
classBST{
private:
BinNode*root;
intnodecount;
inttimes;
voidclearhelp(BinNode*subroot)
{
if(subroot==NULL)return;
clearhelp(subroot->left());
clearhelp(subroot->right());
deletesubroot;
}
/****************************inserthelp******************************************/
BinNode*inserthelp(BinNode*subroot,constint&val)
{
if(subroot==NULL)//Emptytree:
createnode
returnnewBinNode(val,NULL,NULL);
if(KEComp:
:
lt(val,subroot->val()))//Insertonleft
{
subroot->setright(inserthelp(subroot->right(),val));
}
else
{
subroot->setleft(inserthelp(subroot->left(),val));
}
returnsubroot;//Returnsubtreewithnodeinserted
}
/*****************************deletemin******************************************/
BinNode*deletemin(BinNode*subroot,BinNode*&min)
{
if(subroot->left()==NULL)
{
min=subroot;
returnsubroot->right();
}
else
{
subroot->setleft(deletemin(subroot->left(),min));
returnsubroot;
}
}
/****************************removehelp************************************************/
BinNode*removehelp(BinNode*subroot,constint&k,BinNode*&t)
{
if(subroot==NULL)returnfalse;
elseif(KEComp:
:
lt(k,subroot->val()))
subroot->setleft(removehelp(subroot->left(),k,t));
elseif(KEComp:
:
gt(k,subroot->val()))
subroot->setright(removehelp(subroot->right(),k,t));
else
{
BinNode*temp;
t=subroot;
if(subroot->left()==NULL)
subroot=subroot->right();
elseif(subroot->right()==NULL)
subroot=subroot->left();
else
{
subroot->setright(deletemin(subroot->right(),temp));
intte=subroot->val();
subroot->setVal(temp->val());
temp->setVal(te);
t=temp;
}
}
returnsubroot;
}
/*******************************findhelp**************************************/
boolfindhelp(BinNode*subroot,constint&k,int&e,inttimes)const
{
if(subroot==NULL)returnfalse;
elseif(k>subroot->val())
{
times++;
e=subroot->val();
returnfindhelp(subroot->right(),k,e,times);
}
elseif(kval())
{
times++;
e=subroot->val();
returnfindhelp(subroot->left(),k,e,times);
}
else
{
times++;
cout<<"Times:
"<returntrue;
}
}
public:
BST(){root=NULL;nodecount=0;}
~BST(){clearhelp(root);}
voidclear()
{
clearhelp(root);
root=NULL;
nodecount=0;
}
/************************************************************************/
boolremove(constint&k,int&e)
{
BinNode*t=NULL;
root=removehelp(root,k,t);
if(t==NULL)returnfalse;
e=t->val();
nodecount--;
deletet;
returntrue;
}
boolremoveAny(int&e)
{
if(root==NULL)returnfalse;
BinNode*t;
root=deletemin(root,t);
e=t->val();
deletet;
nodecount--;
returntrue;
}
/***************************************************************************/
boolinsert(constint&e)
{
root=inserthelp(root,e);
nodecount++;
returntrue;
}
/************************************powerfind*********************************************************/
/*BinNode*find(BinNode*t,constint&x,int×)//查找函数
{
times++;
if((x>t->val()&&t->right()==NULL)||(xval()&&t->left()==NULL))
{
cout<<"查找不成功,查找次数为:
"<//insert(t,x);
return0;
}
if(t->val()==x)
cout<<"查找成功,查找次数为:
"<elseif(x>=t->val())
find(t->right(),x,times);
else
find(t->left(),x,times);
returnt;
}*/
/****************************************************************************************/
boolfind(constint&k,int&e)const
{
intt=0;
returnfindhelp(root,k,e,t);
}
intsize(){returnnodecount;}
/******************************************输出1*******************************************/
voidpreorderhelp(BinNode*subroot)
{
if(subroot==NULL)return;
else
{
cout<val()<<"";
preorderhelp(subroot->left());
preorderhelp(subroot->right());
}
}
voidpreorder()
{
preorderhelp(root);
}
/******************************************输出2*******************************************/
voidnutorderhelp(BinNode*subroot)
{
if(subroot==NULL)return;
else
{
nutorderhelp(subroot->left());
cout<val()<<"";
nutorderhelp(subroot->right());
}
}
voidnutorder()
{
nutorderhelp(root);
}
/**************************************************************************************/
};
intmain()
{
inta;//number
intz;//input
intf;//find
inte;
intm=0;
BinNode*p=NULL;
BSTb;
cout<<"Pleaseinputanumber:
"<cin>>a;
cout<<"Pleaseinput"<"<cin>>z;
e=z;
if(cin.good()==0){cout<<"ERROR!
!
!
Pleaseinputintegers!
!
!
\n";return0;}
b.insert(z);
for(intj=1;j{
cin>>z;
if(cin.good()==0){cout<<"ERROR!
!
!
Pleaseinputintegers!
!
!
\n";return0;}
b.insert(z);
}
cout<<"printout:
"<cout<<"Preorder:
";
b.preorder();
cout<<"nutorder:
";
b.nutorder();
cout<cout<<"Pleaseinputanumberyouwanttosearch:
"<cin>>f;
//if(b.find(b.root,f,m))
if(b.find(f,e))
cout<<"\nSuccess!
"<else
cout<<"\nFail!
"<return0;
}