ImageVerifierCode 换一换
格式:DOCX , 页数:24 ,大小:95.03KB ,
资源ID:7215227      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/7215227.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(数据结构大作业平衡二叉树.docx)为本站会员(b****6)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

数据结构大作业平衡二叉树.docx

1、数据结构大作业平衡二叉树数学与计算机学院计算机系数据结构程序设计报告平衡二叉树学生姓名:* * 学 好:1004681028 班 级:计算机系102指导老师:* * *报告日期:2011/6/261.平衡二叉树31.1平衡二叉树的定义.31.2平衡二叉树的构造.31.3平衡二叉树查找的分析.32.程序功能33.程序结构类型34.程序函数45.算法思想55.1 判断二叉树的旋转方法.55.2 平衡旋转处理.55.3 在平衡二叉树中插入元素.55.4 在平衡二叉树中删除元素.55.5 输出平衡二叉树树形.55.6 销毁平衡二叉树.56.程序设计总结.97.结束语108.附录:程序清单101.平衡二

2、叉树1.1平衡二叉树的定义 平衡二叉树(Balanced Binary Tree或Height-Balanced Tree)又称AVL树。它或者是一颗空树,或者是具有下列性质的二叉树:它的左子树和右子树都是平衡二叉树,且左子树和右子树的深度之差的绝对值不超过1。若将二叉树上结点的平衡因子BF(Balanced Factor)定义为该结点的左子树的深度减去它的右子树的深度,则平衡二叉树上所有结点的平衡因子之可能是-1、0和1。只要二叉树上有一个结点的平衡因子的绝对值大于1,则该二叉树就是不平衡的。1.2平衡二叉树的构造 构造一颗平衡二叉树的过程就是将一颗空树从根结点起,逐步插入或删除结点并不断对

3、此树进行平衡化。在构造平衡二叉树的过程中有插入和删除两大操作。在树中进行插入和删除操作都可使树失去平衡,然而要让二叉排序树由不平衡转化为平衡,操作就是对二叉树进行旋转,旋转的过程将在算法思想中详细介绍。1.3平衡二叉树查找的分析 在平衡二叉树上进行查找的过程和二叉排序树相同,因此,在查找过程中和给定值进行比较的关键字个数不超过树的深度。因此,在平衡二叉树上进行查找的时间复杂度为O(log n).2.程序功能本程序的功能就是将二叉排序树转变为平衡二叉树,其操作有:创建二叉树、插入数据、删除数据、输出、销毁二叉树和退出。1创 建 二 叉 树2插 入 数 据 3删 除 数 据 4输 出5销 毁 二

4、叉 树0退 出请选择:3.程序结构类型在本程序中主要用到两个结构类型:结构体和队列。二叉树是链式存储结构,故用结构体来定义其结构。队列是用作输出二叉树的树形(层序输出)。4.程序函数4.1 main()函数:(1)函数原形:void main()(2)功能:显示总菜单,调用子函数4.2 Create()函数: (1)函数原形:void Create(BSTree &T) (2)功能:实现二叉树的创建4.3 Insert()函数: (1)函数原形:void Insert(BSTree &T) (2)功能:实现在二叉树中插入数据4.4 InsertAVL()函数: (1)函数原形:int Inse

5、rtAVL(BSTree &T,int e,int &taller) (2)功能:插入结点,并将二叉树平衡化4.5 DeleteMenu()函数: (1)函数原形:void DeleteMenu(BSTree &T) (2)功能:实现在二叉树中删除数据4.6 DeleteAVL()函数: (1)函数原形:int DeleteAVL(BSTree &T,int e,int &shorter) (2)功能:删除结点,并将二叉树平衡化4.7Delete()函数: (1)函数原形:int Delete(BSTree &p) (2)功能:实现删除结点4.8 Search()函数: (1)函数原形:voi

6、d Search(BSTree &T,int e,int key) (2)功能:在树中查找和关键字相等的结点4.9 R_Rotate()函数: (1)函数原形:void R_Rotate(BSTree &p) (2)功能:对以*p为根结点的子树进行右旋平衡处理4.10 L_Rotate()函数: (1)函数原形:void L_Rotate(BSTree &p) (2)功能:对以*p为根结点的子树进行左旋平衡处理4.11 RightBalance()函数: (1)函数原形:int RightBalance(BSTree &T) (2)功能:对以指针T所指结点为根的二叉树作右平衡旋转处理4.12

