1. 程式人生 > >數據結構【查找】—平衡二叉樹AVL

數據結構【查找】—平衡二叉樹AVL

balance 實現 增加 調整 補充 若是 思想 基本思想 頭結點

/*自己看了半天也沒看懂代碼,下次再補充說明*/

解釋:

  平衡二叉樹(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 }

  

數據結構【查找】—平衡二叉樹AVL