1. #include <memory>
  2.  
  3. template<class T>
  4. struct rb_node
  5. {
  6. T key;
  7. bool color;//true red | false black
  8. std::shared_ptr<rb_node> lchild, rchild, parent;
  9.  
  10. rb_node(T key, bool color = true, std::shared_ptr<rb_node> lchild = nullptr,
  11. std::shared_ptr<rb_node> rchild = nullptr, std::shared_ptr<rb_node> parent = nullptr)
  12. :key(key)//此处不能使用this:现在对象还没被构建起来
  13. {
  14. //赋值,初始化在初始化列表中执行
  15. this->color = color;
  16. this->lchild = lchild;
  17. this->rchild = rchild;
  18. this->parent = parent;
  19. }
  20. };
  21.  
  22. template<class T>
  23. class rb_tree
  24. {
  25. private:
  26. std::shared_ptr<rb_node<T>> root;
  27. std::shared_ptr<rb_node<T>> nil;//叶节点
  28. void left_rotation(std::shared_ptr<rb_node<T>> a)
  29. {
  30. if (a == nullptr) return;
  31. std::shared_ptr<rb_node<T>> b = a->rchild;
  32. if (b == nullptr) return;
  33. if (b->lchild != nullptr)
  34. b->lchild->parent = a;
  35. a->rchild = b->lchild;
  36.  
  37. if (a->parent == nil)
  38. root = b;//rbtree的root以nil为父节点
  39. else
  40. {
  41. if (a->parent->lchild == a)
  42. a->parent->lchild = b;
  43. else
  44. a->parent->rchild = b;
  45. }
  46. b->parent = a->parent;
  47.  
  48. b->lchild = a;
  49. a->parent = b;
  50. }
  51. void right_rotation(std::shared_ptr<rb_node<T>> a)
  52. {
  53. if (a == nullptr) return;
  54. std::shared_ptr<rb_node<T>> b = a->lchild;
  55. if (b == nullptr) return;
  56. if (b->rchild != nullptr)
  57. b->rchild->parent = a;
  58. a->lchild = b->rchild;
  59.  
  60. if (a->parent == nil)
  61. root = b;
  62. else
  63. {
  64. if (a->parent->lchild == a)
  65. a->parent->lchild = b;
  66. else
  67. a->parent->rchild = b;
  68. }
  69. b->parent = a->parent;
  70.  
  71. b->rchild = a;
  72. a->parent = b;
  73. }
  74.  
  75. public:
  76. rb_tree()
  77. {
  78. root = nullptr;
  79. T key;
  80. nil = std::make_shared<rb_node<T>>(key, false);
  81. }
  82. void insert(T key)
  83. {
  84. std::shared_ptr<rb_node<T>> tmp = std::make_shared<rb_node<T>>(key, true, nil, nil, nil);
  85. std::shared_ptr<rb_node<T>> ptr = root;
  86.  
  87. //情况1:树为空
  88. if (ptr == nullptr)
  89. {
  90. tmp->color = false;
  91. root = tmp;
  92. return;
  93. }
  94. while (true)
  95. {
  96. if (key <= ptr->key)
  97. {
  98. if (ptr->lchild == nil) break;
  99. ptr = ptr->lchild;
  100. }
  101. else
  102. {
  103. if (ptr->rchild == nil) break;
  104. ptr = ptr->rchild;
  105. }
  106. }
  107.  
  108. if (key <= ptr->key)
  109. ptr->lchild = tmp;
  110. else
  111. ptr->rchild = tmp;
  112. tmp->parent = ptr;
  113.  
  114. while(true)
  115. {
  116. if (ptr == nil)//注意root可能被情况三修改为red,记得加特判
  117. {
  118. tmp->color = false;
  119. root = tmp;
  120. return;
  121. }
  122.  
  123. //情况2:插入节点的父节点为黑色
  124. if (!ptr->color) return;
  125.  
  126. /*情况3:插入节点的父节点和叔节点都存在且都为红色*/
  127. if (ptr->parent->lchild->color && ptr->parent->rchild->color)
  128. {
  129. ptr->parent->color = true;
  130. ptr->parent->lchild->color = false;
  131. ptr->parent->rchild->color = false;
  132.  
  133. tmp = ptr->parent;
  134. ptr = tmp->parent;
  135. continue;
  136. }
  137. if (ptr->parent->lchild == ptr)
  138. {
  139. //情况4:右旋
  140. if (tmp == ptr->lchild)
  141. {
  142. ptr->parent->color = true;
  143. ptr->color = false;
  144. right_rotation(ptr->parent);
  145. return;
  146. }
  147. else
  148. {
  149. //情况5:左旋 + 右旋
  150. left_rotation(ptr);
  151. tmp = ptr;
  152. ptr = tmp->parent;
  153. continue;
  154. }
  155. }
  156. else
  157. {
  158. //情况4:左旋
  159. if (tmp == ptr->rchild)
  160. {
  161. ptr->parent->color = true;
  162. ptr->color = false;
  163. left_rotation(ptr->parent);
  164. return;
  165. }
  166. else
  167. {
  168. //情况5:右旋+左旋
  169. right_rotation(ptr);
  170. tmp = ptr;
  171. ptr = tmp->parent;
  172. continue;
  173. }
  174. }
  175. }
  176. }
  177. void earse(T key)
  178. {
  179. //待续
  180. }
  181. };

