MAC安裝單機zookeeper
紅黑樹是一種含有紅黑結點並能自平衡的二叉查詢樹。它必須滿足下面性質:
- 性質1:每個節點要麼是黑色,要麼是紅色。
- 性質2:根節點是黑色。
- 性質3:每個葉子節點(NIL)是黑色。
- 性質4:每個紅色結點的兩個子結點一定都是黑色。
- 性質5:任意一結點到每個葉子結點的路徑都包含數量相同的黑結點。
紅黑樹節點的插入
新插入的節點為紅色的節點,根據性質4和性質5,每次遇到相鄰的紅色節點都要做一定的處理使紅黑樹保持其性質。
分情況討論
考慮以下三種場景,其他對稱場景不贅述。
場景1
上圖中a、b、c、d子樹可以為NULL,N可以是P的左子樹也可以是右子樹,重新染色。
對於區域性來說,P和U染為黑色,G染為紅色,此時對於G的以及G以上節點到葉子節點的黑色節點數目保持原來的數目不變
場景2
上圖中a、b、c、d子樹可以為NULL,N是P的左子樹,U是NULL或者黑色節點。
對G節點執行右旋操作,對於區域性來說,P染為黑色,G染為紅色,此時對於P的以及P以上節點到葉子節點的黑色節點數目保持原來的數目不變
場景3
上圖中a、b、c、d、e子樹可以為NULL,N是P的右子樹,U是NULL或者黑色節點。
先對P節點給進行左旋,在對G節點執行右旋,對於區域性來說,N染為黑色,G染為紅色,此時對於N的以及N以上節點到葉子節點的黑色節點數目保持原來的數目不變
總結
由於以上情況可知,需要旋轉和重新染色的情況如果以N節點為目標,需要修改其父節點和祖父節點,在遞迴修改的過程中當前節點的位置邏輯較為複雜,用迴圈可能較為簡單。如果習慣遞迴的操作中,以G為當前節點,對其子孫節點進行操作,較為簡單。
迴圈方案程式碼示例:
遞迴方案程式碼示例:
1 RBNode* GetANewRBNode(int key){ 2 RBNode* newnode = (RBNode*)malloc(sizeof(RBNode)); 3 newnode->data = key; 4 newnode->color = Red; 5 return newnode; 6 } 7 8 void RightRotate(RBNode** rbtree){ 9 RBNode* L = (*rbtree)->lchild;View Code10 (*rbtree)->lchild = L->rchild; 11 L->rchild = *rbtree; 12 *rbtree = L; 13 } 14 15 void LeftRotate(RBNode** rbtree){ 16 RBNode* R = (*rbtree)->rchild; 17 (*rbtree)->rchild = R->lchild; 18 R->lchild = *rbtree; 19 *rbtree = R; 20 } 21 22 bool InsertEleIntoRBTreeRecu(RBNode** rbtree,int key){ 23 if(*rbtree == NULL){ 24 *rbtree = GetANewRBNode(key); 25 (*rbtree)->color = Black; 26 }else if ((*rbtree)->data == key){ 27 return false; 28 }else if ((*rbtree)->data > key){ 29 if( (*rbtree)->lchild == NULL ){ 30 (*rbtree)->lchild = GetANewRBNode(key); 31 }else if((*rbtree)->lchild->data == key){ 32 return false; 33 }else { 34 if((*rbtree)->lchild->data > key && (*rbtree)->lchild->lchild == NULL){ 35 //左孩子的右左孩子為空 36 (*rbtree)->lchild->lchild = GetANewRBNode(key); 37 if((*rbtree)->lchild->color == Red ){ 38 if( (*rbtree)->rchild != NULL && \ 39 (*rbtree)->rchild->color == Red ){ 40 //左右子節點同時為紅色,說明當前節點一定是黑色,新增節點,執行染色; 41 (*rbtree)->lchild->color = Black; 42 (*rbtree)->rchild->color = Black; 43 (*rbtree)->color = Red; 44 //printf("wqewo\n"); 45 }else{ 46 //左右子節點不同時為紅色,當前節點,對*rbtree執行右旋 47 RightRotate(rbtree); 48 (*rbtree)->color = Black; 49 (*rbtree)->rchild->color = Red; 50 } 51 } 52 }else if ((*rbtree)->lchild->data < key && (*rbtree)->lchild->rchild == NULL){ 53 //左孩子的右孩子為空 54 (*rbtree)->lchild->rchild = GetANewRBNode(key); 55 if((*rbtree)->lchild->color == Red){ 56 if( (*rbtree)->rchild != NULL && \ 57 (*rbtree)->rchild->color == Red ){ 58 //左右子節點同時為紅色,說明當前節點一定是黑色,新增節點,執行染色; 59 (*rbtree)->lchild->color = Black; 60 (*rbtree)->rchild->color = Black; 61 (*rbtree)->color = Red; 62 }else{ 63 //對(*rbtree)->lchild左旋 64 LeftRotate(&(*rbtree)->lchild); 65 //對*rbtree右旋 66 RightRotate(rbtree); 67 (*rbtree)->color = Black; 68 (*rbtree)->rchild->color = Red; 69 } 70 } 71 }else{ 72 bool sucess = InsertEleIntoRBTreeRecu(&(*rbtree)->lchild,key); 73 if (sucess && (*rbtree)->color == Black && (*rbtree)->lchild->color == Red) { 74 if((*rbtree)->rchild!=NULL && (*rbtree)->rchild->color == Red) 75 { 76 if(((*rbtree)->lchild->lchild!=NULL \ 77 && (*rbtree)->lchild->lchild->color == Red)|| \ 78 ((*rbtree)->lchild->rchild!=NULL && \ 79 (*rbtree)->lchild->rchild->color == Red)) 80 { 81 //染色 82 (*rbtree)->lchild->color = Black; 83 (*rbtree)->rchild->color = Black; 84 (*rbtree)->color = Red; 85 } 86 }else{ 87 if((*rbtree)->lchild->lchild!=NULL \ 88 && (*rbtree)->lchild->lchild->color == Red) 89 { 90 //對*rbtree執行右旋 91 RightRotate(rbtree); 92 (*rbtree)->color = Black; 93 (*rbtree)->rchild->color = Red; 94 }else if((*rbtree)->lchild->rchild!=NULL && \ 95 (*rbtree)->lchild->rchild->color == Red) 96 { 97 //對(*rbtree)->lchild左旋 98 //對*rbtree右旋 99 LeftRotate(&(*rbtree)->lchild); 100 RightRotate(rbtree); 101 (*rbtree)->color = Black; 102 (*rbtree)->rchild->color = Red; 103 } 104 } 105 } 106 else if (!sucess){ 107 return false; 108 } 109 } 110 } 111 }else{ 112 if( (*rbtree)->rchild == NULL ){ 113 (*rbtree)->rchild = GetANewRBNode(key); 114 }else if((*rbtree)->rchild->data == key){ 115 return false; 116 }else { 117 if((*rbtree)->rchild->data < key && (*rbtree)->rchild->rchild == NULL){ 118 //右孩子的右孩子為空 119 (*rbtree)->rchild->rchild = GetANewRBNode(key); 120 121 if((*rbtree)->rchild->color == Red ){ 122 if((*rbtree)->lchild != NULL && \ 123 (*rbtree)->lchild->color == Red ){ 124 //染色; 125 (*rbtree)->lchild->color = Black; 126 (*rbtree)->rchild->color = Black; 127 (*rbtree)->color = Red; 128 }else{ 129 //對*rbtree執行左旋 130 LeftRotate(rbtree); 131 (*rbtree)->color = Black; 132 (*rbtree)->lchild->color = Red; 133 } 134 } 135 }else if ((*rbtree)->rchild->data > key && (*rbtree)->rchild->lchild == NULL){ 136 (*rbtree)->rchild->lchild = GetANewRBNode(key); 137 if((*rbtree)->rchild->color == Red ){ 138 if((*rbtree)->lchild != NULL && \ 139 (*rbtree)->lchild->color == Red ){ 140 //染色; 141 (*rbtree)->lchild->color = Black; 142 (*rbtree)->rchild->color = Black; 143 (*rbtree)->color = Red; 144 }else{ 145 //對(*rbtree)->rchild右旋 146 RightRotate(&(*rbtree)->rchild); 147 //對*rbtree左旋 148 LeftRotate(rbtree); 149 (*rbtree)->color = Black; 150 (*rbtree)->lchild->color = Red; 151 } 152 } 153 }else{ 154 bool sucess = InsertEleIntoRBTreeRecu(&(*rbtree)->rchild,key); 155 if (sucess && (*rbtree)->color == Black && (*rbtree)->rchild->color == Red) { 156 if((*rbtree)->lchild!=NULL && (*rbtree)->lchild->color == Red) 157 { 158 if(((*rbtree)->rchild->rchild!=NULL \ 159 && (*rbtree)->rchild->rchild->color == Red)|| \ 160 ((*rbtree)->rchild->lchild!=NULL && \ 161 (*rbtree)->rchild->lchild->color == Red)) 162 { 163 //染色 164 (*rbtree)->lchild->color = Black; 165 (*rbtree)->rchild->color = Black; 166 (*rbtree)->color = Red; 167 } 168 }else{ 169 if((*rbtree)->rchild->rchild!=NULL \ 170 && (*rbtree)->rchild->rchild->color == Red) 171 { 172 //對*rbtree執行左旋 173 LeftRotate(rbtree); 174 (*rbtree)->color = Black; 175 (*rbtree)->lchild->color = Red; 176 }else if((*rbtree)->rchild->lchild!=NULL && \ 177 (*rbtree)->rchild->lchild->color == Red) 178 { 179 //對(*rbtree)->rchild右旋 180 RightRotate(&(*rbtree)->rchild); 181 //對*rbtree左旋 182 LeftRotate(rbtree); 183 (*rbtree)->color = Black; 184 (*rbtree)->lchild->color = Red; 185 } 186 } 187 }else if (!sucess) 188 return false; 189 } 190 } 191 } 192 return true; 193 } 194 195 bool InsertEleIntoRBTree1(RBNode** rbtree,int key){ 196 bool result = InsertEleIntoRBTreeRecu(&(*rbtree),key); 197 if(result){ 198 (*rbtree)->color = Black; 199 } 200 return result; 201 }
非遞迴方案
1 void RightRotateDualway(RBNode** rbtree){ 2 RBNode* L = (*rbtree)->lchild; 3 4 (*rbtree)->lchild = L->rchild; 5 6 if(L->rchild != NULL){ 7 L->rchild->parent = *rbtree; 8 L->rchild->postion = Left; 9 } 10 L->rchild = *rbtree; 11 12 L->parent = (*rbtree)->parent; 13 L->postion = (*rbtree)->postion; 14 15 *rbtree = L; 16 if((*rbtree)->parent!=NULL){ 17 if((*rbtree)->postion == Right){ 18 (*rbtree)->parent->rchild = (*rbtree); 19 }else{ 20 (*rbtree)->parent->lchild = (*rbtree); 21 } 22 } 23 (*rbtree)->rchild->parent = *rbtree; 24 (*rbtree)->rchild->postion = Right; 25 26 } 27 28 void LeftRotateDualway(RBNode** rbtree){ 29 RBNode* R = (*rbtree)->rchild; 30 31 (*rbtree)->rchild = R->lchild; 32 if(R->lchild != NULL) { 33 R->lchild->parent = (*rbtree); 34 R->lchild->postion = Right; 35 } 36 R->lchild = *rbtree; 37 38 R->parent = (*rbtree)->parent; 39 R->postion = (*rbtree)->postion; 40 41 *rbtree = R; 42 if((*rbtree)->parent!=NULL){ 43 if((*rbtree)->postion == Right){ 44 (*rbtree)->parent->rchild = (*rbtree); 45 }else{ 46 (*rbtree)->parent->lchild = (*rbtree); 47 } 48 } 49 (*rbtree)->lchild->parent = *rbtree; 50 (*rbtree)->lchild->postion = Left; 51 } 52 53 bool InsertEleIntoRBTreeCircle(RBNode** rbtree,int key){ 54 RBNode *parent = NULL,*uncle=NULL,*grantparents = NULL,*current =*rbtree; 55 bool findthekey = (current!=NULL && current->data == key); 56 while (!findthekey && current!=NULL){ 57 if(current->data > key){ 58 parent = current; 59 current = current->lchild; 60 }else{ 61 parent = current; 62 current = current->rchild; 63 } 64 if(current!=NULL && current->data == key){ 65 findthekey = true; 66 break; 67 } 68 } 69 if(findthekey) 70 return false; 71 current = GetANewRBNode(key); 72 current->parent = parent; 73 if(parent!=NULL){ 74 if(current->data < parent->data){ 75 parent->lchild = current,current->postion = Left; 76 }else{ 77 parent->rchild = current,current->postion = Right; 78 } 79 } 80 81 do{ 82 if(parent==NULL){ 83 break; 84 }else if (parent!=NULL && parent->parent==NULL){ 85 current = current->parent;break; 86 }else { 87 grantparents = parent->parent; 88 if(grantparents->color == Black && parent->color == Red){ 89 uncle = (parent->postion == Right)? grantparents->lchild:grantparents->rchild; 90 if (uncle!=NULL && uncle->color == Red){ 91 uncle->color=Black,parent->color=Black,grantparents->color=Red; 92 }else{ 93 if (current->postion == Right && parent->postion == Left){ 94 LeftRotateDualway(&parent);RightRotateDualway(&grantparents); 95 grantparents->rchild->color=Red; 96 }else if (current->postion == Right && parent->postion == Right){ 97 LeftRotateDualway(&grantparents);grantparents->lchild->color=Red; 98 }else if (current->postion == Left && parent->postion == Left){ 99 RightRotateDualway(&grantparents);grantparents->rchild->color=Red; 100 }else if (current->postion == Left && parent->postion == Right){ 101 RightRotateDualway(&parent);LeftRotateDualway(&grantparents); 102 grantparents->lchild->color=Red; 103 } 104 grantparents->color=Black; 105 } 106 current = grantparents,parent = grantparents->parent; 107 }else{ 108 printf(" wqe %d\n",current->data); 109 break; 110 } 111 } 112 }while(current->color!=Black && current->parent!=NULL); 113 114 if(current->parent==NULL){ *rbtree = current;} 115 116 return true; 117 } 118 119 bool InsertEleIntoRBTree2(RBNode** rbtree,int key){ 120 bool result = InsertEleIntoRBTreeCircle(&(*rbtree),key); 121 if(result){ 122 (*rbtree)->color = Black; 123 } 124 return result; 125 }View Code
紅黑樹節點的刪除
如下圖所示,刪除 N‘ 節點,N 節點則成為 P 節點的新的子節點。其中,N' 節點按照二叉搜尋樹的方式查詢確定,它最多隻會有一個子樹,左子樹或者右子樹至少有一個是NULL。
考慮需要刪除節點是否導致紅黑樹性質變化:
(1)如果 N' 節點是根節點,因為至少有一個節點為根節點,則將非空子樹替換原來的樹
(2)如果 N' 節點為紅色節點,N 為NULL,則把 P 節點作為 N 節點
(3)如果 N' 節點為紅色節點,N 不為NULL,且N'不是根節點,那麼 P 必然不是NULL。因此,P 和 N 必然都是黑節點,刪除 N' 之後,N 和 P 節點可以直接相連
(4)如果 N' 為黑色 N 為紅色,那麼將N染色為黑色後,N 和 P 節點相連即可
(5)如果 N' 節點為黑色節點,N 為NULL,性質同(6)
(6)對於 N' 節點為黑色節點,對於父節點 P 和祖父節點 G 來說,其中有一個子樹黑色節點少了一個,導致違反了性質5,因此重新反轉和染色。此種情況下,P 的右子樹中至少包含一個黑色節點,不可能為空。
對於情況(6),分如下情況討論(位置對稱的情況不額外討論):
(6.1)如果 N 為黑色,S 是 N 的兄弟節點,為黑色, SL 是 S 的左孩子,P是父節點,為紅色,G是祖父節點。h/h+1/h+2表示從節點出發到葉子節點的簡單路徑中黑色節點的數量(後面簡稱為黑色節點數量)
①左旋變成②,對於祖父節點 G,孩子節點變成了 S,S節點的左子樹右子樹中黑色節點數量一致。子樹b之前是S節點的孩子,而S為黑色,那麼子樹b的根節點可能為紅也可能為黑,而節點 P 的顏色是紅色,所以要分情況討論:
(6.1.1)如果b的根節點為黑色,S 以及後續的子樹可以構成一個紅黑樹,是平衡的,且 G 節點到以 S 節點作為根節點的子樹的葉子節點的黑色節點數量保持(h+2),所以不違反性質5。P 原來是紅色,那麼 G 節點必然是黑色,到②中 S 變成 G 的孩子,由於 S 是黑色,那麼也不違反紅黑樹性質4。
(6.1.2)如果b的根節點為紅色,對 P 的右子樹進行右旋,然後以 P 為軸心左旋,再將 P 節點染為黑色。
(6.2)如果 N 為黑色,S 是 N 的兄弟節點,為紅色, SL 是 S 的左孩子,P是父節點,為黑色,G是祖父節點。
從①到②左旋,②到③染色,P 染色為紅色,S 染色為黑色,此時藍色虛線區域內的子樹還未平衡,目前起碼違反了性質5,將③中 P 為根節點的子樹單獨劃出來如圖④,此時子圖的情形如(6.1),則進行一次左旋可解滿足紅黑樹的性質。
(6.3)如果 N 為黑色,S 是 N 的兄弟節點,為黑色, SL 是 S 的左孩子,P是父節點,為黑色,G是祖父節點。
此時對子樹左旋,無法解決問題。
(6.3.1)如果 SL 節點為紅色,從①到④變換即可作為保持紅黑樹的性質。
(6.3.2)如果SL節點為黑色或者為空,⑤到⑦進行變換,對於 G 節點,子樹中黑色節點數量由(h+3)變成了(h+2),對於G節點,左右子樹不再平衡,因此這種平衡向上傳播,進行進一步再平衡
完整程式碼如下:
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include <stdbool.h> 5 6 enum Color { Black = 0 ,Red = 1}; 7 enum LeftOrRignt {Left = 0,Right = 1}; 8 9 typedef struct Node{ 10 int data; 11 int height; 12 bool color; 13 struct Node *lchild,*rchild; 14 struct Node *parent; 15 enum LeftOrRignt postion; 16 } AVLNode,BstNode,RBNode; 17 18 19 void PreOrderTraverse(AVLNode * tree){ 20 if(tree!=NULL){ 21 printf("data:%d; color:%d ;parent:%d ;lchild:%d; rchild:%d\n",tree->data,tree->color,tree->parent,tree->lchild,tree->rchild); 22 PreOrderTraverse(tree->lchild); 23 PreOrderTraverse(tree->rchild); 24 } 25 } 26 27 void InOrderTraverse(struct Node * tree){ 28 if(tree!=NULL){ 29 InOrderTraverse(tree->lchild); 30 printf("%d \n",tree->data); 31 InOrderTraverse(tree->rchild); 32 } 33 } 34 35 RBNode* GetANewRBNode(int key){ 36 RBNode* newnode = (RBNode*)malloc(sizeof(RBNode)); 37 newnode->data = key; 38 newnode->color = Red; 39 newnode->lchild = NULL; 40 newnode->rchild = NULL; 41 return newnode; 42 } 43 44 void RightRotate(RBNode** rbtree){ 45 RBNode* L = (*rbtree)->lchild; 46 (*rbtree)->lchild = L->rchild; 47 L->rchild = *rbtree; 48 *rbtree = L; 49 } 50 51 void LeftRotate(RBNode** rbtree){ 52 RBNode* R = (*rbtree)->rchild; 53 (*rbtree)->rchild = R->lchild; 54 R->lchild = *rbtree; 55 *rbtree = R; 56 } 57 58 bool InsertEleIntoRBTreeRecu(RBNode** rbtree,int key){ 59 if(*rbtree == NULL){ 60 *rbtree = GetANewRBNode(key); 61 (*rbtree)->color = Black; 62 }else if ((*rbtree)->data == key){ 63 return false; 64 }else if ((*rbtree)->data > key){ 65 if( (*rbtree)->lchild == NULL ){ 66 (*rbtree)->lchild = GetANewRBNode(key); 67 }else if((*rbtree)->lchild->data == key){ 68 return false; 69 }else { 70 if((*rbtree)->lchild->data > key && (*rbtree)->lchild->lchild == NULL){ 71 //左孩子的右左孩子為空 72 (*rbtree)->lchild->lchild = GetANewRBNode(key); 73 if((*rbtree)->lchild->color == Red ){ 74 if( (*rbtree)->rchild != NULL && \ 75 (*rbtree)->rchild->color == Red ){ 76 //左右子節點同時為紅色,說明當前節點一定是黑色,新增節點,執行染色; 77 (*rbtree)->lchild->color = Black; 78 (*rbtree)->rchild->color = Black; 79 (*rbtree)->color = Red; 80 }else{ 81 //左右子節點不同時為紅色,當前節點,對*rbtree執行右旋 82 RightRotate(rbtree); 83 (*rbtree)->color = Black; 84 (*rbtree)->rchild->color = Red; 85 } 86 } 87 }else if ((*rbtree)->lchild->data < key && (*rbtree)->lchild->rchild == NULL){ 88 //左孩子的右孩子為空 89 (*rbtree)->lchild->rchild = GetANewRBNode(key); 90 if((*rbtree)->lchild->color == Red){ 91 if( (*rbtree)->rchild != NULL && \ 92 (*rbtree)->rchild->color == Red ){ 93 //左右子節點同時為紅色,說明當前節點一定是黑色,新增節點,執行染色; 94 (*rbtree)->lchild->color = Black; 95 (*rbtree)->rchild->color = Black; 96 (*rbtree)->color = Red; 97 }else{ 98 //對(*rbtree)->lchild左旋 99 LeftRotate(&(*rbtree)->lchild); 100 //對*rbtree右旋 101 RightRotate(rbtree); 102 (*rbtree)->color = Black; 103 (*rbtree)->rchild->color = Red; 104 } 105 } 106 }else{ 107 bool sucess = InsertEleIntoRBTreeRecu(&(*rbtree)->lchild,key); 108 if (sucess && (*rbtree)->color == Black && (*rbtree)->lchild->color == Red) { 109 if((*rbtree)->rchild!=NULL && (*rbtree)->rchild->color == Red) 110 { 111 if(((*rbtree)->lchild->lchild!=NULL \ 112 && (*rbtree)->lchild->lchild->color == Red)|| \ 113 ((*rbtree)->lchild->rchild!=NULL && \ 114 (*rbtree)->lchild->rchild->color == Red)) 115 { 116 //染色 117 (*rbtree)->lchild->color = Black; 118 (*rbtree)->rchild->color = Black; 119 (*rbtree)->color = Red; 120 } 121 }else{ 122 if((*rbtree)->lchild->lchild!=NULL \ 123 && (*rbtree)->lchild->lchild->color == Red) 124 { 125 //對*rbtree執行右旋 126 RightRotate(rbtree); 127 (*rbtree)->color = Black; 128 (*rbtree)->rchild->color = Red; 129 }else if((*rbtree)->lchild->rchild!=NULL && \ 130 (*rbtree)->lchild->rchild->color == Red) 131 { 132 //對(*rbtree)->lchild左旋 133 //對*rbtree右旋 134 LeftRotate(&(*rbtree)->lchild); 135 RightRotate(rbtree); 136 (*rbtree)->color = Black; 137 (*rbtree)->rchild->color = Red; 138 } 139 } 140 } 141 else if (!sucess){ 142 return false; 143 } 144 } 145 } 146 }else{ 147 if( (*rbtree)->rchild == NULL ){ 148 (*rbtree)->rchild = GetANewRBNode(key); 149 }else if((*rbtree)->rchild->data == key){ 150 return false; 151 }else { 152 if((*rbtree)->rchild->data < key && (*rbtree)->rchild->rchild == NULL){ 153 //右孩子的右孩子為空 154 (*rbtree)->rchild->rchild = GetANewRBNode(key); 155 156 if((*rbtree)->rchild->color == Red ){ 157 if((*rbtree)->lchild != NULL && \ 158 (*rbtree)->lchild->color == Red ){ 159 //染色; 160 (*rbtree)->lchild->color = Black; 161 (*rbtree)->rchild->color = Black; 162 (*rbtree)->color = Red; 163 }else{ 164 //對*rbtree執行左旋 165 LeftRotate(rbtree); 166 (*rbtree)->color = Black; 167 (*rbtree)->lchild->color = Red; 168 } 169 } 170 }else if ((*rbtree)->rchild->data > key && (*rbtree)->rchild->lchild == NULL){ 171 (*rbtree)->rchild->lchild = GetANewRBNode(key); 172 if((*rbtree)->rchild->color == Red ){ 173 if((*rbtree)->lchild != NULL && \ 174 (*rbtree)->lchild->color == Red ){ 175 //染色; 176 (*rbtree)->lchild->color = Black; 177 (*rbtree)->rchild->color = Black; 178 (*rbtree)->color = Red; 179 }else{ 180 //對(*rbtree)->rchild右旋 181 RightRotate(&(*rbtree)->rchild); 182 //對*rbtree左旋 183 LeftRotate(rbtree); 184 (*rbtree)->color = Black; 185 (*rbtree)->lchild->color = Red; 186 } 187 } 188 }else{ 189 bool sucess = InsertEleIntoRBTreeRecu(&(*rbtree)->rchild,key); 190 if (sucess && (*rbtree)->color == Black && (*rbtree)->rchild->color == Red) { 191 if((*rbtree)->lchild!=NULL && (*rbtree)->lchild->color == Red) 192 { 193 if(((*rbtree)->rchild->rchild!=NULL \ 194 && (*rbtree)->rchild->rchild->color == Red)|| \ 195 ((*rbtree)->rchild->lchild!=NULL && \ 196 (*rbtree)->rchild->lchild->color == Red)) 197 { 198 //染色 199 (*rbtree)->lchild->color = Black; 200 (*rbtree)->rchild->color = Black; 201 (*rbtree)->color = Red; 202 } 203 }else{ 204 if((*rbtree)->rchild->rchild!=NULL \ 205 && (*rbtree)->rchild->rchild->color == Red) 206 { 207 //對*rbtree執行左旋 208 LeftRotate(rbtree); 209 (*rbtree)->color = Black; 210 (*rbtree)->lchild->color = Red; 211 }else if((*rbtree)->rchild->lchild!=NULL && \ 212 (*rbtree)->rchild->lchild->color == Red) 213 { 214 //對(*rbtree)->rchild右旋 215 RightRotate(&(*rbtree)->rchild); 216 //對*rbtree左旋 217 LeftRotate(rbtree); 218 (*rbtree)->color = Black; 219 (*rbtree)->lchild->color = Red; 220 } 221 } 222 }else if (!sucess) 223 return false; 224 } 225 } 226 } 227 return true; 228 } 229 230 bool InsertEleIntoRBTree1(RBNode** rbtree,int key){ 231 bool result = InsertEleIntoRBTreeRecu(&(*rbtree),key); 232 if(result){ 233 (*rbtree)->color = Black; 234 } 235 return result; 236 } 237 238 RBNode* GetANewRBNodeDualway(int key){ 239 RBNode* newnode = (RBNode*)malloc(sizeof(RBNode)); 240 newnode->data = key; 241 newnode->color = Red; 242 newnode->parent = NULL; 243 newnode->lchild = NULL; 244 newnode->rchild = NULL; 245 return newnode; 246 } 247 248 void RightRotateDualway(RBNode** rbtree){ 249 RBNode* L = (*rbtree)->lchild; 250 251 (*rbtree)->lchild = L->rchild; 252 253 if(L->rchild != NULL){ 254 L->rchild->parent = *rbtree; 255 L->rchild->postion = Left; 256 } 257 L->rchild = *rbtree; 258 259 L->parent = (*rbtree)->parent; 260 L->postion = (*rbtree)->postion; 261 262 *rbtree = L; 263 if((*rbtree)->parent!=NULL){ 264 if((*rbtree)->postion == Right){ 265 (*rbtree)->parent->rchild = (*rbtree); 266 }else{ 267 (*rbtree)->parent->lchild = (*rbtree); 268 } 269 } 270 (*rbtree)->rchild->parent = *rbtree; 271 (*rbtree)->rchild->postion = Right; 272 273 } 274 275 void LeftRotateDualway(RBNode** rbtree){ 276 RBNode* R = (*rbtree)->rchild; 277 278 (*rbtree)->rchild = R->lchild; 279 if(R->lchild != NULL) { 280 R->lchild->parent = (*rbtree); 281 R->lchild->postion = Right; 282 } 283 R->lchild = *rbtree; 284 285 R->parent = (*rbtree)->parent; 286 R->postion = (*rbtree)->postion; 287 //(*rbtree)->parent = R; 288 //(*rbtree)->postion = Left; 289 290 291 *rbtree = R; 292 if((*rbtree)->parent!=NULL){ 293 if((*rbtree)->postion == Right){ 294 (*rbtree)->parent->rchild = (*rbtree); 295 }else{ 296 (*rbtree)->parent->lchild = (*rbtree); 297 } 298 } 299 (*rbtree)->lchild->parent = *rbtree; 300 (*rbtree)->lchild->postion = Left; 301 } 302 303 bool InsertEleIntoRBTreeCircle(RBNode** rbtree,int key){ 304 RBNode *parent = NULL,*uncle=NULL,*grantparents = NULL,*current =*rbtree; 305 bool findthekey = (current!=NULL && current->data == key); 306 while (!findthekey && current!=NULL){ 307 if(current->data > key){ 308 parent = current; 309 current = current->lchild; 310 }else{ 311 parent = current; 312 current = current->rchild; 313 } 314 if(current!=NULL && current->data == key){ 315 findthekey = true; 316 break; 317 } 318 } 319 if(findthekey) 320 return false; 321 current = GetANewRBNode(key); 322 current->parent = parent; 323 if(parent!=NULL){ 324 if(current->data < parent->data){ 325 parent->lchild = current,current->postion = Left; 326 }else{ 327 parent->rchild = current,current->postion = Right; 328 } 329 } 330 //while(current->color!=Black || current->parent!=NULL) 331 do{ 332 if(parent==NULL){ 333 break; 334 }else if (parent!=NULL && parent->parent==NULL){ 335 current = current->parent;break; 336 }else { 337 grantparents = parent->parent; 338 if(grantparents->color == Black && parent->color == Red){ 339 uncle = (parent->postion == Right)? grantparents->lchild:grantparents->rchild; 340 if (uncle!=NULL && uncle->color == Red){ 341 uncle->color=Black,parent->color=Black,grantparents->color=Red; 342 }else{ 343 if (current->postion == Right && parent->postion == Left){ 344 LeftRotateDualway(&parent);RightRotateDualway(&grantparents); 345 grantparents->rchild->color=Red; 346 }else if (current->postion == Right && parent->postion == Right){ 347 LeftRotateDualway(&grantparents);grantparents->lchild->color=Red; 348 }else if (current->postion == Left && parent->postion == Left){ 349 RightRotateDualway(&grantparents);grantparents->rchild->color=Red; 350 }else if (current->postion == Left && parent->postion == Right){ 351 RightRotateDualway(&parent);LeftRotateDualway(&grantparents); 352 grantparents->lchild->color=Red; 353 } 354 grantparents->color=Black; 355 } 356 current = grantparents,parent = grantparents->parent; 357 }else{ 358 break; 359 } 360 } 361 }while(current->color!=Black && current->parent!=NULL); 362 363 if(current->parent==NULL){ *rbtree = current;} 364 365 return true; 366 } 367 368 bool InsertEleIntoRBTree2(RBNode** rbtree,int key){ 369 bool result = InsertEleIntoRBTreeCircle(&(*rbtree),key); 370 if(result){ 371 (*rbtree)->color = Black; 372 } 373 return result; 374 } 375 376 bool ReblanceRBTree(RBNode **parent,int sibostion){ 377 378 RBNode *sibling = (sibostion == Right)? (*parent)->rchild:(*parent)->lchild; 379 if(sibling->color == Black && (*parent)->color == Red ){ 380 if(sibostion == Right ){ 381 if((*parent)->rchild->lchild!=NULL && (*parent)->rchild->lchild->color == Red){ 382 RightRotateDualway(&(*parent)->rchild); 383 } 384 LeftRotateDualway(parent); 385 }else{ 386 if((*parent)->lchild->rchild!=NULL && (*parent)->lchild->rchild->color == Red){ 387 LeftRotateDualway(&(*parent)->lchild); 388 } 389 RightRotateDualway(parent); 390 } 391 }else if (sibling->color == Red && (*parent)->color == Black){ 392 if(sibostion == Right){ 393 LeftRotateDualway(parent); 394 (*parent)->color = Black,(*parent)->lchild->color = Red; 395 LeftRotateDualway(&(*parent)->lchild); 396 }else{ 397 RightRotateDualway(parent); 398 (*parent)->color = Black,(*parent)->rchild->color = Red; 399 RightRotateDualway(&(*parent)->rchild); 400 } 401 }else{ 402 if(sibostion == Right){ 403 if((*parent)->rchild->lchild!=NULL && (*parent)->rchild->lchild->color == Red){ 404 RightRotateDualway(&(*parent)->rchild); 405 LeftRotateDualway(parent); 406 (*parent)->color = Black; 407 }else{ 408 LeftRotateDualway(parent); 409 return true; 410 } 411 }else{ 412 if((*parent)->lchild->rchild != NULL && (*parent)->lchild->rchild->color == Red){ 413 LeftRotateDualway(&(*parent)->lchild); 414 RightRotateDualway(parent); 415 (*parent)->color = Black; 416 }else{ 417 RightRotateDualway(parent); 418 return true; 419 } 420 } 421 } 422 return false; 423 } 424 425 bool DeleteEleFromRBTree2(RBNode **rbtree,int key){ 426 return true; 427 } 428 429 bool DeleteEleFromRBTree(RBNode **rbtree,int key){ 430 431 RBNode *current =*rbtree; 432 433 while (current!=NULL && current->data != key){ 434 if(current->data > key){ current = current->lchild; } 435 else{ current = current->rchild; } 436 } 437 if(current==NULL) { return false;} 438 RBNode* realdelnode = current; 439 440 if (realdelnode->lchild != NULL){ 441 realdelnode = realdelnode->lchild; 442 while(realdelnode->rchild != NULL) realdelnode = realdelnode->rchild; 443 } 444 current->data = realdelnode->data; 445 446 RBNode *parent = NULL, *kid=NULL; 447 448 current = realdelnode; 449 parent = realdelnode->parent; 450 int sibpostion = 1-realdelnode->postion; 451 452 if(current->rchild == NULL) kid = current->lchild; else kid = current->rchild; 453 if(current->parent == NULL) { 454 //如果 N' 節點是根節點,因為至少有一個節點為根節點,則將非空子樹替換原來的樹 455 *rbtree = kid; 456 free(realdelnode); 457 return true; 458 } 459 460 if(current->postion==Right) { parent->rchild=kid; } else { parent->lchild = kid; } 461 if(kid != NULL){ kid->parent = parent;} 462 463 int colortodel = realdelnode->color; 464 free(realdelnode); 465 466 if(kid!=NULL && kid->color == Red){ 467 kid->color = colortodel; 468 }else if (colortodel==Black){ 469 bool temp_result = true; 470 RBNode* grandparent = NULL; 471 while (temp_result) { 472 473 grandparent = parent->parent; 474 temp_result = ReblanceRBTree(&parent,sibpostion); 475 if(grandparent != NULL){ 476 if(parent->postion == Right) { 477 grandparent->rchild = parent; 478 }else{ 479 grandparent->lchild = parent; 480 } 481 parent->parent = grandparent; 482 }else{ 483 (*rbtree) = parent; 484 break; 485 } 486 sibpostion = 1-parent->postion; 487 } 488 } 489 (*rbtree)->color = Black; 490 491 return true; 492 } 493 494 int main(void){ 495 AVLNode * tree=NULL; 496 int arr[] = {37,28}; 497 //int arr[] = {35,32,30,28,26,24,22,18,14,10,37,39,44,45,38,33,2,1}; 498 int index = 0; 499 for(index = 0 ; index < 2 ; ++index){ 500 InsertEleIntoRBTree2(&tree,arr[index]); 501 } 502 printf("#########################\n"); 503 printf("PreOrderTraverse start!\n"); 504 PreOrderTraverse(tree); 505 printf("PreOrderTraverse stop!\n"); 506 //printf("######################### %f\n",&tree); 507 printf("#########################\n"); 508 DeleteEleFromRBTree(&tree,37); 509 DeleteEleFromRBTree(&tree,28); 510 printf("#########################\n"); 511 printf("PreOrderTraverse start!\n"); 512 PreOrderTraverse(tree); 513 printf("PreOrderTraverse stop!\n"); 514 printf("#########################\n"); 515 516 return 0; 517 }View Code