7、LeftBalance()函数: (1)函数原形:int LeftBalance(BSTree &T) (2)功能:对以指针T所指结点为根的二叉树作左平衡旋转处理4.13 Output()函数: (1)函数原形:void Output(BSTree T) (2)功能:将二叉树按中序和层序输出4.14 Inordertraverse()函数: (1)函数原形:void Inordertraverse(BSTree T) (2)功能:将二叉树按中序输出4.15 Depth()函数:(1)函数原形:void Depth(BSTree p,int n,int &num)(2)功能:求二叉树的深度4.1

8、6 Levelordertraverse()函数: (1)函数原形:int Levelordertraverse(Stack &Q) (2)功能:将二叉树按层序输出4.17 Initstack()函数: (1)函数原形:int Initstack(Stack &Q) (2)功能:构造一个空队列4.18 Push()函数: (1)函数原形:int Push(Stack &Q,BSTree e) (2)功能:插入元素e为新的队尾元素4.19 Pop()函数: (1)函数原形:int Pop(Stack &Q,BSTree &q) (2)功能:删除对头元素4.20 Destroy()函数: (1)函

9、数原形:void Destroy(BSTree &T) (2)功能:将队列销毁5.算法思想5.1 判断二叉树的旋转方法 在一颗平衡二叉树中插入或删除一个结点后,若二叉树失去平衡,则需将二叉树进行平衡化处理,简而言之,就是对不平衡的二叉树进行旋转处理。假设在二叉排序树中插入或删除结点而失去平衡的最小子树根结点的指针为T(即T是离插入或删除结点最近,且平衡因子绝对值超过1的祖先结点),指针p指向结点T的左子树的根结点,指针q指向结点T的右子树的根结点,则判断方法如下: (1)若结点T的平衡因子为2,结点p的平衡因子为1,则需对结点T进行单向右旋平衡处理; (2)若结点T的平衡因子为-2,结点p的平

10、衡因子为-1,则需对结点T进行单向左旋平衡处理; (3)若结点T的平衡因子为2,结点p的平衡因子为-1,则需先对结点p进行单向左旋平衡处理,再对结点T进行单向右旋平衡处理,将这两步简称为对结点T进行双向旋转(先左后右) 平衡处理; (4) 若结点T的平衡因子为-2,结点p的平衡因子为1,则需先对结点p进行单向右旋平衡处理,再对结点T进行单向左旋平衡处理,将这两步简称为对结点T进行双向旋转(先右后左) 平衡处理;5.2 平衡旋转处理假设由于在二叉排序树上插入或删除结点而失去平衡的最小子树根结点的指针为T(即T为里插入结点最近,且平衡因子绝对值超过1的祖先结点),则失去平衡后进行平衡处理有如下4种

11、情况:(1)单向右旋平衡处理:若指针p指向以*T为根的左子树的根结点,将*p的右子树作为*T的左子树,再将以*T为根的树作为*p的右子树,如图(a)所示。(2)单向左旋平衡处理:若指针p指向以*T为根的右子树的根结点,将*p的左子树作为*T的右子树,再将以*T为根的树作为*p的左子树,如图(b)所示。(3)双向旋转(先左后右)平衡处理:若p指向以*T为根的左子树的根结点,q以*p为根的右子树的根结点,则先将以*p为根结点的树进行单向左旋,再将以*q为根结点的树进行单向右旋,如图(c)所示。(4) 双向旋转(先右后左)平衡处理:若p指向以*T为根的右子树的根结点,q以*p为根的左子树的根结点,则

12、先将以*p为根结点的树进行单向右旋,再将以*q为根结点的树进行单向左旋,如图(d)所示。5.3 在平衡二叉树BBST中插入元素 在平衡的二叉排序树上插入一个新的数据元素e: (1)若BBST为空树,则插入一个数据元素e的新结点作为BBST的根结点,树的深度增1; (2)若e的关键字和BBST的根结点的关键字相等,则不进行插入; (3)若e的关键字小于BBST的根结点的关键字,而且在BBST的左子树中不存在和e有相同关键字的结点,则将e插入在BBST的左子树上,并且当插入之后的左子树深度增加(+1)时,分别就下列不同情况处理:BBST的根结点的平衡因子为-1(右子树的深度大于左子树的深度):则将

13、根结点的平衡因子更改为0,BBST的深度不变;BBST的根结点的平衡因子为0,(左、右子树的深度相等):则将根结点的平衡因子更改为1,BBST的深度增1;BBST的根结点的平衡因子为1(左子树的深度大于右子树的深度):若BBST的左子树的平衡因子为1,则需进行单向右旋平衡处理,并且在右旋处理之后,将根结点和其右子树根结点的平衡因子更改为0,树的深度不变;若BBST的左子树根结点的平衡因子为-1,则需进行先向左、后先向右的双向旋转平衡处理,并且在旋转处理之后,修改根结点和其左、右子树根结点的平衡因子,树的深度不变;(4)若e的关键字大于BBST的根结点的关键字,而且BBST的右子树不存在和e有相