平衡树之RB-tree的更多相关文章

  1. 红黑树(R-B Tree)

    R-B Tree简介 R-B Tree,全称是Red-Black Tree,又称为“红黑树”,它一种特殊的二叉查找树.红黑树的每个节点上都有存储位表示节点的颜色,可以是红(Red)或黑(Black). ...

  2. R-B Tree

    1.简介 R-B Tree,全称Red-Black Tree,又称为"红黑树",为一种自平衡二叉查找树(特殊的平衡二叉树,都是在插入和删除操作时通过特定操作保持二叉树的平衡,从而获 ...

  3. bzoj3223 Tyvj 1729 文艺平衡树(Splay Tree+区间翻转)

    3223: Tyvj 1729 文艺平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2202  Solved: 1226[Submit][Sta ...

  4. 3224: Tyvj 1728 普通平衡树(finger tree)

    3224: Tyvj 1728 普通平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 19122  Solved: 8359[Submit][St ...

  5. 重学数据结构系列之——平衡树之SB Tree(Size Blanced Tree)

    学习来源:计蒜客 平衡树 1.定义 对于每一个结点.左右两个子树的高度差的绝对值不超过1,或者叫深度差不超过1 为什么会出现这样一种树呢? 假如我们依照1-n的顺序插入到二叉排序树中,那么二叉排序树就 ...

  6. 红黑树(RB Tree)

    看到一篇很好的文章 文章来源:http://www.360doc.com/content/15/0730/00/14359545_488262776.shtml 红黑树是一种高效的索引树,多于用关联数 ...

  7. java数据结构——红黑树(R-B Tree)

    红黑树相比平衡二叉树(AVL)是一种弱平衡树,且具有以下特性: 1.每个节点非红即黑; 2.根节点是黑的; 3.每个叶节点(叶节点即树尾端NULL指针或NULL节点)都是黑的; 4.如图所示,如果一个 ...

  8. 树-红黑树(R-B Tree)

    红黑树概念 特殊的二叉查找树,每个节点上都有存储位表示节点的颜色是红(Red)或黑(Black).时间复杂度是O(lgn),效率高. 特性: (1)每个节点或者是黑色,或者是红色. (2)根节点是黑色 ...

  9. 关于红黑树(R-B tree)原理,看这篇如何

    学过数据数据结构都知道二叉树的概念,而又有多种比较常见的二叉树类型,比如完全二叉树.满二叉树.二叉搜索树.均衡二叉树.完美二叉树等:今天我们要说的红黑树就是就是一颗非严格均衡的二叉树,均衡二叉树又是在 ...

  10. [转]SGI STL 红黑树(Red-Black Tree)源代码分析

    STL提供了许多好用的数据结构与算法,使我们不必为做许许多多的重复劳动.STL里实现了一个树结构-Red-Black Tree,它也是STL里唯一实现的一个树状数据结构,并且它是map, multim ...

随机推荐

  1. Generational GC (Part one )

    目录 什么是分代垃圾回收 对象对的年龄 新生代对象和老年对象 Ungar的分带垃圾回收 堆的结构 记录集 写入屏障 对象的结构 分配 新生代GC 幸存空间沾满了怎么办? 老年代GC 优缺点 吞吐量得到 ...

  2. python 基础使用list、dict、set、可变与不可变对象

    参考链接:https://www.liaoxuefeng.com/wiki/1016959663602400/1017104324028448 dict是字典,可以储存键值对类型的值,set与dict ...

  3. hihoCoder #1127 : 二分图二·二分图最小点覆盖和最大独立集

    #1127 : 二分图二·二分图最小点覆盖和最大独立集 Time Limit:10000ms Case Time Limit:1000ms Memory Limit:256MB 描述 在上次安排完相亲 ...

  4. js插件---图片懒加载lazyload

    js插件---图片懒加载lazyload 一.总结 一句话总结:使用异常简单,src里面放加载的图片,data-original里面放原图片,不懂的位置去官网或者github找API就好. 1.laz ...

  5. base64格式的图片数据如何转成图片

    base64格式的图片数据如何转成图片 一.总结 一句话总结:不仅要去掉前面的格式串,还需要base64_decode()解码才行. // $base_img是获取到前端传递的值 $base_img ...

  6. 如何保证对象线程内唯一:数据槽(CallContext)

    CallContext 是类似于方法调用的线程本地存储区的专用集合对象,并提供对每个逻辑执行线程都唯一的数据槽.数据槽不在其他逻辑线程上的调用上下文之间共享.当 CallContext 沿执行代码路径 ...

  7. SQL中NUMERIC和DECIMAL的区别

    numeric 和 decimal 数据类型的默认最大精度值是 38.在 Transact-SQL 中,numeric 与 decimal 数据类型在功能上等效. decimal(numeric ) ...

  8. Fedora27 安装Adobe Flash Player PPAPI与NPAPI实现Firefox和Chromium视频播放

    一.Adobe Flash Player PPAPI与NPAPI有什么区别我们在打开网页视频时有时会弹出没有安装Flash插件的提示,此时就无法观看视频.Adobe Flash Player是浏览器显 ...

  9. angularCli打包遇到的一些问题

    有时在运行项目或者打包项目的时候会遇到报错信息:found version 4, expected 3, 这个大概意思是说该插件需要的依赖当前不支持,需要提高依赖的版本. 比如:@angular/co ...

  10. stat---显示文件的状态信息

    stat命令用于显示文件的状态信息.stat命令的输出信息比ls命令的输出信息要更详细. 语法 stat(选项)(参数) 选项 -L:支持符号连接: -f:显示文件系统状态而非文件状态: -t:以简洁 ...