第九组数据结构课程设计(二叉排序树实现)

上传人:gbs****77 文档编号:10201713 上传时间:2020-04-10 格式:DOC 页数:18 大小:208.50KB
返回 下载 相关 举报
第九组数据结构课程设计(二叉排序树实现)_第1页
第1页 / 共18页
第九组数据结构课程设计(二叉排序树实现)_第2页
第2页 / 共18页
第九组数据结构课程设计(二叉排序树实现)_第3页
第3页 / 共18页
点击查看更多>>
资源描述
黄淮学院“数据结构”课程设计报告系 (院): 信息工程学院 设计题目: 二叉排序树的实现 专业班级: 软件工程15级 小组成员: 唐二虎、赵梦娟、贾月 指导教师: 汪洋 完成时间: 2016.12.27 17二叉排序树的实现1.设计任务1) 实现二叉排序树,包括生成、插入,删除;2) 对二叉排序树进行先根、中根、和后根非递归遍历;3) 每次对树的修改操作和遍历操作的显示结果都需要在用树的形状表示出来。4) 分别用二叉排序树和数组去存储一个班(50人以上)的成员信息(至少包括学号、姓名、成绩3项),对比查找效率,并说明为什么二叉排序树效率高(或者低)。2.程序设计流程图(设计思想)无结点x存在含x的结点,则删除该结点,并作中序遍历找到该节点x输入元素x,查找二叉排序树T对二叉排序树T作中序遍历,并输出结果二叉链表作存储结构和顺序表作存储结构输入数列L, 以回车(n)为输入结束标志生成二叉排序树T;详细设计思想:建立二叉排序树采用边查找边插入的方式。查找函数采用递归的方式进行查找。如果查找到相等的则插入其左子树。然后利用插入函数将该元素插入原树。对二叉树进行中序遍历采用递归函数的方式。在根结点不为空的情况下,先访问左子树,再访问根结点,最后访问右子树。删除结点函数,采用边查找边删除的方式。如果没有查找到,进行提示;如果查找到结点则将其左子树最右边的节点的数据传给它,然后删除其左子树最右边的节点。3.函数模块:3.1.主函数main模块功能1.通过bstreeCreatTree()操作建立二叉排序树。2.在二叉排序树t中通过操作bstreeInsertBST(bstreet,intkey,nametypename,double grade)插入一个节点。3. 从二叉排序树t中通过操作void Delete(bstree&p)删除任意节点。4.在二叉排序树t中通过操作bstnode *SearchBST(bstreet,keytype key)查找节点。5.在二叉排序树t中通过操作p=SearchBST(t,key)查询,并修改节点信息6.非递归遍历二叉排序树。7.定义函数void compare()对数组和二叉排序树的查找效率进行比较比较。3.2创建二叉排序树CreatTree模块从键盘中输入关键字及记录,并同时调用插入函数并不断进行插入。最后,返回根节点T。3.3删除模块:二叉排序树上删除一个阶段相当于删去有序系列中的一个记录,只要在删除某个节点之后依旧保持二叉排序树的性质即可。假设二叉排序树上删除节点为*p(指向节点的指针为p),其双亲节点为*f(节点指针为f)。若*p节点为叶子节点,则即左右均为空树,由于删去叶子节点不破坏整棵树的结构,则只需修改其双亲节点的指针即可;若*p节点只有左子树或只有右子树,此时只要令左子树或右子树直接成为其双亲节点*f的左子树即可;若*p节点的左子树和右子树均不为空,其一可以令*p的左子树为*f的左子树,而*p的右子树为*s的右子树,其二可以令*p的直接前驱(或直接后继)替代*p,然后再从二叉排序树中删去它的直接前驱(或直接后继)。在二叉排序树中删除一个节点的算法为voidDeleteData(bstree&t,keytype key)若二叉排序树t中存在关键字等于key的数据元素,则删除该数据元素节点,并返回TRUE,否则返回FALSE。3.4插入模块二叉排序树是一种动态树表,其特点是树的结构通常不是一次生成的,而是在查找的过程中,当树中不存在关键字等于给定值得节点时在进行插入。新插入的节点一定是一个新添加的叶子节点,并且是查找不成功时查找路径上访问的最后一个节点的左孩子或右孩子的节点。一个无序系列可以通过构造一棵二叉排序树而变成一个有序系列,构造树的过程即为对无序系列进行排序的过程, 并且每次插入的节点都是二叉排序树上新的叶子节点,则在进行插入操作时,不必移动其他节点,仅需改变某个节点的指针由空变为非空即可。二叉排序树的插入算法为bstreeInsertBST(bstreet,intkey,nametypename,double grade)若二叉排序树中不存在关键字等于key的数据元素时,插入元素并返回TRUE。3.5查找模块二叉排序树又称二叉查找树,当二叉排序树不为空时,首先将给定的值和根节点的关键字比较,若相等则查找成功,否则将依据给定的值和根节点关键字之间的大小关系,分别在左子树或右子树上继续进行查找。为此定义一个二叉排序树的查找算法为bstnode *SearchBST(bstreet,keytype key) 在根指针t所指向的二叉排序树中查找关键字等于key的数据元素,如成功,返回指向该元素节点的指针,否则返回空指针。3.6二叉排序树的遍历先序遍历也叫做先根遍历。首先访问根结点然后遍历左子树,最后遍历右子树。在遍历左、右子树时,仍然先访问根结点,然后遍历左子树,最后遍历右子树,如果二叉树为空则返回。其实过程为:先遍历左子树root-left-left-left.-null,由于是先序遍历,因此一遇到节点,便需要立即访问;由于一直走到最左边后,需要逐步返回到父节点访问右节点,因此必须有一个措施能够对节点序列回溯。其一可以用栈记忆在访问途中将依次遇到的节点保存下来。根据栈的先进后出、后进先出的特点特点。则可以用栈保存。每次都将遇到的节点压入栈,当左子树遍历完毕后从栈中弹出最后一个访问的节点,然后访问其右子树。基本算法思想:1.先访问根节点,将根节点入栈2.重复执行两大步骤:如果该节点左孩子存在,则访问该左孩子节点,并将其指针入栈。重复以上操作,直到节点的左孩子不存在。将栈顶的元素,即其指针出栈,回到父节点,如果该指针节点的右孩子存在,则将该指针指向的右孩子节点重复执行以上步骤,直到桟为空为止。操作函数为void x_print(Tree T)中序遍历:中序遍历和先序遍历访问的顺序不同。中序遍历访问顺序为中序遍历左子数,在访问根节点,最后中序遍历右子树。先序遍历是先访问,再入栈;而中序遍历则是先入栈,弹栈后再访问。将二叉树的根节点入栈,如果该节点有左孩子,将左孩子直接入栈,重复该操作,直到该节点无左孩子;在将栈顶元素出栈,并访问该节点指向的节点,如果该指针指向的右孩子存在,则将当前指针指向右孩子节点。重复执行步骤直到栈为空为止。操作函数为void z_print(Tree T )。后序遍历:先后序遍历左子树,在后序遍历右子树,最后访问根节点。先将根节点入栈,如果该节点左孩子节点存在,将该节点左孩子节点入栈。重复执行此操作,直到节点左孩子节点为空。取栈顶元素,并赋值给P,如果P的右孩子为空或P的右孩子等于q(即如果p的右孩子已访问,则访问根节点,即p指向的节点,并用q来记录刚刚访问的节点的指针),若p有右孩子,且右孩子没有别访问过,则p=p-rchild。操作函数为void h_print(Tree T)4.源代码#include /* run this program using the console pauser or add your own getch, system(pause) or input loop */#include#include#include#include#include using namespace std;typedef stringnametype;typedef unsigned long keytype;typedefstruct node /结点的结构体keytype key; nametype name; int grade;struct node *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;return 1;int Push(Sqstack&s ,node *e) *s.top=e;s.top=s.top+1;return 1;int Pop(Sqstack&s, bstree&e) if(s.top=s.base)return 0;elses.top=s.top-1;e=*s.top;return 1;/非递归历遍并输出结点信息/*-先序非递归遍历-*/voidx_print(node *t)Sqstack s;InitStack(s);bstnode *p;p=t;while(p|!(s.top=s.base)if(p) Push(s,p);coutkeytsetw(20);coutnametsetw(20);coutgradetlchild;elsePop(s,p);p=p-rchild;/*-中序非递归遍历-*/voidz_print(node *t)Sqstack s;InitStack(s);bstnode *p;p=t;while(p|!(s.top=s.base)if(p) Push(s,p);p=p-lchild;elsePop(s,p);coutkeytsetw(20);coutnametsetw(20);coutgradetrchild;/*-非递归后序遍历-*/voidh_print(node *t)Sqstack s;InitStack(s);node *p,*q;p=t;q=NULL;while(p | !(s.top=s.base)if(p)Push(s,p); p=p-lchild;else p=*(s.top-1);if(p-rchild=q) Pop(s,q);p=NULL;coutkeytsetw(20);coutnametsetw(20);coutgradetrchild;q=NULL; /递归查找二叉树/ /*-归查找,若找到就返回指向该结点的指针,否则返回空-*/bstnode *SearchBST(bstreet,keytype key) if(t=NULL|key=t-key)return t;if(keykey)returnSearchBST(t-lchild ,key);elsereturnSearchBST(t-rchild ,key);/-给定学生信息插入到二叉树中-/bstreeInsertBST(bstreet,intkey,nametypename,double grade)bstreep,q;if(t=NULL) t=new bstnode();t-key=key;t-name=name;t-grade=grade;t-lchild=t-rchild=NULL;elsep=t;while(p) q=p;if(p-keykey)p=q-lchild;else if(p-keyrchild;elsecoutendl;cout树中已有该节点:keyendl;coutkey=key;p-name=name;p-grade=grade;p-lchild=p-rchild=NULL;if(q-keykey)q-lchild=p;elseq-rchild=p;return t;/-二叉树排序树的构建-/bstreeCreatTree() bstree t=NULL;keytype key;nametype name;double grade;printf(n*本系统由二胡科技所有成员公同组建!*nnn);printf(请输入-学号-姓名-成绩-(输入0时结束):n);cinkey;if(key=0)return t;cinname;cingrade;while(key) t=InsertBST(t,key,name,grade);printf(请输入-学号-姓名-成绩-(输入0时结束):n);cinkey;if(key=0)break;cinname;cingrade;return t;/-删除树中的结点-/void Delete(bstree&p) bstreeq,s;if(!p-rchild)q=p;p=q-lchild ;delete q;else if(!p-lchild)q=p;p=p-rchild;delete q;elseq=p;s=p-lchild;while(s-rchild)q=s;s=s-rchild;p-name=s-name;if(q!=p)q-rchild=s-lchild;elseq-lchild=s-lchild;delete s;voidDeleteData(bstree&t,keytype key)if(!t)printf(没有该信息,请重新输入!n);cinkey;DeleteData(t,key);elseif(t-key=key)Delete(t); printf(删除成功!n);else if(t-keykey)DeleteData(t-lchild,key); elseDeleteData(t-rchild,key); /二叉树的深度intTreeDepth(bstree t)intleft,right,max;if(t!=NULL)left=TreeDepth(t-lchild);right=TreeDepth(t-rchild);max=leftright?left:right;return max+1;elsereturn 0;/树状输出二叉树voidPrintTree(bstreet,int layer)int k;if(t=NULL)return ;PrintTree(t-rchild,layer+1);for(k=0;klayer;k+)cout ;coutkeylchild,layer+1);/-主函数测试-/int main()int d;/system(cls);system(Color 2f);keytype key;bstree t=NULL; t=CreatTree();d=TreeDepth(t);printf(二叉排序树的树形表示如下n);PrintTree(t,d);char choose;nametype name;bstree p;double grade;printf( n);printf(-请输入你要选择的操作-n);printf( |-|n);printf( |-|n);printf( | a 插入信息 |n);printf( | b 删除信息 |n);printf( | c 查询信息 |n);printf( | d 修改信息 |n);printf( | 0 退出 |n);printf( | e 对二叉排序树进行非递归遍历 |n);printf( |-|n);printf( |-|n);printf(n);printf(需要选择的操作为:);cinchoose;coutkey;if(key=0) PrintTree(t,d);printf(n*插入信息结束!);break;cinname;cingrade;while(key) t=InsertBST(t,key,name,grade);printf(请输入-学号-姓名-成绩-(输入0时结束):n);cinkey;if(key=0)printf(插入信息结束!);break;cinname;cingrade;break;case b:printf(请输入要删除信息学生的学号:n);cinkey;DeleteData(t,key); d=TreeDepth(t);printf(删除结点后二叉树的树形显示如下n);PrintTree(t,d);break;case c:cout请输入要查询学生的学号:key;p=SearchBST(t,key);if(p=NULL)cout无查询的关键字:keyendl;elsecout成绩tsetw(20)姓名tsetw(20)学号endl;coutkeytsetw(20);coutnametsetw(20);coutgradekey;p=SearchBST(t,key);if(p=NULL)cout无你所要修改的关键字:keyname;printf(n请输入修改的成绩:);cingrade;p-name=name;p-grade=grade;printf(n修改成功!n);break;case e:if(!t)printf(没有任何信息,请先输入信息!);elsecout学号tsetw(20)姓名tsetw(20)成绩choose;coutendl;return 0;5.运行结果及截图从键盘读入数据以0作为结束标志可得二叉排序树树状表示主菜单选择模块需要在树种添加节点则执行操作a需要在书中删除节点执行操作b需要查询节点信息执行操作c修改某一节点信息执行操作d执行操作e对树进行先序遍历、后序遍历、中序遍历运行结果如下图执行操作0退出程序执行
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 办公文档 > 解决方案


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!