二叉排序树课程设计报告.docx
- 文档编号:23644913
- 上传时间:2023-05-19
- 格式:DOCX
- 页数:18
- 大小:189.20KB
二叉排序树课程设计报告.docx
《二叉排序树课程设计报告.docx》由会员分享,可在线阅读,更多相关《二叉排序树课程设计报告.docx(18页珍藏版)》请在冰豆网上搜索。
二叉排序树课程设计报告
计算机科学与技术系
课程设计报告
2008~2009学年第二学期
课程
数据结构与算法
课程设计名称
二叉排序树运算
学生姓名
学号
专业班级
指导教师
2009年6月
一、问题分析和任务定义
题目:
二叉排序树运算
任务定义:
对一组数据构造二叉排序树,并在二叉排序树中实现多种方式的查找。
基本任务:
(1)选择合适的存储结构构造二叉排序树;
(2) 对二叉排序树T作中序遍历,输出结果;(3)在二叉排序树中实现多种方式的查找,并给出二叉排序树中插入和删除的操作。
(4)尽量给出“顺序和链式”两种不同结构下的操作,并比较。
若要完成题目的要求,需要解决以下几个问题:
1、选择一种数据结构存储二叉树的信息。
2、建立一个新的二叉排序树
3、在二叉排序树中插入,删除,查找相关节点
二、数据结构的选择和概要设计
1、数据结构的选择:
题目要求选择合适的存储结构构造二叉排序树,我选择链式结构存储。
用链表的方式构造节点,存储二叉排序树中的节点!
节点类型和指针类型如下!
typedefstructnode
{intkey;
intother;
structnode*lchild,*rchild;
}Bstnode;
2、概要设计:
为了完成所需的功能,需要的函数及其功能如下:
main():
主函数模块
Bsearch():
查找相应的节点
InsertBST():
插入一个新节点
CreateBST():
创建一棵二叉排序树
Inorder():
对二叉排序树进行中序遍历
menu():
主函数显示菜单模块
DeleteBST():
删除节点
主函数流程图:
图(a)主函数流程图
子函数流程图:
插入子函数InsertBST()的流程图:
图(b)子函数InsertBST()的流程图
子函数Bsearch(p)的流程图
图(c)子函数Bsearch(p)的流程图
三、详细设计和编码
二叉排序树的基本操作
1、二叉排序树的查找算法
(1)若二叉排序树为空,则查找失败。
(2)否则,将根结点的关键字与待查关键字进行比较,若相等,则查找成功;若根节点关键字大于待查值,则进入左子树重复次步骤,否则,进入右子树进行此步骤;若在查找过程中遇到二叉排序树的叶子节点时,还没有找到待查节点,则查找不成功。
算法如下:
Bstnode*Bsearch(Bstnode*t,intx)//查找
{Bstnode*p;
intflag=0;p=t;
while(p!
=NULL)
{if(p->key==x)
{printf("已找到该节点!
");flag=1;return(p);break;}
if(x
p=p->lchild;
elsep=p->rchild;
}
if(flag==0)
{printf("找不到值为%d的节点!
",x);returnNULL;}
}
2、二叉排序树的节点插入算法
在二叉排序树中插入一个新节点,首先要查找该节点在二叉排序树中是否已经存在。
若二叉排序树中不存在关键字等于x的节点,则插入。
将一个关键字值为x的节点s插入到二叉排序树中,可以用下面的方法:
(1)若二叉排序树为空,则关键字为x的节点s成为二叉排序树的根‘
(2)若二叉排序树非空,则将x与二叉排序树根进行比较,如果x的值等于根节点关键值,则停止插入;如果x的根节点值小于根节点关键值,则将x插入左子树;如果x的值大于根节点关键字的值,则将x插入右子树。
在左右两个子树的插入方法与整个二叉排序树相同。
算法如下:
Bstnode*InsertBST(Bstnode*t,intx)//插入
{Bstnode*s,*p,*f;p=t;
while(p!
=NULL){
f=p;//查找过程中,f指向*p的父节点
if(x==p->key)returnt;//二叉排序树中已有关键字为x的元素,无序插入
if(x
elsep=p->rchild;
}
s=(Bstnode*)malloc(sizeof(Bstnode));
s->key=x;s->lchild=NULL;s->rchild=NULL;
if(t==NULL)returns;//原树为空,新节点成为二叉排序树的根
if(x
elsef->rchild=s;//新节点作为*f的右孩子
returnt;
}
3、二叉排序树的节点删除算法
在二叉排序树中删除节点,首先要进行查找操作,以确定被删除的节点是否在二叉排序树中
若不在,则不做任何操作;否则,假设要删除的节点为*p,节点*p的父节点为*f,并假设*p是*f的左孩子。
根据被删除节点*p有无孩子,删除部分可做以下3中情况讨论:
(1)若*p为叶子节点,则可令其父节点*f的左孩子指针域为空,直接将其删除。
(2)若*p节点只有右子树或左子树,则可以将p的左子树或右子树直接改为其双亲节点f的左子树。
(3)若*p既有左子树又有右子树;将节点*s为*p的中序前驱。
首先找到*p的中序前驱节点*s,然后用节点*s的值代替节点*p的值,再将节点*s删除,节点*s的原左子树改为*s的双亲节点*q的右子树;
算法如下:
Bstnode*DeleteBST(Bstnode*t,intk)//删除
{
Bstnode*p,*f,*s,*q;p=t;f=NULL;
while(p){//查找关键字为k的待删节点*p
if(p->key==k)break;//找到,则退出循环
f=p;//节点*f为节点*p的父节点
if(p->key>k)p=p->lchild;
elsep=p->rchild;
}
if(p==NULL)returnt;//若找不到,则返回原二叉排序树的根指针
if((p->lchild==NULL)||(p->rchild==NULL)){//若*p无左孩子或右孩子
if(f==NULL)//若*p是原二叉排序树的根
if(p->lchild==NULL)t=p->rchild;
elset=p->lchild;
elseif(p->lchild==NULL)//若*p无左孩子
if(f->lchild==p)f->lchild=p->rchild;//p是*f的左孩子
elsef->rchild=p->rchild;
elseif(f->lchild==p)//若*p无右孩子
f->lchild=p->lchild;//p是*f的左孩子
elsef->lchild=p->lchild;//p是*f的右孩子
free(p);
}
else{
q=p;s=p->lchild;//若p有左右子树
while(s->rchild){
q=s;s=s->rchild;//在*p的左子树中查找最右下节点
}
if(q==p)q->lchild=s->lchild;
p->key=s->key;//将*s的值赋给*p
free(s);
}
returnt;
}
四、上机调试
1、我所写的程序和课本上的二叉排序树基本相同!
但是在调试过程中遇到了一些问题。
我采用的是非递归思想进行遍历,所以存在的基本的语法错误,问题主要在于函数和变量的定义。
关键字和函数名的书写。
2、时间,空间性能分析:
二叉排序树的的查找与二分查找类似,是一个逐一缩小查找范围的过程。
具有n个节点的排序二叉树是一棵深度为n的单枝树,平均查找长度与顺序查找相同,为(n+1)/2;即平均查找长度的数量级为O(n)。
五.测试结果及其分析
1、输入节点信息:
图
(1)输入节点信息图
2、显示菜单后,根据提示选择操作
选择插入一个新节点
图
(2)插入新节点图
3、继续选择操作,查找一个已有的节点
图(3)查找一个已有节点图
4、查找一个没有的节点。
图(4)查找一个没有的节点图
5、删除一个节点
图(5)删除一个节点图
6、若操作已完成,则退出程序。
图(6)退出图
六、用户使用说明
1、用户更具提示输入二叉排序树的节点信息并且以0结束输入
2、根据菜单提示选择相应的操作
3、输出的结果是中序遍历后的结果
七、参考文献
[1]王昆仑,李红等编著.数据结构与算法.北京:
中国铁道出版社,2007.
[2]李业丽,郑良斌编著。
数据结构(c)实验教程。
北京理工大学出版社2005
八、附录(源代码)
#include"stdio.h"
#include"malloc.h"
#defineNULL0
typedefstructnode
{intkey;
intother;
structnode*lchild,*rchild;
}Bstnode;
Bstnode*Bsearch(Bstnode*t,intx)//查找
{Bstnode*p;
intflag=0;p=t;
while(p!
=NULL)
{if(p->key==x)
{printf("已找到该节点!
");flag=1;return(p);break;}
if(x
p=p->lchild;
elsep=p->rchild;
}
if(flag==0)
{printf("找不到值为%d的节点!
",x);returnNULL;}
}
Bstnode*InsertBST(Bstnode*t,intx)//插入
{
Bstnode*s,*p,*f;p=t;
while(p!
=NULL){
f=p;//查找过程中,f指向*p的父节点
if(x==p->key)returnt;//二叉排序树中已有关键字为x的元素,无序插入
if(x
elsep=p->rchild;
}
s=(Bstnode*)malloc(sizeof(Bstnode));
s->key=x;s->lchild=NULL;s->rchild=NULL;
if(t==NULL)returns;//原树为空,新节点成为二叉排序树的根
if(x
elsef->rchild=s;//新节点作为*f的右孩子
returnt;
}
Bstnode*CreateBST()//创建一个新的二叉树
{
Bstnode*t;intkey;t=NULL;//设置二叉排序树的初态为空
scanf("%d",&key);//读入第一个节点的关键字
while(key!
=0){
t=InsertBST(t,key);scanf("%d",&key);
}
returnt;
}
voidInorder(Bstnode*T)//中序遍历
{
if(T){//若二叉树不空
Inorder(T->lchild);//中序遍历左子树
printf("%4d",T->key);//访问根节点
Inorder(T->rchild);//中序遍历右子树
}
}
Bstnode*DeleteBST(Bstnode*t,intk)//删除
{
Bstnode*p,*f,*s,*q;p=t;f=NULL;
while(p){//查找关键字为k的待删节点*p
if(p->key==k)break;//找到,则退出循环
f=p;//节点*f为节点*p的父节点
if(p->key>k)p=p->lchild;
elsep=p->rchild;
}
if(p==NULL)returnt;//若找不到,则返回原二叉排序树的根指针
if((p->lchild==NULL)||(p->rchild==NULL)){//若*p无左孩子或右孩子
if(f==NULL)//若*p是原二叉排序树的根
if(p->lchild==NULL)t=p->rchild;
elset=p->lchild;
elseif(p->lchild==NULL)//若*p无左孩子
if(f->lchild==p)f->lchild=p->rchild;//p是*f的左孩子
elsef->rchild=p->rchild;
elseif(f->lchild==p)//若*p无右孩子
f->lchild=p->lchild;//p是*f的左孩子
elsef->lchild=p->lchild;//p是*f的右孩子
free(p);
}
else{
q=p;s=p->lchild;//若p有左右子树
while(s->rchild){
q=s;s=s->rchild;//在*p的左子树中查找最右下节点
}
if(q==p)q->lchild=s->lchild;
p->key=s->key;//将*s的值赋给*p
free(s);
}
returnt;
}
voidmenu()
{printf("┏━━━━━━━━━━━━━━━┓\n");
printf("┃1----------插入节点-----------┃\n");
printf("┠───────────────┨\n");
printf("┃2----------查找节点-----------┃\n");
printf("┠───────────────┨\n");
printf("┃3----------删除节点-----------┃\n");
printf("┠───────────────┨\n");
printf("┃4-----------退出--------------┃\n");
printf("┗━━━━━━━━━━━━━━━┛\n");
}
voidmain(){
Bstnode*tree,*p;intseai,deli,x;
intk,flag=1;
printf("请输入节点信息,并以‘0’结束:
\n");tree=CreateBST();
printf("中序遍历所得序列为:
\n");Inorder(tree);
printf("\n");
menu();
while(flag)
{
printf("请选择操作:
");
scanf("%d",&k);
switch(k)
{
case1:
{printf("插入一个新的节点:
");scanf("%d",&x);InsertBST(tree,x);
printf("插入后,中序遍历所得序列:
\n");Inorder(tree);printf("\n");
break;}
case2:
{
printf("输入查找的数据:
");scanf("%d",&seai);
p=Bsearch(tree,seai);printf("\n");
break;}
case3:
{
printf("输入删除的数据:
");scanf("%d",&deli);
tree=DeleteBST(tree,deli);
printf("删除后,中序遍历所得序列:
\n");
Inorder(tree);printf("\n");
break;}
case4:
{flag=0;break;}
}
}
}
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 二叉排序树 课程设计 报告