平衡二叉树(AVL树)的基本操作(附有示意图)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
平衡二叉树关于树的深度是平衡的,具有较高的检索效率。平衡二叉树或是一棵空树,或是具有下列性质的二叉排序树:其左子树和右子树都是平衡二叉树,而且左右子树深度之差绝对值不超过1. 由此引出了平衡因子(balance factor)的概念,bf定义为该结点的左子树的深度减去右子树的深度(有些书是右子树深度减去左子树深度,我是按照左子树减去右子树来计算的,下面的代码也是这样定义的),所以平衡二叉树的结点的平衡因子只可能是-1,0,1 ,某个结点的平衡因子绝对值大于1,该二叉树就不平衡。
平衡二叉树在出现不平衡状态的时候,要进行平衡旋转处理,有四种平衡旋转处理(单向右旋处理,单向左旋处理,双向旋转(先左后右)处理,双向旋转(先右后左)处理),归根到底是两种(单向左旋处理和单向右旋处理)。
文件"tree.h"
view plain
1.#include
2.#include
3.#include
ing namespace std;
5.
6.const int LH=1; //左子树比右子树高1
7.const int EH=0; //左右子树一样高
8.const int RH=-1;//右子树比左子树高1
9.const int MAX_NODE_NUM=20; //结点数目上限
10.
11.class AVL_Tree;
12.
13.class AvlNode
14.{
15.int data;
16.int bf; //平衡因子
17. AvlNode *lchild;
18. AvlNode *rchild;
19.friend class AVL_Tree;
20.};
21.
22.class AVL_Tree
23.{
24.public:
25.int Get_data(AvlNode *p)
26. {
27.return p->data;
28. }
29.
30.void Create_AVl(AvlNode *&T) //建树
31. {
32. cout<<"输入平衡二叉树的元素,输入-1代表结束输入:";
33.int num[MAX_NODE_NUM];
34.int a,i=0;
35.while(cin>>a && a!=-1)
36. {
37. num[i]=a;
38. i++;
39. }
40.
41.if(num[0]==-1)
42. {
43. cout<<"平衡树为空"< 44. T=NULL; 45.return; 46. } 47. 48.int k=i; 49.bool taller=false; 50.for(i=0;i 51. Insert_Avl(T,num[i],taller);//逐个进行插入,插入过程看下面的示意图 52. cout<<"_____建树完成____"< 53. } 54. 55.void L_Rotate(AvlNode *&p) 56. { 57.//以p为根节点的二叉排序树进行单向左旋处理 58. AvlNode *rc=p->rchild; 59. p->rchild=rc->lchild; 60. rc->lchild=p; 61. p=rc; 62. } 63. 64.void R_Rotate(AvlNode *&p) 65. { 66.//以p为根节点的二叉排序树进行单向右旋处理 67. AvlNode *lc=p->lchild; 68. p->lchild=lc->rchild; 69. lc->rchild=p; 70. p=lc; 71. } 72. 73.void Left_Balance(AvlNode *&T) 74. { 75.//以T为根节点的二叉排序树进行左平衡旋转处理 76. AvlNode *lc,*rd; 77. lc=T->lchild; 78.switch(lc->bf) 79. { 80.case LH: 81.//新结点插在T的左孩子的左子树上,做单向右旋处理 82. T->bf=lc->bf=EH; 83. R_Rotate(T); 84.break; 85.case RH: 86.//新结点插在T的左孩子的右子树上,要进行双旋平衡处理(先左后右) 87. rd=lc->rchild; 88.switch(rd->bf) 89. { 90.case LH: 91.//插在右子树的左孩子上 92. T->bf=RH; 93. lc->bf=EH; 94.break; 95.case EH: 96. T->bf=lc->bf=EH; 97.break; 98.case RH: 99. T->bf=EH; 100. lc->bf=LH; 101.break; 102. } 103. rd->bf=EH; 104. L_Rotate(T->lchild);//先对T的左子树进行单向左旋处理 105. R_Rotate(T); //再对T进行单向右旋处理 106. } 107. } 108. 109.void Right_Balance(AvlNode *&T) 110. { 111.//以T为根节点的二叉排序树进行右平衡旋转处理 112. AvlNode *rc,*ld; 113. rc=T->rchild; 114.switch(rc->bf) 115. {