红黑树C++实现
来源:互联网 发布:网络篮球游戏 编辑:程序博客网 时间:2024/06/16 21:44
1 /* 2 * rbtree.h 3 * 1. 每个节点是红色或者黑色 4 * 2. 根节点是黑色 5 * 3. 每个叶子节点是黑色(该叶子节点就空的节点) 6 * 4. 如果一个节点是红色,则它的两个子节点是黑色的 7 * 5.对每个节点,从该节点道其他所有后代的叶子节点的简单路径上,均包含相同数目的黑色节点 8 * 9 */ 10 11 #ifndef SRC_RBTREE_H_ 12 #define SRC_RBTREE_H_ 13 #include<iostream> 14 #include<queue> 15 16 using namespace std; 17 enum colors{ RED,BLACK}; 18 typedef int color_type; 19 namespace red_black_tree{ 20 struct rb_tree_base{ 21 struct rb_tree_base * parent; 22 struct rb_tree_base * left; 23 struct rb_tree_base * right; 24 color_type color; 25 }; 26 27 template<class T> 28 struct rb_tree_node:public rb_tree_base{ 29 T data; 30 typedef rb_tree_node<T>* link_type; 31 }; 32 template<class Value> 33 class rb_tree{ 34 public: 35 typedef rb_tree_base* rb_ptr; 36 typedef typename rb_tree_node<Value>::link_type link_type; 37 typedef rb_tree_node<Value> tree_node; 38 private: 39 rb_ptr head; 40 private: 41 bool _right_rotate(rb_ptr root); 42 bool _left_rotate(rb_ptr root); 43 rb_ptr _get_node(const Value& e) const; 44 bool _insert_fix_up(rb_ptr current_ptr); 45 46 bool _erase_fix_up(rb_ptr current_ptr,rb_ptr parent_ptr); 47 48 void _preOrder(rb_ptr root) const; 49 50 rb_ptr _successor(rb_ptr current_ptr) const; 51 public: 52 rb_tree(); 53 ~rb_tree(); 54 bool insert(const Value &e); 55 bool empty() const; 56 bool erase(const Value &e); 57 rb_ptr find(const Value &e); 58 void levelOrder() const; 59 void preOrder() const; 60 }; 61 template<class Value> 62 rb_tree<Value>::rb_tree() { 63 head = new tree_node(); 64 head->left=head; 65 head->right=head; 66 head->parent=head; 67 68 head->color=BLACK; 69 } 70 71 template<class Value> 72 rb_tree<Value>::~rb_tree() { 73 } 74 75 template<class Value> 76 bool rb_tree<Value>::insert(const Value& e) { 77 rb_ptr insert_ptr =_get_node(e); 78 if(head->parent ==head){ 79 head->parent=insert_ptr; 80 insert_ptr->parent=head; 81 insert_ptr->color=BLACK; 82 return true; 83 } 84 rb_ptr root_ptr=head->parent; 85 rb_ptr root_remember=nullptr; 86 while(root_ptr){ 87 root_remember=root_ptr; 88 if(link_type(insert_ptr)->data<=link_type(root_ptr)->data) 89 root_ptr=root_ptr->left; 90 else 91 root_ptr=root_ptr->right; 92 } 93 insert_ptr->parent=root_remember; 94 if(link_type(insert_ptr)->data <= link_type(root_remember)->data ) 95 root_remember->left=insert_ptr; 96 else if(link_type(insert_ptr)->data >link_type( root_remember)->data) 97 root_remember->right=insert_ptr; 98 bool ret =_insert_fix_up(insert_ptr); 99 return ret;100 }101 template<class Value>102 bool rb_tree<Value>::empty() const {103 104 return head->parent==head;105 }106 107 template<class Value>108 bool rb_tree<Value>::erase(const Value& e) {109 110 rb_ptr erase_ptr = find(e);111 112 if(!erase_ptr)113 114 return false;115 116 int erase_color =erase_ptr->color;117 118 rb_ptr fix_up_ptr=nullptr;119 120 rb_ptr fix_up_parent_ptr=nullptr;121 122 if(erase_ptr){123 124 if(!erase_ptr->left&&!erase_ptr->right){//叶子节点125 126 if(erase_ptr==erase_ptr->parent->left){127 128 erase_ptr->parent->left=nullptr;129 130 fix_up_parent_ptr= erase_ptr->parent;131 132 }133 134 if(erase_ptr==erase_ptr->parent->right){135 136 erase_ptr->parent->right=nullptr;137 138 fix_up_parent_ptr= erase_ptr->parent;139 140 }141 142 if(erase_ptr==head->parent){143 144 head->parent=head;145 146 fix_up_parent_ptr=head;147 148 }149 150 erase_color =erase_ptr->color;151 152 delete erase_ptr;153 154 }else if(erase_ptr->right){155 156 rb_ptr successor_ptr =_successor(erase_ptr);//left一定为空157 158 link_type(erase_ptr)->data=link_type(successor_ptr)->data;159 160 if(successor_ptr==successor_ptr->parent->left)161 162 successor_ptr->parent->left=successor_ptr->right;163 164 if(successor_ptr==successor_ptr->parent->right)165 166 successor_ptr->parent->right=successor_ptr->right;167 168 if(successor_ptr->right)169 170 successor_ptr->right->parent=successor_ptr->parent;171 172 173 174 fix_up_ptr=successor_ptr->right;175 176 fix_up_parent_ptr=successor_ptr->parent;177 178 erase_color=successor_ptr->color;179 180 delete successor_ptr;181 182 }else{//直接用左子树代替,或者找到后继节点代替也行,但比较麻烦,效果一样。183 184 if(erase_ptr ==erase_ptr->parent->left)185 186 erase_ptr->parent->left=erase_ptr->left;187 188 else189 190 erase_ptr->parent->right=erase_ptr->left;191 192 erase_ptr->left->parent=erase_ptr->parent;193 194 fix_up_ptr=erase_ptr->left;195 196 fix_up_parent_ptr=erase_ptr->parent;197 198 erase_color=erase_ptr->color;199 200 delete erase_ptr;201 202 }203 204 if(erase_color==BLACK)205 206 return _erase_fix_up(fix_up_ptr,fix_up_parent_ptr);207 208 }209 return false;210 }211 212 template<class Value>213 typename rb_tree<Value>::rb_ptr rb_tree<Value>::find(const Value& e) {214 215 rb_ptr root=head->parent;216 217 if(head->parent !=head){218 219 while(root){220 221 if(link_type(root)->data == e)222 223 return root;224 225 else if( e<=link_type(root)->data){226 227 root=root->left;228 229 }else230 231 root=root->right;232 233 }234 235 }236 return nullptr;237 }238 /**239 * current_ptr节点的祖父节点一定是黑色,因为它的父节点是红色的,所以性质4只在插入节点和该父节点被破坏240 * 情况1:叔节节点uncle_ptr是红色;241 * 1)父节点parent_ptr和叔节点uncle_ptr的颜色改为黑色,祖父节点grandfather_ptr的颜色改为红色242 * 2)把current_ptr节点设置为grandfather,因为只有祖父节点和祖父节点的父节点之间会违法性质。243 244 * 情况2:叔父节点uncle_ptr是黑色,或者unclue_ptr为空;245 246 * 1)根据根据当前节点的位置,把当前节点current_ptr设置为parent_ptr,对其左旋或右旋。247 248 * 情况3:叔父节点存在或者叔父节点颜色为黑色,且父右儿右关系(或父左儿左)249 250 1)把父节点颜色设为黑色,把祖父颜色设为红色251 252 2)对祖父节点进行左旋(或右旋)253 *254 */255 template<class Value>256 bool rb_tree<Value>:: _insert_fix_up(rb_ptr current_ptr){257 while(current_ptr->parent->color ==RED){258 259 rb_ptr parent_ptr =current_ptr->parent;260 rb_ptr grandfather_ptr=parent_ptr->parent;261 if(parent_ptr ==grandfather_ptr->left){262 rb_ptr uncle_ptr=parent_ptr->parent->right;263 if(uncle_ptr && uncle_ptr->color==RED){264 parent_ptr->color=BLACK;265 uncle_ptr->color=BLACK;266 grandfather_ptr->color=RED;267 current_ptr=grandfather_ptr;268 }else if(current_ptr ==parent_ptr->right){269 current_ptr=parent_ptr;270 _left_rotate(current_ptr);271 }else{272 273 current_ptr->parent->color=BLACK;274 current_ptr->parent->parent->color=RED;275 _right_rotate(current_ptr->parent->parent);276 277 }278 }else{279 rb_ptr uncle_ptr=parent_ptr->parent->left;280 if(uncle_ptr && uncle_ptr->color==RED){281 parent_ptr->color=BLACK;282 uncle_ptr->color=BLACK;283 grandfather_ptr->color=RED;284 current_ptr=grandfather_ptr;285 }else if(current_ptr ==parent_ptr->left){//uncle_ptr->color 是BLACK,或者uncle_ptr为空286 current_ptr=parent_ptr;287 _right_rotate(current_ptr);//其实就是转换为父右儿右的情况288 }else{//父右儿右289 290 current_ptr->parent->color=BLACK;291 current_ptr->parent->parent->color=RED;292 _left_rotate(current_ptr->parent->parent);293 294 }295 }296 }297 head->parent->color=BLACK;298 return true;299 }300 301 template<class Value>302 303 bool rb_tree<Value>::_erase_fix_up(rb_ptr current_ptr,rb_ptr parent_ptr){304 305 while((!current_ptr||current_ptr->color==BLACK)&¤t_ptr!=head->parent){306 307 if(parent_ptr->left ==current_ptr){308 309 rb_ptr brother_ptr = parent_ptr->right;310 311 if(brother_ptr->color ==RED){312 313 parent_ptr->color=RED;314 315 brother_ptr->color=BLACK;316 317 _left_rotate(brother_ptr);318 319 brother_ptr=current_ptr->parent->right;320 321 }322 323 if(brother_ptr->color==BLACK &&324 325 (!brother_ptr->left ||brother_ptr->left->color ==BLACK)&&326 327 (!brother_ptr->right || brother_ptr->right->color ==BLACK)){328 329 brother_ptr->color=RED;330 331 current_ptr=parent_ptr;332 333 parent_ptr=current_ptr->parent;334 335 }else {336 337 if(brother_ptr->color==BLACK &&338 339 (!brother_ptr->right||brother_ptr->right->color==BLACK)){//右侄黑,左侄红340 341 342 343 brother_ptr->left->color=BLACK;344 345 brother_ptr->color=RED;346 347 _right_rotate(brother_ptr);348 349 brother_ptr=parent_ptr->right;350 351 }//右侄红色352 353 brother_ptr->color=parent_ptr->color;354 355 parent_ptr->color=BLACK;356 357 if(brother_ptr->right)358 359 brother_ptr->right->color=BLACK;360 361 _left_rotate(parent_ptr);362 363 current_ptr=head->parent;364 365 }366 367 }else{368 369 rb_ptr brother_ptr = parent_ptr->left;370 371 if(brother_ptr->color ==RED){372 373 parent_ptr->color=RED;374 375 brother_ptr->color=BLACK;376 377 _right_rotate(brother_ptr);378 379 brother_ptr=current_ptr->parent->left;380 381 }382 383 if(brother_ptr->color==BLACK &&384 385 (!brother_ptr->left ||brother_ptr->left->color ==BLACK)&&386 387 (!brother_ptr->right || brother_ptr->right->color ==BLACK)){388 389 brother_ptr->color=RED;390 391 current_ptr=parent_ptr;392 393 parent_ptr=current_ptr->parent;394 395 }else {396 397 if(brother_ptr->color==BLACK &&398 399 (!brother_ptr->right||brother_ptr->right->color==BLACK)){//右侄黑,左侄红400 401 brother_ptr->left->color=BLACK;402 403 brother_ptr->color=RED;404 405 _left_rotate(brother_ptr);406 407 brother_ptr=parent_ptr->left;408 409 }//右侄红色410 411 brother_ptr->color=parent_ptr->color;412 413 parent_ptr->color=BLACK;414 415 if(brother_ptr->left)416 417 brother_ptr->left->color=BLACK;418 419 _right_rotate(parent_ptr);420 421 current_ptr=head->parent;422 423 }424 425 }426 427 }428 429 if (current_ptr)430 431 current_ptr->color=BLACK;432 433 return true;434 435 }436 437 template<class Value>438 439 typename rb_tree<Value>::rb_ptr rb_tree<Value>::_successor(rb_ptr current_ptr) const{440 441 rb_ptr right_child_ptr = current_ptr->right;442 443 if(right_child_ptr){444 445 rb_ptr left_ptr =right_child_ptr->left;446 447 rb_ptr left_remember_ptr;448 449 if(left_ptr){450 451 while(left_ptr){452 453 left_remember_ptr =left_ptr;454 455 left_ptr=left_ptr->left;456 457 }458 459 return left_remember_ptr;460 461 }462 463 return right_child_ptr;464 465 466 467 }else{468 469 rb_ptr parent_ptr=current_ptr->parent;470 471 while(current_ptr ==parent_ptr->right){472 473 current_ptr=parent_ptr;474 475 parent_ptr=parent_ptr->parent;476 477 }478 479 return parent_ptr;480 481 }482 483 return nullptr;484 485 }486 template<class Value>487 typename rb_tree<Value>::rb_ptr rb_tree<Value>::_get_node(const Value& e) const {488 rb_ptr insert_ptr = new tree_node();489 link_type(insert_ptr)->data=e;490 insert_ptr->parent=nullptr;491 insert_ptr->left=nullptr;492 insert_ptr->right=nullptr;493 insert_ptr->color=RED;494 return insert_ptr;495 }496 template<class Value>497 bool rb_tree<Value>::_right_rotate(rb_ptr root){498 if(root->left!=nullptr){499 rb_ptr left_child_ptr=root->left;500 501 root->left=left_child_ptr->right;502 if(left_child_ptr->right !=nullptr)503 left_child_ptr->right->parent=root;504 505 left_child_ptr->right=root;506 left_child_ptr->parent=root->parent;507 if(root->parent->left ==root)508 root->parent->left=left_child_ptr;509 else if(root->parent->right==root)510 root->parent->right=left_child_ptr;511 512 if(root->parent==head){513 514 root->parent->parent=left_child_ptr;515 516 }517 518 root->parent=left_child_ptr;519 return true;520 }521 return false;522 }523 template<class Value>524 bool rb_tree< Value >::_left_rotate(rb_ptr root){525 if(root->right!=nullptr){526 rb_ptr right_child_ptr=root->right;527 528 root->right=right_child_ptr->left;529 if(right_child_ptr->left != nullptr)530 right_child_ptr->left->parent=root;531 532 right_child_ptr->left=root;533 right_child_ptr->parent=root->parent;534 if(root->parent->left ==root)535 root->parent->left=right_child_ptr;536 else if(root->parent->right ==root)537 root->parent->right=right_child_ptr;538 539 if(root->parent==head){540 541 root->parent->parent=right_child_ptr;542 543 }544 root->parent=right_child_ptr;545 546 return true;547 }548 return false;549 }550 template<class Value>551 void rb_tree<Value>::levelOrder() const {552 rb_ptr root =head->parent;553 queue<rb_ptr> q;554 if(head->parent !=head){555 q.push(root);556 while(!q.empty()){557 rb_ptr visit_ptr = q.front();558 cout<<"data: "<<link_type(visit_ptr)->data<<" color: "<<((visit_ptr->color==0)?"RED":"BLACK")<<endl;559 if(visit_ptr->left)560 q.push(visit_ptr->left);561 if(visit_ptr->right)562 q.push(visit_ptr->right);563 q.pop();564 }565 }566 }567 template<class Value>568 void rb_tree<Value>:: _preOrder(rb_ptr root) const{569 if(root){570 cout<<"data: "<<link_type(root)->data<<" color: "571 572 <<((root->color==0)?"RED":"BLACK")<<endl;573 _preOrder(root->left);574 _preOrder(root->right);575 }576 }577 template<class Value>578 void rb_tree<Value>:: preOrder() const{579 _preOrder(head->parent);580 }581 }582 583 584 //#include "rbtree.cpp"585 #endif /* SRC_RBTREE_H_ */
阅读全文
0 0
- 红黑树C实现
- 红黑树<C语言实现>
- 红黑树C语言实现
- 红黑树-C语言实现
- 红黑树的C实现
- 红黑树(c实现)
- C语言实现红黑树
- 红黑树与C实现算法 - RedBlackTree.c
- 高效实现红黑树的插入--c实现
- 红黑树的实现(C++)
- 红黑树的一个C实现
- 红黑树及C语言实现
- 红黑树实现文件C语言
- 红黑树与C实现算法
- 红黑树的插入C实现
- 红黑树的c语言实现
- C/C++: 实现加减乘除。
- C实现C(3)
- Android 属性(attr)引用
- 排序之快速排序
- NOI2017退役记
- caffe框架研究(一)
- java foreach与for速度比较
- 红黑树C++实现
- 排序之归并排序
- java小算法—判断一个数是否为质数
- Git 使用规范流程
- 最强lvs总结
- c语言学习笔记-控制流-郝斌老师讲解
- 迷茫时的感想
- Http服务器实现文件上传与下载(五)
- Linux学习之端口被占用查询方法详解