14、同关键字的结点,则将e插入在BBST的右子树上,并且当插入之后的右子树深度增加(+1)时,分别就不同情况处理:BBST的根结点的平衡因子为1(左子树的深度大于右子树的深度):则将根结点的平衡因子更改为0,BBST的深度不变;BBST的根结点的平衡因子为0,(左、右子树的深度相等):则将根结点的平衡因子更改为-1,BBST的深度增1;BBST的根结点的平衡因子为-1(右子树的深度大于左子树的深度):若BBST的左子树的平衡因子为-1,则需进行单向左旋平衡处理,并且在左旋处理之后,将根结点和其左子树根结点的平衡因子更改为0,树的深度不变;若BBST的左子树根结点的平衡因子为1,则需进行先向右、后先

15、向左的双向旋转平衡处理,并且在旋转处理之后,修改根结点和其左、右子树根结点的平衡因子,树的深度不变;5.4平衡二叉树中删除元素 假设在平衡二叉树上删除结点为*p(指向结点的指针为p),其双亲结点为*f(结点指针为f),且不失一般性,可设*p是*f的左孩子: (1)若*p结点为叶子结点,则直接将*p结点删除,如图(e)所示。 (2)若*p结点只有左子树或者只有右子树,此时只要令*p的左子树或右子树成为其双亲结点*f的左子树,如图(f)所示;(2)若*p结点的左子树和右子树均不空,则令*p的直接前驱代替*p,然后再从二叉排序树中删去它的直接前驱,如图(g)所示; 在上述三种删除*p结点的处理后,若

16、二叉树仍然平衡,则只需修改*f结点的平衡因子;否则,则需从*p结点回溯到根结点,找到回溯途中遇到的不平衡结点,并将其平衡化;将删除结点后不平衡树平衡化的具体处理方法如下:设p为回溯至根结点的路径上的某一结点结点p的平衡因子为0,若删除结点为p结点左子树上的结点,则将结点p的平衡因子改为-1,并相应将树平衡化;若删除结点为p结点右子树上的结点,则将结点p的平衡因子改为1,并相应将树平衡化。无论删除结点为p结点左子树或右子树上的结点,都不需要再向根结点回溯,平衡处理结束;结点p的平衡因子为1,若删除结点为p结点左子树上的结点,则将结点p的平衡因子该为0,再从结点p向根结点回溯;若删除结点为p结点右

17、子树上的结点,设q指向p的左子树的根结点,则需将结点p进行单向右旋处理,并相应修改各结点的平衡因子,再从结点p向根结点回溯;结点p的平衡因子为-1,若删除结点为p结点左子树上的结点,设q指向p的右子树的根结点,则需将结点p进行单向左旋处理,并相应修改各结点的平衡因子,再从结点p向根结点回溯;若删除结点为p结点右子树上的结点,则将结点p的平衡因子该为0,再从结点p向根结点回溯;特别需要注意的是,在平衡二叉树中删除一个结点后使不平衡根结点的平衡因子变为2或-2,根结点的左或右孩子的平衡因子为0,此时需将根结点进行单向右或左旋处理,然而旋转处理后的树的深度不变,如图(h)所示。5.5输出平衡二叉树树

18、形 将一颗平衡二叉树按树形输出,要用到队列,并且将此平衡二叉树当做满二叉树,孩子结点为空的用空字符代替。首先,应先求出二叉树的深度n,根据完全二叉树的性质知,第n层上的结点数至多为2n-1。此时,便可知道每层上应输出的空格数,并可以控制每层上结点之间的间距。此外,还要控制换行,记录输出的结点数num,若num等于i层的总结点数2i-1则换行。若树不为空,则将根结点插入到队列中,接着将根结点从队列中删除并输出,再把根结点的左、右孩子插入到队列中,若孩子结点为空则用空字符代替,重复上述操作,直到当num等于n层总结点数2n-1,则结束输出。5.6销毁平衡二叉树 销毁平衡二叉树就是将二叉树中的每一个

