数据结构【查找】—平衡二叉树AVL
/*自己看了半天也没看懂代码,下次再补充说明*/
解释:
平衡二叉树(Self-Balancing Binary Search Tree 或Height-Balanced Binary Search Tree),是一种二叉排序树,其中每一个节点的左子树和右子树的高度差至多等于1。
实现原理:
平衡二叉树构建的基本思想就是在构建二又排序树的过程中,每当插入一个结点时,先检查是否因插入而破坏了树的平衡性,若是,则找出最小不平衡子树。在保持二又排序树特性的前提下,调整最小不平衡子树中各结点之间的链接关系,进行相应的旋转,使之成为新的平衡子树。
右旋:
左旋:
左旋、右旋:
代码实现:
1 #include "000库函数.h" 2 3 #define MAXSIZE 100// 4 #define EH 0 5 #define LH +1 //左高 6 #define RH -1 //右高 7 8 //二叉树的结构 9 struct BiTree 10 { 11 int data; 12 int bf;//AVL的平衡因子 13 BiTree *lchild, *rchild; 14 }; 15 16 bool L_Rotate(BiTree* &T) {//对T的左子树作左旋平衡处理 17 BiTree *R; 18 R = T->rchild; 19 T->rchild = R->lchild;//R的左子树挂接为T的右子树 20 R->lchild = T; 21 T = R; 22 return true; 23 } 24 25 bool R_Rotate(BiTree* &T) {//对T做右旋处理 26 BiTree *L; 27 L = T->lchild; 28 T->lchild = L->rchild; 29 L->rchild = T; 30 T = L; 31 return true; 32 } 33 34 35 36 37 //判断再加入左子树会不会打破平衡 38 bool LeftBalace(BiTree* &T) {//如今再添加进左边就应该添加后判断是否打破了平衡 39 BiTree *L, *Lr; 40 L = T->lchild; 41 switch (L->bf)//判断左子树的平衡因子 42 { 43 case LH://原为左增,现再增加就打破平衡了,故需要做右旋处理 44 T->bf = L->bf = EH; 45 R_Rotate(T); 46 break; 47 case RH://原节点为右增,再增加左节点(深度+1),就打破平衡了,故作双旋处理 48 Lr = L->rchild; 49 switch (Lr->bf) 50 { 51 case LH: 52 T->bf = RH; 53 L->bf = EH; 54 break; 55 case EH: 56 T->bf = L->bf = EH; 57 break; 58 case RH: 59 T->bf = EH; 60 L->bf = LH; 61 break; 62 default: 63 break; 64 } 65 Lr->bf = EH; 66 L_Rotate(T->lchild);//对T的左子树作左旋平衡处理 67 R_Rotate(T);//对T做右旋处理 68 break; 69 default: 70 break; 71 } 72 return true; 73 } 74 75 //判断再加入右子树会不会打破平衡 76 bool RightBalace(BiTree* &T) {//如今再添加进右边就应该添加后判断是否打破了平衡 77 BiTree *R, *Rl; 78 R = T->rchild; 79 switch (R->bf)//判断右子树的平衡因子 80 { 81 case LH://原节点为左增,再增加右节点(深度+1),就打破平衡了,故作双旋处理 82 Rl = R->lchild; 83 switch (Rl->bf) 84 { 85 case LH: 86 T->bf = EH; 87 R->bf = RH; 88 break; 89 case EH: 90 T->bf = R->bf = EH; 91 break; 92 case RH: 93 T->bf = LH; 94 R->bf = EH; 95 break; 96 default: 97 break; 98 } 99 Rl->bf = EH; 100 R_Rotate(T->rchild);//对T的左子树作左旋平衡处理 101 L_Rotate(T);//对T做右旋处理 102 break; 103 case RH://原为右增,现再增加就打破平衡了,故需要做左旋处理 104 T->bf = R->bf = EH; 105 L_Rotate(T); 106 break; 107 default: 108 break; 109 } 110 return true; 111 } 112 113 //AVL创建 114 /* 若在平衡的二叉排序树T中不存在和e有相同关键字的结点,则插入一个 */ 115 /* 数据元素为e的新结点,并返回1,否则返回0。若因插入而使二叉排序树 */ 116 /* 失去平衡,则作平衡旋转处理,布尔变量taller反映T长高与否。 */ 117 bool InsertAVL(BiTree * &T, int elem, bool &n) { 118 if (T == NULL) { 119 BiTree *p; 120 p = new BiTree; 121 p->data = elem; 122 p->bf = EH; 123 p->lchild = NULL; 124 p->rchild = NULL; 125 T = p; 126 n = true; 127 return true; 128 } 129 if (T->data == elem) {//数据已存在,不需要再添加 130 n = false; 131 return false; 132 } 133 if (elem < T->data) { 134 if (!(InsertAVL(T->lchild, elem, n)))//应当继续在左子树中继续查找 135 return false;//添加失败 136 if (n) {//添加成功 137 switch (T->bf)//检查AVL的平衡因子 138 { 139 case LH://原树左边高 140 LeftBalace(T);//如今再添加进左边就应该添加后判断是否打破了平衡 141 n = false; 142 break; 143 case EH://原树左等高度,那就加入其左边,让其增高 144 T->bf = LH; 145 n = true; 146 break; 147 case RH://原树右端高,那就加入左端,抵消有右边的高度 148 T->bf = EH; 149 n = false; 150 break; 151 default: 152 break; 153 } 154 } 155 } 156 else { 157 if (!(InsertAVL(T->rchild, elem, n)))//应当继续在右子树中继续查找 158 return false;//添加失败 159 if (n) {//添加成功 160 switch (T->bf)//检查AVL的平衡因子 161 { 162 case LH://原树左边高 163 T->bf = EH;//加入右端,抵消有左边的高度 164 n = false; 165 break; 166 case EH://原树左等高度,那就加入其右边,让其增高 167 T->bf = LH; 168 n = true; 169 break; 170 case RH://原树右端高 171 RightBalace(T);//如今再添加进右边就应该添加后判断是否打破了平衡 172 n = false; 173 break; 174 default: 175 break; 176 } 177 } 178 } 179 180 181 } 182 //遍历AVL 183 void ShowTree(BiTree *T) { 184 //进行中序浏览 185 if (T) { 186 ShowTree(T->lchild); 187 cout << T->data << "—>"; 188 ShowTree(T->rchild); 189 } 190 } 191 192 int T033(void) 193 { 194 int i; 195 int a[10] = { 3,2,1,4,5,6,7,10,9,8 }; 196 BiTree *T = new BiTree; 197 T = NULL; 198 bool taller;//用来判断AVL是否增加了深度 199 BiTree *p; 200 for (i = 0; i < 10; i++) { 201 InsertAVL(T, a[i], taller); 202 if (i == 0)p = T;//记住头结点 203 } 204 ShowTree(T); 205 cout << endl; 206 return 0; 207 }