数据结构课程设计二叉排序树的实现精编版Word格式文档下载.docx
《数据结构课程设计二叉排序树的实现精编版Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《数据结构课程设计二叉排序树的实现精编版Word格式文档下载.docx(26页珍藏版)》请在冰豆网上搜索。
![数据结构课程设计二叉排序树的实现精编版Word格式文档下载.docx](https://file1.bdocx.com/fileroot1/2022-11/23/e2fbb3cc-f514-4bbd-b26e-7c320bb67ee6/e2fbb3cc-f514-4bbd-b26e-7c320bb67ee61.gif)
t,keytypekey)
若二叉排序树t中存在关键字等于key的数据元素,则删除该数据元素节点,并返回TRUE,否则返回FALSE。
2.4插入模块
二叉排序树是一种动态树表,其特点是树的结构通常不是一次生成的,而是在查找的过程中,当树中不存在关键字等于给定值得节点时在进行插入。
新插入的节点一定是一个新添加的叶子节点,并且是查找不成功时查找路径上访问的最后一个节点的左孩子或右孩子的节点。
一个无序系列可以通过构造一棵二叉排序树而变成一个有序系列,构造树的过程即为对无序系列进行排序的过程,并且每次插入的节点都是二叉排序树上新的叶子节点,则在进行插入操作时,不必移动其他节点,仅需改变某个节点的指针由空变为非空即可。
二叉排序树的插入算法为
bstreeInsertBST(bstreet,intkey,nametypename,doublegrade)
若二叉排序树中不存在关键字等于key的数据元素时,插入元素并返回TRUE。
2.5查找模块
二叉排序树又称二叉查找树,当二叉排序树不为空时,首先将给定的值和根节点的关键字比较,若相等则查找成功,否则将依据给定的值和根节点关键字之间的大小关系,分别在左子树或右子树上继续进行查找。
为此定义一个二叉排序树的查找算法为
bstnode*SearchBST(bstreet,keytypekey)
在根指针t所指向的二叉排序树中查找关键字等于key的数据元素,如成功,返回指向该元素节点的指针,否则返回空指针。
2.6效率比较compare模块
voidcompare()对数组和二叉排序树的查找效率进行比较比较。
2.7二叉排序树的遍历
先序遍历也叫做先根遍历。
首先访问根结点然后遍历左子树,最后遍历右子树。
在遍历左、右子树时,仍然先访问根结点,然后遍历左子树,最后遍历右子树,如果二叉树为空则返回。
其实过程为:
先遍历左子树root->
left->
left...->
null,由于是先序遍历,因此一遇到节点,便需要立即访问;
由于一直走到最左边后,需要逐步返回到父节点访问右节点,因此必须有一个措施能够对节点序列回溯。
其一可以用栈记忆在访问途中将依次遇到的节点保存下来。
根据栈的先进后出、后进先出的特点特点。
则可以用栈保存。
每次都将遇到的节点压入栈,当左子树遍历完毕后从栈中弹出最后一个访问的节点,然后访问其右子树。
基本算法思想:
1.先访问根节点,将根节点入栈
2.重复执行两大步骤:
如果该节点左孩子存在,则访问该左孩子节点,并将其指针入栈。
重复以上操作,直到节点的左孩子不存在。
将栈顶的元素,即其指针出栈,回到父节点,如果该指针节点的右孩子存在,则将该指针指向的右孩子节点重复执行以上步骤,直到桟为空为止。
操作函数为voidx_print(TreeT)
中序遍历:
中序遍历和先序遍历访问的顺序不同。
中序遍历访问顺序为中序遍历左子数,在访问根节点,最后中序遍历右子树。
先序遍历是先访问,再入栈;
而中序遍历则是先入栈,弹栈后再访问。
将二叉树的根节点入栈,如果该节点有左孩子,将左孩子直接入栈,重复该操作,直到该节点无左孩子;
在将栈顶元素出栈,并访问该节点指向的节点,如果该指针指向的右孩子存在,则将当前指针指向右孩子节点。
重复执行步骤直到栈为空为止。
操作函数为voidz_print(TreeT)。
后序遍历:
先后序遍历左子树,在后序遍历右子树,最后访问根节点。
先将根节点入栈,如果该节点左孩子节点存在,将该节点左孩子节点入栈。
重复执行此操作,直到节点左孩子节点为空。
取栈顶元素,并赋值给P,如果P的右孩子为空或P的右孩子等于q(即如果p的右孩子已访问,则访问根节点,即p指向的节点,并用q来记录刚刚访问的节点的指针),若p有右孩子,且右孩子没有别访问过,则p=p->
rchild。
操作函数为voidh_print(TreeT)
3.源代码
#include<
stdio.h>
iostream>
string>
time.h>
#include<
iomanip>
usingnamespacestd;
typedefstringnametype;
typedefunsignedlongkeytype;
typedefstructnode//结点的结构体
{
keytypekey;
nametypename;
intgrade;
structnode*lchild,*rchild;
}bstnode;
typedefbstnode*bstree;
//栈的定义//
typedefstruct{//栈结构
bstree*base;
bstree*top;
intstacksize;
}Sqstack;
intInitStack(Sqstack&
s)//建立一个空栈
s.base=(bstree*)malloc(1000*sizeof(int));
s.top=s.base;
return1;
};
intPush(Sqstack&
s,node*e)//在栈顶插入元素(进栈)
*s.top=e;
s.top=s.top+1;
intPop(Sqstack&
s,bstree&
e)//出栈
if(s.top==s.base)return0;
elses.top=s.top-1;
e=*s.top;
//非递归历遍并输出结点信息//
/*---------------先序非递归遍历---------------*/
voidx_print(node*t)
Sqstacks;
InitStack(s);
bstnode*p;
p=t;
while(p||!
(s.top==s.base))
{
if(p)
{
Push(s,p);
cout<
<
p->
key<
"
\t"
setw(20);
name<
grade<
endl;
p=p->
lchild;
}
else
{
Pop(s,p);
rchild;
}
}
/*---------------中序非递归遍历---------------*/
voidz_print(node*t)
/*---------------非递归后序遍历---------------*/
voidh_print(node*t)
node*p,*q;
q=NULL;
while(p||!
if(p){
p=p->
}else
p=*(s.top-1);
if(p->
rchild==q)
{
Pop(s,q);
p=NULL;
cout<
q->
cout<
q=NULL;
}
//递归查找二叉树//
/*---归查找,若找到就返回指向该结点的指针,否则返回空---*/
bstnode*SearchBST(bstreet,keytypekey){
if(t==NULL||key==t->
key)
returnt;
if(key<
t->
returnSearchBST(t->
lchild,key);
else
rchild,key);
//-------------------给定学生信息插入到二叉树中-------------------//
bstreep,q;
if(t==NULL)//树初始为空,新建二叉树
t=newbstnode();
t->
key=key;
t->
name=name;
grade=grade;
lchild=t->
rchild=NULL;
else
p=t;
while(p)//树已存在,按照二叉排序树的特性查找
q=p;
if(p->
key>
p=q->
elseif(p->
else
树中已有该节点:
returnt;
}
p=newbstnode();
//找不到结点就新建一个结点插入到二叉排序树中
p->
lchild=p->
if(q->
q->
lchild=p;
else
rchild=p;
returnt;
//-------------------二叉树排序树的构建-------------------//
bstreeCreatTree()//不断输入学生信息以插入到二叉树中
bstreet=NULL;
doublegrade;
请输入---学号---姓名---成绩---(输入0时结束):
cin>
>
key;
if(key==0)
name;
grade;
while(key)//key==0时退出
t=InsertBST(t,key,name,grade);
cin>
if(key==0)
break;
//-------------------删除树中的结点-------------------//
voidDelete(bstree&
p)//删除结点的函数
bstreeq,s;
if(!
rchild)
q=p;
p=q->
lchild;
deleteq;
elseif(!
lchild)
p=p->
s=p->
while(s->
q=s;
s=s->
name=s->
if(q!
=p)
rchild=s->
lchild=s->
deletes;
t){
cout<
没有该信息,请重新输入!
;
DeleteData(t,key);
if(t->
key==key)
Delete(t);
//若找到结点直接删除
删除成功!
elseif(t->
DeleteData(t->
lchild,key);
//结点数据比查找关键字大,继续在其左子树中查找
rchild,key);
//结点数据比查找关键字小,继续在其右子树中查找
//数组和二叉排序树的查找效率比较//
voidcompare()
clock_tstart,end,start1,end1;
intnum=0;
inta=0;
intb=0;
intc=0;
intd=1;
bstreep;
stringkey,name;
nametypestr[100][3];
//cout<
(输入0时结束)"
cin>
if(key=="
0"
)
return;
while(key!
="
str[num][0]=key;
str[num][1]=name;
str[num][2]=grade;
intkey1=atoi(key.c_str());
//用库函数将字符串转化为关键字的int型
t=InsertBST(t,key1,name,grade);
//插入结点
cin>
if(key=="
break;
num++;
进行数组和二叉排序树的查询效率比较(比较:
1不比较:
0)"
d;
while(d!
=NULL)
switch(d)
case0:
返回选择界面"
break;
case1:
数组查询!
请输入查询的成绩:
start=clock();
while(a<
=10000000)//循环模拟数组查找
while(b<
=99)
if(str[b][0]==key)
{b=100;
b++;
b=0;
a++;
end=clock();
if(num>
=100)
数组查询:
无查询信息,花费时间:
"
end-start<
毫秒"
查到信息,花费时间:
intkey1=atoi(key.c_str());
//同上转化
start1=clock();
while(c<
=10000000)//用循环来模拟树中查找
p=SearchBST(t,key1);
c++;
end1=clock();
if(p==NULL)
树查询:
end1-start1<
a=0;
c=0;
break;
是否继续进行操作(是:
1否:
0):
//二叉树的深度
intTreeDepth(bstreet)
intleft,right,max;
if(t!
left=TreeDepth(t->
lchild);
right=TreeDepth(t->
rchild);
max=left>
right?
left:
right;
returnmax+1;
return0;
//树状输出二叉树
voidPrintTree(bstreet,intlayer)
intk;
if(t==NULL)
return;
PrintTree(t->
rchild,layer+1);
for(k=0;
k<
layer;
k++)
\n"
lchild,layer+1);
//-------------------主函数测试-------------------//
intmain()
intd;
t=CreatTree();
d=TreeDepth(t);
二叉排序树的树形表示如下"
PrintTree(t,d);
charchoose;
-----------------------------请输入你要选择的操作-------------------------------"
|-------------------------------------|"
||-----------------------------------||"
||a插入信息||"
||b删除信息||"
||c查询信息||"
||d修改信息||"
||0退出||"
||e对二叉排序树进行非递归遍历||"
||f进行数组和二叉树查找效率实验||"
需要选择的操作为:
choose;
while(choose)
switch(choose)
case'
a'
:
//cout<
输入学生信息信息(学号为0时结束)."
if(key==0)/*{