19、结点用free()函数释放,其具体过程采用递归:将平衡二叉树的根结点的指针T传到销毁函数,如果*T结点的左孩子不为空,则将*T结点的左子树的根结点进行递归,直到结点的左孩子为空;再判断结点的右孩子是否为空,若不为空则将结点的右子树的根结点进行递归,直到结点的右子树为空;最后将结点的指针赋为空指针。6. 程序设计总结 将一颗二叉排序树转变为平衡二叉树并将平衡树按树形输出的算法,主要操作就是插入、删除和输出。本人在编写插入算法,经过陈老师的讲解和课后的思考,根据书本上的算法编写完成。然而,在二叉树中删除结点,本人是在网上以及图书馆书籍上查找的。很令人失望的是,网上和书籍里对于在二叉树中删除结点再将

20、其平衡化的算法思想介绍很少,甚至有些书籍上根本就没提及过。看着做的一点笔记,本人还是很是不知所措,不懂其算法思想,经过三天的思索,终于有些头绪,尝试着编写,尽管失败了很多次,但总算勉强写出了算法。(我所编写的算法可能和书籍中讲解的不同,只是换了一种实现方法。)至于将二叉树按树形输出,是在陈老师的指导下写出的,陈老师告诉我算法思想,之后就在思想的指导下完成了算法。能完成这个程序,我还是感到挺高兴的,在今后我也会一如既往,认真努力学习,不断提升自己,实现自己的理想。7. 结束语 在此,我很是感谢陈老师,他在我学习的途中给了我很多的帮助,让我懂得很多东西,学会很多,真心感谢他。同时,我也要对平时帮助

21、我的同学表示感谢。在我人生的道路中,很多人在我失意时帮我走出阴霾,感谢他们。8. 附录:程序清单#include#include#include#define OK 1#define ERROR 0#define LH 1#define EH 0#define RH -1typedef struct BSTNode int data; int bf; struct BSTNode *lchild,*rchild;BSTNode,*BSTree;typedef struct BSTree p;elem,*Elem;typedef struct Elem base; Elem top;Stack;

22、 int h,num,m,k,t,key=0;BSTree w;void Create(BSTree &T);void Insert(BSTree &T);int InsertAVL(BSTree &T,int e,int &taller);void R_Rotate(BSTree &p);void L_Rotate(BSTree &p);int LeftBalance(BSTree &T);int RightBalance(BSTree &T);void DeleteMenu(BSTree &T);int DeleteAVL(BSTree &T,int e,int &shorter);int

23、 Delete(BSTree &p);void Search(BSTree &T,int e,int key);void Output(BSTree T);void Inordertraverse(BSTree T);void Depth(BSTree p,int n,int &num);int Levelordertraverse(Stack &Q);int Initstack(Stack &Q);int Push(Stack &Q,BSTree e);int Pop(Stack &Q,BSTree &q);void Destroy(BSTree &T);void main() int a=

24、1,flag=0; BSTree T=NULL; while(a) system(cls); printf(nnnnntttt1创 建 二 叉 树nnnn); printf(tttt2插 入 数 据nnnn); printf(tttt3删 除 数 据nnnn); printf(tttt4输 出nnnn); printf(tttt5销 毁 二 叉 树nnnn); printf(tttt0退 出nn); if(!flag) printf(nnnn请选择:); else printf(nnnn你的输入有误,请重新输入:); flag=0; scanf(%d,&a); switch(a) case 1

25、:system(cls);Create(T);break; case 2:system(cls);Insert(T);break; case 3:system(cls);DeleteMenu(T);break; case 4:system(cls); if(T) Output(T); else printf(此二叉树为空树); printf(nnn按Enter); getchar();getchar(); break; case 5: system(cls);Destroy(T); printf(已将此二叉树销毁nnnn); printf(nnn按Enter); getchar();getch

26、ar(); case 0:system(cls);printf(nnnnnnnnnntttttTHANKSnnnnnnnnnnnn);break; default:flag=1;break; void Create(BSTree &T) int a=1,s,taller=false; while(a) printf(请输入数据(0结束):); scanf(%d,&a); if(a) s=InsertAVL(T,a,taller); if(!s) printf(%d已存在二叉树中,a); printf(nn); void Insert(BSTree &T) int a,s,taller=fals

27、e; printf(请输入数据:); scanf(%d,&a); do s=InsertAVL(T,a,taller); if(s) printf(nn%d已插入到二叉树中,a); else system(cls); printf(%d已存在二叉树中,请重新输入:,a); scanf(%d,&a); while(!s); printf(nnnnnnn按Enter); getchar();getchar();int InsertAVL(BSTree &T,int e,int &taller) if(!T) T=(BSTree)malloc(sizeof(BSTNode); if(!T) exit

28、(-1); T-data=e;T-bf=EH;T-lchild=T-rchild=NULL; taller=true; else if(e=T-data) taller=false; return 0; else 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(!InsertAVL(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=f

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1