红黑树C++实现

- 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 else
- 189
- 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 }else
- 230
- 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_ */

红黑树C++实现的更多相关文章
- 红黑树——算法导论(15)
1. 什么是红黑树 (1) 简介 上一篇我们介绍了基本动态集合操作时间复杂度均为O(h)的二叉搜索树.但遗憾的是,只有当二叉搜索树高度较低时,这些集合操作才会较快:即当树的高度较高(甚至一种极 ...
- jdk源码分析红黑树——插入篇
红黑树是自平衡的排序树,自平衡的优点是减少遍历的节点,所以效率会高.如果是非平衡的二叉树,当顺序或逆序插入的时候,查找动作很可能会遍历n个节点 红黑树的规则很容易理解,但是维护这个规则难. 一.规则 ...
- 谈c++ pb_ds库(二) 红黑树大法好
厉害了,没想到翻翻pb_ds库看到这么多好东西,封装好的.现成的splay.红黑树.avl... 即使不能在考场上使用也可以用来对拍哦 声明/头文件 #include <ext/pb_ds/tr ...
- 定时器管理:nginx的红黑树和libevent的堆
libevent 发生超时后, while循环一次从堆顶del timer——直到最新调整的最小堆顶不是超时事件为止,(实际是del event),但是会稍后把这个timeout的 event放到ac ...
- 从2-3-4树到红黑树(下) Java与C的实现
欢迎探讨,如有错误敬请指正 如需转载,请注明出处 http://www.cnblogs.com/nullzx/ 相关博客: 从2-3-4树到红黑树(上) 从2-3-4树到红黑树(中) 1. 实现技 ...
- 红黑树/B+树/AVL树
RB Tree 红黑树 :http://blog.csdn.net/very_2/article/details/5722682 Nginx的RBTree实现 :http://blog.csdn ...
- 论AVL树与红黑树
首先讲解一下AVL树: 例如,我们要输入这样一串数字,10,9,8,7,15,20这样一串数字来建立AVL树 1,首先输入10,得到一个根结点10 2,然后输入9, 得到10这个根结点一个左孩子结点9 ...
- DataStructure——红黑树学习笔记
1.前言 本文伪码和解释参考: http://blog.csdn.net/v_JULY_v/article/details/6105630 C实现的源码本文未贴出,请见: http://blog.cs ...
- 红黑树(Red-Black tree)
红黑树又称红-黑二叉树,它首先是一颗二叉树,它具体二叉树所有的特性.同时红黑树更是一颗自平衡的排序二叉树.我们知道一颗基本的二叉树他们都需要满足一个基本性质–即树中的任何节点的值大于它的左子节点,且小 ...
- map,hash_map, hash_table, 红黑树 的原理和使用
在刷算法题的时候总是碰到好多题,号称可以用hash table来解题.然后就蒙圈了. 1.首先,map和hash_map的区别和使用: (1)map底层用红黑树实现,hash_map底层用hash_t ...
随机推荐
- 键盘enter按钮出发登陆事件
$("#nameInput").focus();$(".txtUserName").keydown(function (event) { if (event.k ...
- jquery.flexslider-min.js实现banner轮播图效果
实现方法 引用jQuery和flexslider.js到你的页面 <script type="text/javascript" src="js/jquery-1.7 ...
- Windows 环境下分布式跨域Session共享
为什么还是那句话,在网上找了N篇Session共享,但真正可以直接解决问题的还是没有找到. 一.以下为本人亲测,为防止环境不一致,对本文产生歧义,限定环境如下: 1. IIS7.0 2. Asp.ne ...
- asp.net生成视图时报错 未引用System.Runtime, Version...
这是没有添加程序集引用 在程序集中添加一条引用 <compilation debug="true" targetFramework="4.5.1"> ...
- Android studio 使用心得(三)—从Eclipse迁移到Android studio
断断续续的也算是把eclipse上的代码成功迁移到android studio上来了,现在,我同事继续用eclipse,我用android studio,svn上还是之前eclipse的项目,迁移成功 ...
- How to fix Cannot change version of project facet Dynamic Web Module to 3.0 Error in Eclipse---转载
How to fix Cannot change version of project facet Dynamic Web Module to 3.0 Error in Eclipse 原文:http ...
- MySQL监控脚本
zabbix监控mysql时自定key用到的脚本 #!/usr/bin/env python #-*- coding: UTF-8 -*- from __future__ import print_f ...
- windows server 2008 桌面图标
1.开始-->"搜索"-->"icon"-->"显示桌面通用图标"
- 【JavaScript】一个同步于本地时间的动态时间
这样例很easy.了解JavaScript之后就是几行的代码便可以完毕的事情. 可是对于一些未接触过JavaScript的人来说,差点儿非常大project的样子.然后在网上苦苦寻觅代码,之后在茫茫的 ...
- THINKPHP3.2视频教程
http://edu.51cto.com/lesson/id-24504.html lunix视频教程 http://bbs.lampbrother.net/read-htm-tid-161465.h ...