二叉排序树的实现Word文档下载推荐.docx
《二叉排序树的实现Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《二叉排序树的实现Word文档下载推荐.docx(14页珍藏版)》请在冰豆网上搜索。
该模块功能主要是给用户提供清晰的可操作界面,易于人机操作。
并能很好的调用其他各模块,使程序更加优化,思路更加清晰,结构更加明了,提高了程序的实用性。
其算法如下:
voidmain()
{nodeT=NULL;
intnum;
intch=0;
nodep=NULL;
printf("
pleaseinputalistofnumbersendwithzero:
"
);
do{scanf("
%d"
&
num);
if(!
num)printf("
youhavefinishedyourinput!
\n"
elseinsertBST(&
T,num);
}while(num);
\n\n---themenuoftheopperation---\n"
/*主程序菜单*/
\n0:
exit"
);
\n1:
inordertravelthetree"
\n2:
delete"
while(ch==ch)
{printf("
\nchoosetheopperationtocontinue:
scanf("
ch);
switch(ch){
case0:
exit(0);
/*0--退出*/
case1:
Theresultoftheinordertraverseis:
\n"
inorderTraverse(&
T);
/*1--中序遍历*/
break;
case2:
Pleaseinputthenumberyouwanttodelete:
/*3--删除某个结点*/
if(searchBST(T,num,NULL,&
p))
{
T=Delete(T,num);
Youhavedeletethenumbersuccessfully!
}
elseprintf("
Nonode%dyouwanttodelete!
num);
default:
Yourinputiswrong!
pleaseinputagain!
/*输入无效字符*/
}
3.2.2查找模块
该模块是给用户提供查找功能。
其查找过程是:
若二叉排序树为空,则查找失败,结束查找,返回信息NULL;
否则,将要查找的值与二叉排序树根结点的值进行比较,若相等,则查找成功,结束查找,返回被查到结点的地址,若不等,则根据要查找的值与根结点值的大小关系决定是到根结点的左子树还是右子树中继续查找(查找过程同上),直到查找成功或者查找失败为止。
searchBST(nodet,intkey,nodef,node*p)/*查找函数*/
{
t){*p=f;
return(0);
}/*查找不成功*/
elseif(key==t->
data){*p=t;
return
(1);
}/*查找成功*/
elseif(key<
t->
data)searchBST(t->
lchild,key,t,p);
/*在左子树中继续查找*/
elsesearchBST(t->
rchild,key,t,p);
/*在右子树中继续查找*/
3.2.3插入模块
在二叉排序树中插入新结点,要保证插入后的二叉树仍符合二叉排序树的定义。
插入过程:
若二叉排序树为空,则待插入结点*p作为根结点插入到空树中;
当非空时,将待插结点关键字p->
item和树根关键字t->
item进行比较,若p->
item=t->
item,则无须插入,若p->
item<
t->
item,则插入到根的左子树中,若p->
item>
item,则插入到根的右子树中。
而子树中的插入过程和在树中的插入过程相同,如此进行下去,直到把结点*p作为一个新的树叶插入到二叉排序树中,或者直到发现树已有相同关键字的结点为止。
insertBST(node*t,intkey)/*插入函数*/
nodep=NULL,s=NULL;
searchBST(*t,key,NULL,&
p))/*查找不成功*/
s=(node)malloc(sizeof(BSTnode));
s->
data=key;
lchild=s->
rchild=NULL;
p)*t=s;
/*被插结点*s为新的根结点*/
p->
data)p->
lchild=s;
/*被插结点*s为左孩子*/
elsep->
rchild=s;
/*被插结点*s为右孩子*/
return
(1);
elsereturn(0);
/*树中已有关键字相同的结点,不再插入*/
3.2.4中序遍历模块
遍历(Traversal)是指沿着某条搜索路线,依次对树中每个结点均做一次且仅做一次访问。
访问结点所做的操作依赖于具体的应用问题。
二叉树共有三个部分组成,即根结点,根结点的左子树,根结点的右子树。
限定以从左至右方式共有三种遍历方式,即前序遍历,中序遍历,后序遍历。
中序遍历的原则:
若被遍历的二叉树为非空,则依次执行如下操作:
a)以中序遍历方式遍历左子树;
b)访问根结点;
c)以中序遍历方式遍历右子树。
inorderTraverse(node*t)/*中序遍历函数*/
if(*t){
if(inorderTraverse(&
(*t)->
lchild))/*中序遍历根的左子树*/
%d"
(*t)->
data);
/*输出根结点*/
rchild));
/*中序遍历根的右子树*/
return
(1);
3.2.5删除模块
删除模块:
删除结点函数,采用边查找边删除的方式。
如果没有查找到,则不对树做任何的修改;
如果查找到结点,则分四种情况分别进行讨论:
a)该结点左右子树均为空,可以直接进行删除;
b)该结点仅左子树为空,右子树不为空,用右子树的根结点取代被删除结点的位置;
c)该结点仅右子树为空,左子树不为空;
d)该结点左右子树均不为空,找到被删除结点右子树中值的最小的结点,并用该结点取代被删除节点的位置。
nodeDelete(nodet,intkey)/*删除函数*/
nodep=t,q=NULL,s,f;
while(p!
=NULL)/*查找要删除的点*/
if(p->
data==key)break;
q=p;
data>
key)p=p->
lchild;
elsep=p->
rchild;
if(p==NULL)returnt;
/*查找失败*/
lchild==NULL)/*p指向当前要删除的结点*/
if(q==NULL)t=p->
/*q指向要删结点的父母*/
elseif(q->
lchild==p)q->
lchild=p->
/*p为q的左孩子*/
elseq->
rchild=p->
/*p为q的右孩子*/
free(p);
else{/*p的左孩子不为空*/
f=p;
s=p->
while(s->
rchild)/*左拐后向右走到底*/
f=s;
s=s->
if(f==p)f->
/*重接f的左子树*/
elsef->
rchild=s->
/*重接f的右子树*/
p->
data=s->
data;
free(s);
returnt;
4.运行结果及算法分析
4.1运行结果
图3主菜单界面
图4中序排列效果图
图5删除成功效果图
图6删除不成功效果图
4.2算法分析
若二叉树有n个结点深度为h,中序遍历算法的时间复杂度为O(n),空间复杂度为O(h)。
5.实验心得
课程设计是培养学生综合运用所学知识,发现提出分析和解决实际问题,锻炼实践能力的重要环节,是对学生实际能力的具体训练和考察过程。
回顾数据设计这些日子,至今我感慨颇多,的确,学到了很多的东西包括以前在课本上没有学到的知识,还使我懂的了理论和时间结合是很重要
通过这次课程设计,我加深了对数据结构这门课程的理解,更好的掌握了各种二叉数的递归与非递归,树与二叉树的转换。
以及树的中序的递归,非递归算法,层次序的非递归算法的实现,更巩固了自己的C和C++的知识。
在老师的指导、书本上和网络上查找资料下,终于把程序编出来,在此非常感谢老师对我的指导。
6.程序代码
#include<
stdio.h>
#include<
stdlib.h>
typedefstructTnode{
intdata;
/*输入的数据*/
structTnode*lchild,*rchild;
/*结点的左右指针,分别指向结点的左右孩子*/
}*node,BSTnode;
searchBST(nodet,intkey,nodef,node*p)/*查找函数*/
}/*查找不成功*/
}/*查找成功*/
/*在右子树中继续查找*/
rchi