1、数据结构程序报告平衡二叉树的操作计算机科学学院数据结构课程设计报告平衡二叉树操作学生姓名:学 号:班 级:指导老师:报告日期:1. 需求分析1建立平衡二叉树并进行创建、查找、插入、删除等功能。2设计一个实现平衡二叉树的程序,可进行创建、查找、插入、删除等操作,实现动态的输入数据,实时的输出该树结构。3测试数据:自选数据2.概要设计1.抽象数据类型定义:typedef struct BSTNode int data; int bf; /节点的平衡因子 struct BSTNode *lchild,*rchild; /左右孩子指针BSTNode,*BSTree;void CreatBST(BSTr
2、ee &T); /创建平衡二叉树void R_Rotate(BSTree &p); /对以*p为根的二叉排序树作左旋处理void L_Rotate(BSTree &p); /对以*p为根的二叉排序树作左旋处理void LeftBalance(BSTree &T); /对以指针所指结点为根的二叉树作左平衡旋转处理void RightBalance(BSTree &T); /对以指针所指结点为根的二叉树作右平衡旋转处理bool InsertAVL(BSTree &T,int e,bool &taller); /插入结点ebool SearchBST(BSTree &T,int key); /查找元
3、素key是否在树T中void LeftBalance_div(BSTree &p,int &shorter); /删除结点时左平衡旋转处理void RightBalance_div(BSTree &p,int &shorter); /删除结点时右平衡旋转处理void Delete(BSTree q,BSTree &r,int &shorter); /删除结点int DeleteAVL(BSTree &p,int x,int &shorter); /平衡二叉树的删除操作void PrintBST(BSTree T,int m); /按树状打印输出二叉树的元素2. 主程序的流程请输入操作的选项编号
4、(1-5)1-创建平衡二叉树2-查找3-插入4-删除5-结束3.各模块之间的层次调用插入退出输出删除主模块查找显示主菜单输入数据元素平衡化 3. 详细设计1.以平衡二叉树的插入和平衡化为例:bool InsertAVL(BSTree &T,int e,bool &taller)/若存在平衡的二叉排序树T中不存在和e有相同关键字的节点,则插入一个数据元素为e/的新结点,并返回1,否者返回0。若因插入而使二叉排序树失去平衡,则作平衡旋转理,/布尔变量taller反映T长高与否。 if(!T)/插入新结点,树“长高”,置taller为true T = (BSTree)malloc(sizeof(BS
5、TNode); T-data = e; T-lchild = T-rchild =NULL; T-bf = EH; taller = true; else if(EQ(e,T-data) /树中已存在和有相同关键字的结点 taller = false;printf(已存在相同关键字的结点n); return 0; /则不再插入 if(LT(e,T-data) /应继续在*T的左子树中进行搜索 if(!InsertAVL(T-lchild,e,taller) return 0;/未插入 if(taller) /已插入到*T的左子树中且左子树“长高” switch(T-bf) /检查*T的平衡度
6、case LH: /原本左子树比右子树高,需要作左平衡处理 LeftBalance(T); taller = false; break; case EH: /原本左子树、右子等高,现因左子树增高而使树增高 T-bf = LH; taller = true; break; case RH: /原本右子树比左子树高,现左、右子树等高 T-bf = EH; taller = false; break; /switch(T-bf) /if else /应继续在*T的右子树中进行搜索 if(!InsertAVL(T-rchild,e,taller) return 0;/未插入 if(taller) /已
7、插入到*T的右子树中且右子树“长高” switch(T-bf) /检查*T的平衡度 case LH: /原本左子树比右子树高,现左、右子树等高 T-bf = EH; taller = false; break; case EH: /原本左子树、右子等高,现因右子树增高而使树增高 T-bf = RH; taller = true; break; case RH: /原本右子树比左子树高,需要作右平衡处理 RightBalance(T); taller = false; break; /switch(T-bf) /else /else return 1;/InsertAVL2.说明:执行完输入函数
8、后,会在键盘缓冲区中保存回车键,后面再对字符型量赋值时,会将缓冲区当成数据存入变量中,所以要在某些输入语句后面加getchar函数。 4.调试分析1. 遇到的问题:(1)对平衡二叉树的删除的算法设计程序存在很大问题。删除节点后需要对新的排序树平衡化,改变节点的信息,使之形成一棵新的平衡二叉树。(2)主函数中的实参和子函数中的实参相等,造成调用该子函数时,虽然没有错误,但其功能不能正确的实现。改变该变量后程序成功实现各种功能。(3)一些逻辑逻辑运算符书写不正确,造成实现的功能不正确或程序死循环。2.收获:(1)对平衡二叉树的构造、插入和删除的算法思想有了更清楚的认识,能够对平衡二叉树进行创建、调
9、平、插入、删除等操作,实现动态的输入数据,实时的输出该树结构.(2)对多个程序的调用5.用户使用说明1.了解程序清单上给出的功能,并根据提示依次进行操作。2.创建二叉树,输入的数据元素为整数,当输入-123时,停止创建。并显示平衡二叉树的中序凹入树形图。3.查找(输入你要查找的元素)。4.插入(输入要插入的数据元素,并输出)5.删除(删除指定的元素,并输出)6.结束说明:其中每一个功能实现后都会提示是否继续:选择y继续,否则,终止。6.测试结果1.创建平衡二叉树:(中序凹入输出)2.查找查找成功或失败时:3.插入4.删除,结束7.附录源代码:#include#include#define LH
10、 +1#define EH 0#define RH -1#define NULL 0typedef struct BSTNode int data; int bf; struct BSTNode *lchild,*rchild;BSTNode,*BSTree;void CreatBST(BSTree &T);void R_Rotate (BSTree &p);void L_Rotate(BSTree &p);void LeftBalance(BSTree &T);void RightBalance(BSTree &T);bool InsertAVL(BSTree &T,int e,bool &
11、taller);bool SearchBST(BSTree &T,int key);void LeftBalance_div(BSTree &p,int &shorter);void RightBalance_div(BSTree &p,int &shorter);void Delete(BSTree q,BSTree &r,int &shorter);int DeleteAVL(BSTree &p,int x,int &shorter);void PrintBST(BSTree T,int depth);void main() BSTree T; int sear,cmd,depth; ch
12、ar ch; int shorter=0; bool taller=false; T=(BSTree)malloc(sizeof(BSTNode); T=NULL; printf(*平衡二叉树的操作菜单*n); printf( 1-创建n); printf( 2-查找n); printf( 3-插入n); printf( 4-删除n); printf( 5-退出n); printf(*n); do printf(n请选择操作的编号:); scanf(%d,&cmd); getchar(); switch(cmd) case 1: CreatBST(T);break; case 2: print
13、f(请输入您要查找的关键字:); scanf(%d,&sear);getchar(); if(SearchBST(T,sear) printf(关键字%d存在,查找成功!n,sear); else printf(查找失败!n); break; case 3: printf(请输入您要插入的关键字:); scanf(%d,&sear);getchar; InsertAVL(T,sear,taller);depth=0; PrintBST(T,depth); break; case 4: depth=0; printf(请输入你要删除的关键字: ); scanf(%d,&sear); getcha
14、r(); DeleteAVL(T,sear,shorter); PrintBST(T,depth); break; case 5: printf(结束!n); break; default: printf(输入错误!n); if(cmd=5) break; printf(n继续吗? y/n: ); scanf(%s,&ch); getchar(); printf(n); while(ch=y); printf(n);void CreatBST(BSTree &T) int depth; int e; bool taller=false; T = NULL; printf(n请输入关键字(以-1
15、23结束建立平衡二叉树):); scanf(%d,&e); getchar(); while(e != -123) InsertAVL(T,e,taller); printf(n请输入关键字(以-123结束建立平衡二叉树):); scanf(%d,&e); getchar(); taller=false; depth=0; printf(n*n); printf( 您创建的二叉树为n); if(T) PrintBST(T,depth); else printf(这是一棵空树!n);void R_Rotate (BSTree &p) /对以*p为根的二叉排序树作右旋处理 BSTree lc; l
16、c=p-lchild; p-lchild=lc-rchild; lc-rchild=p; p=lc;void L_Rotate(BSTree &p) /对以*p为根的二叉排序树作左旋处理 BSTree rc; rc=p-rchild; p-rchild=rc-lchild; rc-lchild=p; p=rc;void LeftBalance(BSTree &T) /对以指针所指结点为根的二叉树作左平衡旋转处理 BSTree lc,rd; lc=T-lchild; switch(lc-bf) case LH: T-bf=lc-bf=EH; R_Rotate(T); break; case RH
17、: rd=lc-rchild; switch(rd-bf) case LH: T-bf=RH;lc-bf=EH;break; case EH: T-bf=lc-bf=EH;break; case RH:T-bf=EH;lc-bf=LH;break; rd-bf=EH; L_Rotate(T-lchild); R_Rotate(T); void RightBalance(BSTree &T) /对以指针所指结点为根的二叉树作右平衡旋转处理 BSTree rc,ld; rc=T-rchild; switch(rc-bf) case RH: T-bf=rc-bf=EH; L_Rotate(T); b
18、reak; case LH: ld=rc-lchild; switch(ld-bf) case RH:T-bf=LH;rc-bf=EH;break; case EH:T-bf=rc-bf=EH;break; case LH:T-bf=EH;rc-bf=RH;break; ld-bf=EH; R_Rotate(T-rchild); L_Rotate(T); bool InsertAVL(BSTree &T,int e,bool &taller) /插入结点e if(!T) T=(BSTree)malloc(sizeof(BSTNode); T-data=e; T-lchild=T-rchild=
19、NULL; T-bf=EH; taller=true; else if(e=T-data) taller=false; printf(已存在相同关键字的结点!n); return 0; if(edata) if(!InsertAVL(T-lchild,e,taller) return 0; if(taller) switch(T-bf) case LH: LeftBalance(T);taller=false;break; case EH: T-bf=LH;taller=true;break; case RH: T-bf=EH;taller=false;break; else if(!Inse
20、rtAVL(T-rchild,e,taller) return 0; if(taller) switch(T-bf) case LH: T-bf=EH;taller=false;break; case EH: T-bf=RH;taller=true;break; case RH: RightBalance(T);taller=false;break; bool SearchBST(BSTree &T,int key) /查找元素key是否在树中 if(!T) return false; else if(key=T-data) return true; else if(keydata) retu
21、rn SearchBST(T-lchild,key); else return SearchBST(T-rchild,key);void LeftBalance_div(BSTree &p,int &shorter) /删除结点时左平衡旋转处理 BSTree p1,p2; if(p-bf=1) p-bf=0; shorter=1; else if(p-bf=0) p-bf=-1; shorter=0; else p1=p-rchild; if(p1-bf=0) L_Rotate(p); p1-bf=1; p-bf=-1; shorter=0; else if(p1-bf=-1) L_Rotat
22、e(p); p1-bf=p-bf=0; shorter=1; else p2=p1-lchild; p1-lchild=p2-rchild; p2-rchild=p1; p-rchild=p2-lchild; p2-lchild=p; if(p2-bf=0) p-bf=0; p1-bf=0; else if(p2-bf=-1) p-bf=1;p1-bf=0; else p-bf=0;p1-bf=-1; p2-bf=0; p=p2; shorter=1; void RightBalance_div(BSTree &p,int &shorter) /删除结点时右平衡旋转处理 BSTree p1,p
23、2; if(p-bf=-1) p-bf=0; shorter=1; else if(p-bf=0) p-bf=1; shorter=0; else p1=p-lchild; if(p1-bf=0) R_Rotate(p); p1-bf=-1; p-bf=1; shorter=0; else if(p1-bf=1) R_Rotate(p); p1-bf=p-bf=0; shorter=1; else p2=p1-rchild; p1-rchild=p2-lchild; p2-lchild=p1; p-lchild=p2-rchild; p2-rchild=p; if(p2-bf=0) p-bf=
24、0; p1-bf=0; else if(p2-bf=1) p-bf=-1; p1-bf=0; else p-bf=0; p1-bf=1; p2-bf=0; p=p2; shorter=1; void Delete(BSTree q,BSTree &r,int &shorter) /删除结点 if(r-rchild=NULL) q-data=r-data; q=r; r=r-lchild; free(q); shorter=1; else Delete(q,r-rchild,shorter); if(shorter=1) RightBalance_div(r,shorter); int Dele
25、teAVL(BSTree &p,int x,int &shorter) /平衡二叉树的删除操作 int k; BSTree q; if(p=NULL) printf(不存在要删除的关键字!n); return 0; else if(xdata) k=DeleteAVL(p-lchild,x,shorter); if(shorter=1) LeftBalance_div(p,shorter); return k; else if(xp-data) k=DeleteAVL(p-rchild,x,shorter); if(shorter=1) RightBalance_div(p,shorter);
26、 return k; else q=p; if(p-rchild=NULL) p=p-lchild; free(q); shorter=1; else if(p-lchild=NULL) p=p-rchild; free(q); shorter=1; else Delete(q,q-lchild,shorter); if(shorter=1) LeftBalance_div(p,shorter); p=q; return 1; void PrintBST(BSTree T,int depth) int i; if(T-rchild) PrintBST(T-rchild,depth+1); for(i=1;idata); if(T-lchild) PrintBST(T-lchild,depth+1);
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1