c 语言实现红黑树
rbtree
1 /*----------------------------------------------------------- 2 RB-Tree的插入和删除操作的实现算法 3 参考资料: 4 1) <<Introduction to algorithm>> 5 2) [url]http://lxr.linux.no/linux/lib/rbtree.c[/url] 6 作者:[url]http://www.cppblog.com/converse/[/url] 7 您可以自由的传播,修改这份代码,转载处请注明原作者 8 红黑树的几个性质: 9 1) 每个结点只有红和黑两种颜色 10 2) 根结点是黑色的 11 3)空节点是黑色的(红黑树中,根节点的parent以及所有叶节点lchild、rchild都不指向NULL,而是指向一个定义好的 12 空节点)。 13 4) 如果一个结点是红色的,那么它的左右两个子结点的颜色是黑色的 14 5) 对于每个结点而言,从这个结点到叶子结点的任何路径上的黑色结点 15 的数目相同 16 -------------------------------------------------------------*/ 17 #include <stdio.h> 18 #include <stdlib.h> 19 #include <string.h> 20 typedef enum color_t 21 { 22 RED = 0, 23 BLACK = 1 24 }color_t; 25 typedef struct rb_node_t 26 { 27 struct rb_node_t *left, *right, *parent; 28 char key[21]; 29 color_t color; 30 }rb_node_t; 31 32 /* forward declaration */ 33 rb_node_t* rb_insert(char * key, rb_node_t* root); 34 rb_node_t* rb_search(char * key, rb_node_t* root); 35 rb_node_t* rb_erase(char * key, rb_node_t* root); 36 static rb_node_t* rb_new_node(char * key) 37 { 38 rb_node_t *node = (rb_node_t*)malloc(sizeof(struct rb_node_t)); 39 if (!node) 40 { 41 printf("malloc error!\n"); 42 exit(-1); 43 } 44 strcpy(node->key,key); 45 return node; 46 } 47 /*----------------------------------------------------------- 48 | node right 49 | / \ ==> / \ 50 | a right node y 51 | / \ / \ 52 | b y a b 53 -----------------------------------------------------------*/ 54 static rb_node_t* rb_rotate_left(rb_node_t* node, rb_node_t* root) 55 { 56 rb_node_t* right = node->right; 57 if ((node->right = right->left)) 58 { 59 right->left->parent = node; 60 } 61 right->left = node; 62 if ((right->parent = node->parent)) 63 { 64 if (node == node->parent->right) 65 { 66 node->parent->right = right; 67 } 68 else 69 { 70 node->parent->left = right; 71 } 72 } 73 else 74 { 75 root = right; 76 } 77 node->parent = right; 78 return root; 79 } 80 /*----------------------------------------------------------- 81 | node left 82 | / \ / \ 83 | left y ==> a node 84 | / \ / \ 85 | a b b y 86 -----------------------------------------------------------*/ 87 static rb_node_t* rb_rotate_right(rb_node_t* node, rb_node_t* root) 88 { 89 rb_node_t* left = node->left; 90 if ((node->left = left->right)) 91 { 92 left->right->parent = node; 93 } 94 left->right = node; 95 if ((left->parent = node->parent)) 96 { 97 if (node == node->parent->right) 98 { 99 node->parent->right = left; 100 } 101 else 102 { 103 node->parent->left = left; 104 } 105 } 106 else 107 { 108 root = left; 109 } 110 node->parent = left; 111 return root; 112 } 113 static rb_node_t* rb_insert_rebalance(rb_node_t *node, rb_node_t *root) 114 { 115 rb_node_t *parent, *gparent, *uncle, *tmp; 116 while ((parent = node->parent) && parent->color == RED) 117 { 118 gparent = parent->parent; 119 if (parent == gparent->left) 120 { 121 uncle = gparent->right; 122 if (uncle && uncle->color == RED) 123 { 124 uncle->color = BLACK; 125 parent->color = BLACK; 126 gparent->color = RED; 127 node = gparent; 128 } 129 else 130 { 131 if (parent->right == node) 132 { 133 root = rb_rotate_left(parent, root); 134 tmp = parent; 135 parent = node; 136 node = tmp; 137 } 138 parent->color = BLACK; 139 gparent->color = RED; 140 root = rb_rotate_right(gparent, root); 141 } 142 } 143 else 144 { 145 uncle = gparent->left; 146 if (uncle && uncle->color == RED) 147 { 148 uncle->color = BLACK; 149 parent->color = BLACK; 150 gparent->color = RED; 151 node = gparent; 152 } 153 else 154 { 155 if (parent->left == node) 156 { 157 root = rb_rotate_right(parent, root); 158 tmp = parent; 159 parent = node; 160 node = tmp; 161 } 162 parent->color = BLACK; 163 gparent->color = RED; 164 root = rb_rotate_left(gparent, root); 165 } 166 } 167 } 168 root->color = BLACK; 169 return root; 170 } 171 static rb_node_t* rb_erase_rebalance(rb_node_t *node, rb_node_t *parent, rb_node_t *root) 172 { 173 rb_node_t *other, *o_left, *o_right; 174 while ((!node || node->color == BLACK) && node != root) 175 { 176 if (parent->left == node) 177 { 178 other = parent->right; 179 if (other->color == RED) 180 { 181 other->color = BLACK; 182 parent->color = RED; 183 root = rb_rotate_left(parent, root); 184 other = parent->right; 185 } 186 if ((!other->left || other->left->color == BLACK) && 187 (!other->right || other->right->color == BLACK)) 188 { 189 other->color = RED; 190 node = parent; 191 parent = node->parent; 192 } 193 else 194 { 195 if (!other->right || other->right->color == BLACK) 196 { 197 if ((o_left = other->left)) 198 { 199 o_left->color = BLACK; 200 } 201 other->color = RED; 202 root = rb_rotate_right(other, root); 203 other = parent->right; 204 } 205 other->color = parent->color; 206 parent->color = BLACK; 207 if (other->right) 208 { 209 other->right->color = BLACK; 210 } 211 root = rb_rotate_left(parent, root); 212 node = root; 213 break; 214 } 215 } 216 else 217 { 218 other = parent->left; 219 if (other->color == RED) 220 { 221 other->color = BLACK; 222 parent->color = RED; 223 root = rb_rotate_right(parent, root); 224 other = parent->left; 225 } 226 if ((!other->left || other->left->color == BLACK) && 227 (!other->right || other->right->color == BLACK)) 228 { 229 other->color = RED; 230 node = parent; 231 parent = node->parent; 232 } 233 else 234 { 235 if (!other->left || other->left->color == BLACK) 236 { 237 if ((o_right = other->right)) 238 { 239 o_right->color = BLACK; 240 } 241 other->color = RED; 242 root = rb_rotate_left(other, root); 243 other = parent->left; 244 } 245 other->color = parent->color; 246 parent->color = BLACK; 247 if (other->left) 248 { 249 other->left->color = BLACK; 250 } 251 root = rb_rotate_right(parent, root); 252 node = root; 253 break; 254 } 255 } 256 } 257 if (node) 258 { 259 node->color = BLACK; 260 } 261 return root; 262 } 263 static rb_node_t* rb_search_auxiliary(char * key, rb_node_t* root, rb_node_t** save) 264 { 265 rb_node_t *node = root, *parent = NULL; 266 int ret; 267 while (node) 268 { 269 parent = node; 270 ret = strcmp(node->key,key); 271 if (0 < ret) 272 { 273 node = node->left; 274 } 275 else if (0 > ret) 276 { 277 node = node->right; 278 } 279 else 280 { 281 return node; 282 } 283 } 284 if (save) 285 { 286 *save = parent; 287 } 288 return NULL; 289 } 290 rb_node_t* rb_insert(char * key,rb_node_t* root) 291 { 292 rb_node_t *parent = NULL, *node; 293 parent = NULL; 294 if ((node = rb_search_auxiliary(key, root, &parent))) 295 { 296 return root; 297 } 298 node = rb_new_node(key); 299 node->parent = parent; 300 node->left = node->right = NULL; 301 node->color = RED; 302 if (parent) 303 { 304 if (strcmp(parent->key,key) > 0) 305 { 306 parent->left = node; 307 } 308 else 309 { 310 parent->right = node; 311 } 312 } 313 else 314 { 315 root = node; 316 } 317 return rb_insert_rebalance(node, root); 318 } 319 rb_node_t* rb_search(char * key, rb_node_t* root) 320 { 321 return rb_search_auxiliary(key, root, NULL); 322 } 323 rb_node_t* rb_erase(char * key, rb_node_t *root) 324 { 325 rb_node_t *child, *parent, *old, *left, *node; 326 color_t color; 327 if (!(node = rb_search_auxiliary(key, root, NULL))) 328 { 329 printf("key %d is not exist!\n"); 330 return root; 331 } 332 old = node; 333 if (node->left && node->right) 334 { 335 node = node->right; 336 while ((left = node->left) != NULL) 337 { 338 node = left; 339 } 340 child = node->right; 341 parent = node->parent; 342 color = node->color; 343 if (child) 344 { 345 child->parent = parent; 346 } 347 if (parent) 348 { 349 if (parent->left == node) 350 { 351 parent->left = child; 352 } 353 else 354 { 355 parent->right = child; 356 } 357 } 358 else 359 { 360 root = child; 361 } 362 if (node->parent == old) 363 { 364 parent = node; 365 } 366 node->parent = old->parent; 367 node->color = old->color; 368 node->right = old->right; 369 node->left = old->left; 370 if (old->parent) 371 { 372 if (old->parent->left == old) 373 { 374 old->parent->left = node; 375 } 376 else 377 { 378 old->parent->right = node; 379 } 380 } 381 else 382 { 383 root = node; 384 } 385 old->left->parent = node; 386 if (old->right) 387 { 388 old->right->parent = node; 389 } 390 } 391 else 392 { 393 if (!node->left) 394 { 395 child = node->right; 396 } 397 else if (!node->right) 398 { 399 child = node->left; 400 } 401 parent = node->parent; 402 color = node->color; 403 if (child) 404 { 405 child->parent = parent; 406 } 407 if (parent) 408 { 409 if (parent->left == node) 410 { 411 parent->left = child; 412 } 413 else 414 { 415 parent->right = child; 416 } 417 } 418 else 419 { 420 root = child; 421 } 422 } 423 free(old); 424 if (color == BLACK) 425 { 426 root = rb_erase_rebalance(child, parent, root); 427 } 428 return root; 429 }