




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、实验四 平衡二叉树演示1. 问题定义及需求分析1.1课题目的和任务问题描述:利用平衡二叉树设计动态查找表。实验要求:设计平衡二叉树的动态演示的模拟程序。1)采用平衡二叉树存储结构。2)完成平衡二叉树的创建、查找、插入和删除的演示操作。3)可以考虑两棵平衡二叉树的合并。1.2数据形式输入数据形式:通过键盘输入数据输入值的范围:树中元素的值为float型,范围为1.2e-38至3.4e+38;树的名称为char类型数据,可以输入字母,数字和符号,但是长度必须在20位以内;对菜单进行操作时,输入数据长度必须在200以内,且有效的输入数据为0至7,其中0为退出程序,1至7为对应菜单的操作选项。输出数据
2、形式:输出到显示器。1.3程序功能创建平衡二叉树存储结构,通过平衡因子,使二叉排序树达到平衡,提供平衡二叉树的创建、查找和删除,树中元素的查找、插入和删除等基本功能,可以实现创建多棵平衡二叉树,并且能够进行两棵树的合并。通过平衡二叉树,能够使树时刻保持平衡,从而提高在树中遍历数据的速度,具有重要意义。1.4测试数据1 /创建平衡二叉树2 /输入创建树的个数t1 /输入第一个树的名称5 /输入第一个树中元素的个数5 2 6 8 9 /依次输入各个元素t2 /输入第二个树的名称5 /输入第二个树中元素的个数3 1 4 10 7 /依次输入各个元素5 /层次遍历输出第一个树的结构图t1 /操作树名5
3、 /层次遍历输出第二个树的结构图t2 /操作树名3 /插入元素操作t1 /操作树名1 /插入元素个数7 /依次插入元素5 /层次遍历输出树的结构图t1 /操作树名4 /删除元素操作t2 /操作树名1 /删除元素个数7 /依次删除元素5 /层次遍历输出树的结构图t2 /操作树名6 /合并两个树操作t1 t2 /操作树名5 /层次遍历输出树的结构图t1 /操作树名2 /查询元素操作t1 /操作树名5 /需要查询的元素(该元素树中存在)2 /查询元素操作t1 /操作树名11 /需要查询的元素(该元素树中不存在)7 /删除二叉平衡树操作t1 /操作树名2 /查询操作t1 /操作树名(会提示该树不存在,
4、说明删除树成功)0 /退出程序2. 概要设计2.1抽象数据类型需要定义一个树的结构类型,其中包含数据类型,它的左右孩子指针,以及平衡因子,平衡因子的取值为-1,0,1三种,分别对应树的右边高(RH),平衡(EH)和左边高(LH)三种情形,通过平衡因子的判别,来调整树的高度使其达到平衡;另外需要用到双向链表的数据结构,以及队列的数据结构。2.2主程序流程及各模块之间的调用关系3. 详细设计3.1存储结构实现typedef struct Type/数据类型结构 float num;Type;/*平衡树结构声明*/typedef struct AVLTree/二叉平衡树结构体声明 int bf;/结
5、点的平衡因子 struct Type data;/结点数据 struct AVLTree* lchild,* rchild;/左右孩子AVLTree,*AVL;/*队列结构声明*/typedef struct QNode/队列 AVL tree; struct QNode* next;QNode,*QP;typedef struct QP fron; QP rear;LinkQ;/*双向链表结构声明*/typedef struct LNode/链表 AVL t; char tree_nameNAME_LENGTH; struct LNode* prior,* next;LNode,*Link;
6、3.2负责模块的伪码算法(1)void LeftBalance(AVL& t)/左部平衡化处理 l=t-lchild; switch(l-bf) /检查T的左子树平衡度,并作相应的平衡处理 case LH:/新节点插入在T的左孩子的左子树上,做单右旋处理 调整平衡因子;R_Rotate(t);break; case EH:/deleteAVL需要,insertAVL用不着 调整平衡因子;R_Rotate(t);break; case RH:/新插入节点在T的左孩子的右子树上,做双旋处理 lr=l-rchild; switch(lr-bf) case LH: 调整平衡因子;break; case
7、 EH: 调整平衡因子;break; case RH: 调整平衡因子;break; 调整平衡因子; L_Rotate(t-lchild); R_Rotate(t); (2)void RightBalance(AVL& t)/右部平衡化处理 r=t-rchild; switch(r-bf) case RH:/新节点插在T的右孩子的右子树上,要做单左旋处理 调整平衡因子;L_Rotate(t);break; case EH:/deleteAVL需要,insertAVL用不着 调整平衡因子;L_Rotate(t);break; case LH:/新节点插在T的右孩子的左子树上,要做双旋处理 rl=r
8、-lchild; switch(rl-bf) case LH: 调整平衡因子;break; case EH: 调整平衡因子;break; case RH: 调整平衡因子;break; 调整平衡因子; R_Rotate(t-rchild); L_Rotate(t); (3)void R_Rotate(AVL& t)/以T为根节点的二叉排序树进行右旋转 l=t-lchild;/将t的左孩子给l t-lchild=l-rchild;/将l的右孩子给t的左孩子指针 l-rchild=t;/将t变成l的右孩子 t=l;/指向新的节点l(4)void L_Rotate(AVL& t)/以T为根节点的二叉排
9、序树进行左旋转 r=t-rchild; t-rchild=r-lchild; r-lchild=t; t=r;(5)int DeleteTree(AVL& t,Type e,int& shorter)/平衡二叉树的结点删除 if(t=NULL)/不存在该元素 return 0;/删除失败 else if(e=t-data)/找到元素结点 q=NULL; if(t-lchild=NULL)/左子树为空将右子树接上,删除该点; shorter=1; else if(t-rchild=NULL)/右子树为空将左子树接上,删除该点; shorter=1; else/左右子树都存在 q=t-lchild
10、; while(q-rchild)/找到要删除结点t的左孩子的最右孩子q q=q-rchild; t-data=q-data;/把q的值给t DeleteTree(t-lchild,q-data,shorter);/在左子树中递归删除前驱结点。即查找q的值 if(shorter)/如果树变矮了,调节平衡因子 switch(t-bf) case LH:t-bf=EH;shorter=1;break; case EH:t-bf=RH;shorter=0;break; case RH: if(t-rchild-bf=EH) shorter=0; else shorter=1; RightBalanc
11、e(t);/右平衡处理 break; else if(edata)/左子树中继续查找 if(!DeleteTree(t-lchild,e,shorter) return 0; if(shorter) switch(t-bf) case LH:t-bf=EH;shorter=1;break; case EH:t-bf=RH;shorter=0;break; case RH: if(t-rchild-bf=EH) shorter=0; else shorter=1; RightBalance(t);/右平衡处理 break; else/右子树中继续查找 if(!DeleteTree(t-rchil
12、d,e,shorter) return 0; if(shorter) switch(t-bf) case LH: if(t-lchild-bf=EH) shorter=0; else shorter=1; LeftBalance(t); /左平衡处理 break; case EH:t-bf=LH;shorter=0;break; case RH:t-bf=EH;shorter=1;break; return 1;(6) int MergeTree(AVL& t1,AVL& t2)/将树t2合并到t1上 while(t2!=NULL)/t2不为空时 InsertTree(t1,t2-data,t
13、aller);/将t2中元素插入t1 DeleteTree(t2,t2-data,shorter);/将插入后的t2中元素删除 return 1;(7) const int PrintTreeStructure(AVL t)/利用层次遍历,输出树的形状 if(!t)return 0;/树不存在,返回 InitQ(q);/建立空队列 while(1)/循环输出树中元素 i+;/第i个元素 num=0; j=1; while(jlchild);/将左右孩子入队列 EnQ(q,t-rchild); if(j=i+1) coutlchild=NULL&t-rchild=NULL)/T为空时进行判断,当
14、平衡树中出现层数不同的空结点时,终止输出 if(!level)/首次出现两个孩子都空的结点,将其孩子的层数赋给level level=num+1; else EnQ(q,NULL);/若该点为空,则它的孩子也为空,入队列 EnQ(q,NULL); if(level&level+2=num)/当遇到空结点,并且它的层数比标记层数大2时,结束输出 return 1; elsecout* ;/用*代表空 if(j=i+1) coutlchild; switch(l-bf) /检查T的左子树平衡度,并作相应的平衡处理 case LH:/新节点插入在T的左孩子的左子树上,做单右旋处理 t-bf=l-bf
15、=EH; R_Rotate(t); break;需要,insertAVL用不着 t-bf=LH; l-bf=RH; R_Rotate(t); break; case RH:/新插入节点在T的左孩子的右子树上,做双旋处理 lr=l-rchild; switch(lr-bf) case LH: t-bf=RH; l-bf=EH; break; case EH: t-bf=l-bf=EH; break; case RH: t-bf=EH; l-bf=LH; break; lr-bf=EH; L_Rotate(t-lchild); R_Rotate(t); void RightBalance(AVL&
16、 t)/右部平衡化处理 AVL r,rl; r=t-rchild; switch(r-bf) case RH:/新节点插在T的右孩子的右子树上,要做单左旋处理 t-bf=r-bf=EH; L_Rotate(t); break;需要,insertAVL用不着 t-bf=RH; r-bf=LH; L_Rotate(t); break; case LH:/新节点插在T的右孩子的左子树上,要做双旋处理 rl=r-lchild; switch(rl-bf) case LH: t-bf=EH; r-bf=RH; break; case EH: t-bf=r-bf=EH; break; case RH: t
17、-bf=LH; r-bf=EH; break; rl-bf=EH; R_Rotate(t-rchild); L_Rotate(t); void R_Rotate(AVL& t)/以T为根节点的二叉排序树进行右旋转 AVL l; l=t-lchild; t-lchild=l-rchild; l-rchild=t; t=l;/p指向新的根节点void L_Rotate(AVL& t)/以T为根节点的二叉排序树进行左旋转 AVL r; r=t-rchild; t-rchild=r-lchild; r-lchild=t; t=r;int DeleteTree(AVL& t,Type e,int& sh
18、orter)/平衡二叉树的结点删除 if(t=NULL)/不存在该元素 return 0;/删除失败 else if(e.num=t-data.num)/找到元素结点 AVL q=NULL; if(t-lchild=NULL)/左子树为空 q=t; t=t-rchild; delete q; shorter=1; else if(t-rchild=NULL)/右子树为空 q=t; t=t-lchild; delete q; shorter=1; else/左右子树都存在 q=t-lchild; while(q-rchild)/找到要删除结点t的左孩子的最右孩子q q=q-rchild; t-d
19、ata.num=q-data.num;/把q的值给t DeleteTree(t-lchild,q-data,shorter);/在左子树中递归删除前驱结点。即查找q的值 if(shorter) switch(t-bf) case LH: t-bf=EH; shorter=1; break; case EH: t-bf=RH; shorter=0; break; case RH: if(t-rchild-bf=EH) shorter=0; else shorter=1; RightBalance(t);/右平衡处理 break; else if(e.numdata.num)/左子树中继续查找 i
20、f(!DeleteTree(t-lchild,e,shorter) return 0; if(shorter) switch(t-bf) case LH: t-bf=EH; shorter=1; break; case EH: t-bf=RH; shorter=0; break; case RH: if(t-rchild-bf=EH) shorter=0; else shorter=1; RightBalance(t);/右平衡处理 break; else/右子树中继续查找 if(!DeleteTree(t-rchild,e,shorter) return 0; if(shorter) swi
21、tch(t-bf) case LH: if(t-lchild-bf=EH) shorter=0; else shorter=1; LeftBalance(t); /左平衡处理 break; case EH: t-bf=LH; shorter=0; break; case RH: t-bf=EH; shorter=1; break; return 1;int MergeTree(AVL& t1,AVL& t2)/将树t2合并到t1上 while(t2!=NULL) int taller,shorter; InsertTree(t1,t2-data,taller); DeleteTree(t2,t
22、2-data,shorter); return 1;#includeH.hconst int PrintTreeStructure(AVL t)/利用层次遍历,输出树的形状 if(!t)return 0; int i=0,level=0,j,num; LinkQ q; InitQ(q); while(1) i+; num=0; j=1; while(j=i) num+;/num为记层标志,记录当前T所在层数 j=2*j; if(t!=NULL) coutdata.num(bflchild); EnQ(q,t-rchild); if(j=i+1) coutlchild=NULL&t-rchild
23、=NULL)/T为空时进行判断,当平衡树中出现层数不同的空结点时,终止输出 if(!level)/首次出现两个孩子都空的结点,将其孩子的层数赋给level level=num+1; else EnQ(q,NULL);/若该点为空,则它的孩子也为空,入队列 EnQ(q,NULL); if(level&level+2=num) return 1; elsecout* ;/用*代表空 if(j=i+1) coutendl; DeQ(q,t); /while7.2程序全部代码/*H.h文件*/#ifndef H_H_INCLUDED#define H_H_INCLUDED#include#includ
24、e#include#includeusing namespace std;#define NAME_LENGTH 20#define LH 1 /树的左部比右部高1#define EH 0 /树的左右一般高#define RH -1 /树的右部比左部高1typedef struct Type/数据类型结构 float num;Type;/*平衡树结构声明*/typedef struct AVLTree/二叉平衡树结构体声明 int bf;/结点的平衡因子 struct Type data;/结点数据 struct AVLTree* lchild,* rchild;/左右孩子AVLTree,*A
25、VL;/*队列结构声明*/typedef struct QNode/队列 AVL tree; struct QNode* next;QNode,*QP;typedef struct QP fron; QP rear;LinkQ;/*双向链表结构声明*/typedef struct LNode/链表 AVL t; char tree_nameNAME_LENGTH; struct LNode* prior,* next;LNode,*Link;/*双向链表操作函数声明*/int InitL(Link& );int InsertL(Link& ,AVL& ,char* );int DeleteL(
26、Link& );const int SearchL(Link ,char* ,Link& );/*菜单*/void Menu();/*队列操作函数声明*/int InitQ(LinkQ& );int EnQ(LinkQ& ,AVL );int DeQ(LinkQ& ,AVL& );/*平衡树操作函数声明*/void R_Rotate(AVL& );void L_Rotate(AVL& );void LeftBalance(AVL& );void RightBalance(AVL& );int InsertTree(AVL& ,Type ,int& );int MergeTree(AVL& ,A
27、VL& );const int SearchTree(AVL ,Type ,AVL& );const int PrintTreeStructure(AVL );int DeleteTree(AVL& ,Type ,int& );int DestroyTree(AVL& );#endif / H_H_INCLUDED/*main.cpp文件*/#includeH.hint main() Menu(); return 1;/*MENU.cpp*/#includeH.hvoid Menu() char i10*NAME_LENGTH,a; int j; for(j=0;j10*NAME_LENGTH
28、;j+)ij=0; Link l; InitL(l);/创建包含一个空头结点的链表 while(1) system(cls); cout 平衡二叉树(AVL树)的演示endlendl; cout 1.创建二叉平衡树endl; cout 2.在树中查找元素endl; cout 3.在树中插入元素endl; cout 4.在树中删除元素endl; cout 5.输出二叉平衡树结构示意图endl; cout 6.合并两个二叉平衡树endl; cout 7.删除二叉平衡树endlendl; cout请输入操作序号(输入0退出程序):; cin.getline(i,10*NAME_LENGTH,n);
29、if(strlen(i)!=1)continue; else a=i0; if(a=0) break; switch(a) case 1: system(cls); coutk; for(j=0;jk;j+) cout请输入第j+1name; cout请输入元素个数:n; cout请依次输入元素:endl; Type e; AVL t=NULL; for(m=0;me.num; int taller=0;/增高标识,1为增高,0为不增高 InsertTree(t,e,taller);/生成树结点 InsertL(l,t,name);/将该平衡树命名,并接入链表 cout创建成功!endl; system(pause); system(cls); break; case 2: system(cls); cout请输入你想要访问的树名:name; Li
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年G2电站锅炉司炉理论考试题及答案
- 口才考试题及答案
- 钢筋考试题及答案
- 中华传统文化知到智慧树答案
- 药品知识竞赛考试题目及答案
- 中西医临床骨伤科学(运动健康与创伤防治)知到智慧树答案
- 中学生物学教学论知到智慧树答案
- 公需科目考试试题及答案
- 2025版清尾款支付与产品验收标准合同范本
- VR技能考核系统设计-洞察及研究
- 2025年财政管理知识竞赛题库及答案
- 满意度调查测评方案
- 区域产业协同发展面试题
- 当归种植培训课件
- 三年(2023-2025)中考语文真题分类汇编(全国)专题22 议论文阅读(解析版)
- 2025年浙江省教师招聘考试(语文)历年参考题库含答案详解(5卷)
- 医学类案例教学法
- 2025巡护员考试题库及答案
- 2025文化和旅游部直属事业单位招聘社会人员29人模拟试卷附答案详解
- 产前准备课件
- 2025年安徽滁州郊源阳光电力维修工程有限责任公司招聘14人(第二批次)笔试参考题库附带答案详解(10套)
评论
0/150
提交评论