二叉排序树的基本操作.docx
《二叉排序树的基本操作.docx》由会员分享,可在线阅读,更多相关《二叉排序树的基本操作.docx(21页珍藏版)》请在冰豆网上搜索。
![二叉排序树的基本操作.docx](https://file1.bdocx.com/fileroot1/2023-3/19/26ca330c-2e49-4ba5-a58e-8bce3519f66e/26ca330c-2e49-4ba5-a58e-8bce3519f66e1.gif)
二叉排序树的基本操作
井冈山大学
电子与资讯工程学院
数据结构课程设计报告
(2012——2013年度第一学期)
课程名称:
数据结构课程设计
题目一:
6.4.1二叉排序树基本操作的实现
院系:
计算机科学系
班级:
10软件本二班
姓名:
XX
学号:
100913005
指导教师:
孙凌宇老师
成绩:
2012年12月01日
成绩评定
一、指导教师评语
二、成绩
成绩
备注
指导教师:
日期:
年月日
设计题目<一>:
6.4.1二叉排序树基本操作的实现
一、设计要求
1.问题描述
从键盘读入一组数据,建立二叉排序树并对其进行查找、插入、遍历、打印输出操作。
测试数据元素关键词序列为{11,33,44,55,58,79,88}.
1.需求分析
(1)建二叉排序树。
按照用户需要的二叉排序树,构建二叉排序树。
(2)按照树形结构打印输出二叉排序树。
(3)对二叉排序树进行遍历操作。
(4)对二叉排序树进行查找,包括成功和不成功两种情况,并给出查找长度。
(5)对二叉排序树进行插入操作。
二、概要设计
1.主接口设计
图1二叉排序树操作程序主菜单
2.存储结构设计
本程序主要采二叉树结构类型来表示二叉排序树。
其中二叉树节点由1个表示关键词的分量组成,还有数据域(data)、左孩子指针域(Lchild)、和右孩子指针域(Rchild)。
3.系统功能设计
本程序除了完成二叉排序树的创建功能外还设置了5个子功能菜单。
由于这5个子功能都是建立在二叉排序树的构造上,所以二叉排序树的创建由主函数main()实现。
5个子功能的设计描述如下:
(1)建立二叉排序树。
根据系统提示,输入节点的关键词,并以-1作为结束的标识符。
该功能由BstreeCreate()函数实现。
(2)树状输出二叉排序树。
树状输出二叉排序树有函数TranslevelPrint()实现。
当用户选择该功能时,系统即以树状的形式输出用户所创建的二叉排序树。
(3)在二叉排序树中插入新结点。
由函数BstreeInsert()实现。
当用户选择该功能时,系统即在二叉排序树中自动插入添加的新结点,构建新的二叉排序树。
(4)在二叉排序树中查找结点。
由函数BstreeSearch()实现。
该功能按照二叉排序树数组元素的顺利对比找出关键词key,查找成功就给出查找长度,否则输出无此结点。
(5)遍历二叉排序树。
由函数voidTraverse()实现。
该功能是将输入的数组元素按顺序依次输出。
三、模块设计
1.模块设计
本程序包含两个模块:
主程序模块和二叉排序树操作模块。
其调用关系如图2
图2二叉排序树模块调用关系
2.系统子程序及功能设计
本系统共设计了5个子程序,个程序的的函数名及其功能说明如下:
BstreeCreate();//创建二叉排序树
BstreeInsert(Bstreetree,intkey);//插入
BstreeSearch(Bstreetree,intkey);//查找
voidTraverse(Bstreetree);//遍历
voidTranslevelPrint(Bstreebt);//树状打印
3.函数主要调用关系图
图3函数主要调用关系
四、详细设计
1.数据类型定义
typedefstructBstnode
{//本系统采用二叉树结构存储节点信息
intkey;//数据域
structBstnode*lchild,*rchild;//左右孩子指针域
}Bstnode,*Bstree;
2.系统主要子程序详细设计
(1)主函数模块和工作区模块设计
voidmain()
{
system("color9E");
Bstreetree=NULL,p;
intkey1,key2,key3;
intselect,flag;
printf("______________________________________________________________\n");
printf("||\n");
printf("|-----------------欢迎使用二叉排序树基本操作程序---------------|\n");
printf("|---_____________________________________---|\n");
printf("|---︱----菜单选项----︱---|\n");
printf("|---︱1.创建二叉排序树2.打印操作︱---|\n");
printf("|---︱3.插入操作4.查找操作︱---|\n");
printf("|---︱5.遍历操作6.退出操作︱---|\n");
printf("|---⊥__________________________⊥---|\n");
printf("|-----------------【零式】制作—QQ:
461595940-----------------|\n");
printf("|______________________________________________________________|\n");
printf("【零式提醒】请输入您的选择并回车:
");
while(select!
=6)
{
scanf("%d",&select);
switch(select)
{
case1:
printf("【零式提醒】请输入一组数据元素,两两之间用空格隔开,结尾以-1结束:
\n");
tree=Create();
printf("\n");
break;
case2:
printf("【零式提醒】树形图打印输出如下:
\n");
TranslevelPrint(tree);
break;
case3:
printf("【零式提醒】请插入一个新的节点:
");
scanf("%d",&key1);
if(Tree==NULL)
printf("【零式提醒】请先创建二叉树,再进行插入操作!
");
else
{
Insert(Tree,key1);
printf("【零式提醒】看菜单请选择您需要的操作并按回车继续!
");
}
printf("\n");
break;
case4:
printf("【零式提醒】请输入查找的数据:
");
scanf("%d",&key2);
p=Search(Tree,key2);
break;
case5:
printf("【零式提醒】遍历后的序列为:
\n");
Traverse(Tree);
printf("\n【零式提醒】看菜单请选择您需要的操作并按回车继续!
\n");
break;
case6:
printf("【零式制作】欢迎再次使用!
");
flag=0;break;
default:
printf("【零式提醒】您的输入错误,请重新输入:
");
break;
}
}
}
(2)建立二叉排序树模块
BstreeCreate()
{
intkey,flag=0;//标志
Bstreetree=NULL;//初始化空树
scanf("%d",&key);
while(key!
=-1)//创建二叉排序树以-1为结束
{flag=1;
tree=Insert(tree,key);//逐个插入节点
scanf("%d",&key);
}
if(flag)
printf("【零式提醒】二叉排序树已创建成功!
\n");
printf("【零式提醒】看菜单请选择您需要的操作并按回车继续!
");
returntree;
}
(3)树状输出二叉排序树
voidTranslevelPrint(Bstreebt)
{//本算法实现二叉树的按层打印
structnode
{
Bstreevec[MAXLEN];//存放树结点
intlayer[MAXLEN];//结点所在的层
intlocate[MAXLEN];//打印结点的位置
intfront,rear;
}q;//定义队列q
inti,j=1,k=0,nLocate;
q.front=0;q.rear=0;//初始化队列q队头,队尾
printf("");
q.vec[q.rear]=bt;//将二叉树根结点如队列
q.layer[q.rear]=1;
q.locate[q.rear]=20;
q.rear=q.rear+1;
while(q.front{
bt=q.vec[q.front];
i=q.layer[q.front];
nLocate=q.locate[q.front];
if(j
{
printf("\n");printf("\n");
j=j+1;k=0;
while(k{
printf("");k++;
}
}
while(k<(nLocate-1))//利用结点深度控制横向位置
{
printf("");k++;
}
printf("%d",bt->key);
q.front=q.front+1;
if(bt->lchild!
=NULL)//存放在左子树,将左子树根结点如队列
{
q.vec[q.rear]=bt->lchild;
q.layer[q.rear]=i+1;
q.locate[q.rear]=(int)(nLocate-pow(2,NLAYER-i-1));
q.rear=q.rear+1;
}
if(bt->rchild!
=NULL)//存放右子树,将右子树根结点入队列
{
q.vec[q.rear]=bt->rchild;
q.layer[q.rear]=i+1;
q.locate[q.rear]=(int)(nLocate+pow(2,NLAYER-i-1));
q.rear=q.rear+1;
}
}
printf("\n【零式提醒】看菜单请选择您需要的操作并按回车继续!
\n");
}
五、测试分析
请根据程序提示进行操作和使用。
各子功能测试运行结果如下。
(1)创建二叉排序树
在主菜单下,用户输入1并回车,运行结果如图4(a)所示。
图4(a)创建二叉排序树
然后输入数据元素,以-1为结尾并回车,运行结果如图4(b)所示。
图4(b)创建二叉排序树
(2)树状打印二叉排序树
根据提示输入2并回车,运行结果如图5所示。
图5树形打印二叉排序树
(3)在二叉排序树中插入新结点。
根据提示输入3并回车,运行结果如图6(a)所示。
图6(a)二叉排序树插入新结点
根据提示,输入想要插入的结点元素,例如插入9并回车,运行结果如图6(b)所示。
图6(b)二叉排序树插入新结点
然后再次输入2并回车,查看二叉排序树打印结果,如图6(c)所示。
图6(c)二叉排序树插入新结点
(4)根据提示输入4并回车进行查找操作,运行结果如图7(a)所示。
如图7(a)查找二叉排序树结点元素
然后根据提示操作,例如输入12并回车,运行结果如图7(b)所示。
图7(b)查找二叉排序树结点元素
继续输入4并回车,输入想要查找的结点元素(例如33)并回车,运行结果如图7(c)所示。
图7(c)查找二叉排序树结点元素
(5)对二叉排序树进行遍历。
根据提示输入5并回车,运行结果如图8所示。
图9遍历二叉排序树
(6)退出。
根据提示输入6并回车,即退出此操作程序。
六、用户手册
(1)本程序执行文件为“二叉排序树的基本操作的实现.exe”。
(2)进入本程序之后,首先按照提示创建二叉排序树(末尾以-1结束)。
如按下列次序顺序读入字符:
11334455587988-1
(3)用户可以根据菜单的提示选择相应的数字,进入相应的子菜单,在创建二叉排序树时注意以0为输入结束标志,在创建完成后可立即进行遍历,看创建的是否有误。
此外,本程序关键字既是节点的关键字也是节点的信息。
七、调试报告
(1)调试过程中最常见的便是代码输入错误,如字母大小写、顺序颠倒、符号的半/全角使用等一些问题,都是在调试过程中逐一改正的。
(2)本程序是在二叉树的基本操作的基础上进行深入修改,根据他人建议和意见统改而做,由于本人水平有限,难免在执行程序时会发生错误。
但只要根据本程序的说明操作就可以完成本程序特定的功能操作。
(3)我想以后还可以给此程序添加其它一些功能,例如创建平衡二叉排序树;对创建的二叉排序树进行删除,匹配等操作,如何解决程序顺利执行而不会陷入死循环一些问题等等。
(4)感想:
由于为了简化程序的复杂度,本程序只以整形的关键字作为节点的唯一信息,但本程序能够很好的实现二叉排序树的基本操作。
在调试程序过程中,对左右孩子的处理是难点,其中出现了许多的错误,但通过错误的改正也加深了对二叉排序树的认识。
Ps:
忘记了在程序出错时进行截图保存!
八、程序清单
#include
#include
#include
#include
#defineMAXLEN100
#defineNLAYER4
//******二叉排序树的数据结构**********
typedefstructBstnode
{
intkey;
structBstnode*lchild,*rchild;
}Bstnode,*Bstree;
BstreeTree=NULL;
BstreeCreate();//创建二叉排序树
BstreeInsert(Bstreetree,intkey);//插入
BstreeSearch(Bstreetree,intkey);//查找
voidTraverse(Bstreetree);//遍历
voidTranslevelPrint(Bstreebt);//树状打印
//************创建二叉排序树**********
BstreeCreate()
{
intkey,flag=0;//标志
Bstreetree=NULL;//初始化空树
scanf("%d",&key);
while(key!
=-1)//创建二叉排序树以-1为结束
{flag=1;
tree=Insert(tree,key);//逐个插入节点
scanf("%d",&key);
}
if(flag)
printf("【零式提醒】二叉排序树已创建成功!
\n");
printf("【零式提醒】看菜单请选择您需要的操作并按回车继续!
");
returntree;
}
//******树状打印输出二叉排序树********
voidTranslevelPrint(Bstreebt)
{//本算法实现二叉树的按层打印
structnode
{
Bstreevec[MAXLEN];//存放树结点
intlayer[MAXLEN];//结点所在的层
intlocate[MAXLEN];//打印结点的位置
intfront,rear;
}q;//定义队列q
inti,j=1,k=0,nLocate;
q.front=0;q.rear=0;//初始化队列q队头,队尾
printf("");
q.vec[q.rear]=bt;//将二叉树根结点如队列
q.layer[q.rear]=1;
q.locate[q.rear]=20;
q.rear=q.rear+1;
while(q.front{
bt=q.vec[q.front];
i=q.layer[q.front];
nLocate=q.locate[q.front];
if(j
{
printf("\n");printf("\n");
j=j+1;k=0;
while(k{
printf("");k++;
}
}
while(k<(nLocate-1))//利用结点深度控制横向位置
{
printf("");k++;
}
printf("%d",bt->key);
q.front=q.front+1;
if(bt->lchild!
=NULL)//存放在左子树,将左子树根结点如队列
{
q.vec[q.rear]=bt->lchild;
q.layer[q.rear]=i+1;
q.locate[q.rear]=(int)(nLocate-pow(2,NLAYER-i-1));
q.rear=q.rear+1;
}
if(bt->rchild!
=NULL)//存放右子树,将右子树根结点入队列
{
q.vec[q.rear]=bt->rchild;
q.layer[q.rear]=i+1;
q.locate[q.rear]=(int)(nLocate+pow(2,NLAYER-i-1));
q.rear=q.rear+1;
}
}
printf("\n【零式提醒】看菜单请选择您需要的操作并按回车继续!
\n");
}
//******************插入******************
BstreeInsert(Bstreetree,intkey)
{
Bstreep=tree;
Bstrees,f;
while(p!
=NULL)
{
f=p;
if(key==p->key)
returntree;
if(keykey)
p=p->lchild;
else
p=p->rchild;
}
s=(Bstree)malloc(sizeof(Bstnode));
s->key=key;
s->lchild=NULL;
s->rchild=NULL;
if(tree==NULL)
{
Tree=s;//赋给根节点
returns;
}//新节点为二叉排序树的根
if(keykey)
f->lchild=s;
else
f->rchild=s;
returntree;
}
//**************查找**************
BstreeSearch(Bstreetree,intkey)
{
Bstreep=tree;
intflag=0;
inti=1;
if(p==NULL)
{
printf("【零式提醒】请先创建二叉树,在进行查找操作!
");
returnp;
}
while(p!
=NULL)
{
if(p->key==key)
{
printf("【零式提醒】查询到该节点!
它的长度为%d\n",i);
printf("【零式提醒】看菜单请选择您需要的操作并按回车继续!
\n");
flag=1;
return(p);
break;
}
i++;
if(keykey)
p=p->lchild;
else
p=p->rchild;
}
if(flag==0)
{
printf("【零式提醒】查询不到关键字为%d的节点!
\n",key);
printf("【零式提醒】看菜单请选择您需要的操作并按回车继续!
\n");
returnNULL;
}
}
//***************遍历******************
inti=1;//标志避免递归时多次输出
voidTraverse(Bstreetree)
{
if(Tree==NULL&&i)
{
printf("【零式提醒】请先创建二叉树,在进行遍历操作!
");
return;
}
if(tree)
{
i=0;
Traverse(tree->lchild);
printf("%d\t",tree->key);
Traverse(tree->rchild);
}
}
//*************主函数*******************
voidmain()
{
system("color9E");
Bstreetree=NULL,p;
intkey1,key2,key3;
intselect,flag;
printf("______________________________________________________________\n");
printf("||\n");
printf("|-----------------欢迎使用二叉排序树基本操作程序---------------|\n");
printf("|---_____________________________________---|\n");
printf("|---︱----菜单选项----︱---|\n");
printf("|---︱1.创建二叉排序树2.打印操作