1. //RB_Tree.hpp
  2. //The code of red black trees
  3. //2011/12/31 by Adoo
  4. // The foundation :http://www.roading.org/?p=691
  5.  
  6. #ifndef RB_TREES_HPP
  7. #define RB_TREES_HPP
  8. #include<iterator>
  9. #include<iomanip>
  10. #include<deque>
  11. enum RB_Color{
  12. red,
  13. black
  14. };
  15. template<typename Type>
  16. class RB_Tree{
  17. private:
  18. struct rb_node;
  19. class node_iterator;
  20. public:
  21. typedef node_iterator iterator;
  22. typedef const node_iterator const_iterator;
  23.  
  24. RB_Tree(){
  25. _nil->_color=black;
  26. _root=_nil;
  27. };
  28. ~RB_Tree()
  29. {
  30. for(iterator iter=begin(); iter !=end();)
  31. {
  32. eraser(iter++);
  33. }
  34. _root=_nil;
  35. }
  36. iterator begin(){
  37. return sub_min(_root);
  38. }
  39. iterator end(){
  40. return iterator(_nil);
  41. }
  42. static iterator sub_min(iterator iter){
  43. rb_node *min=iter.pointer();
  44. while(min->_left !=_nil)
  45. {
  46. min=min->_left;
  47. }
  48. return min;
  49. }
  50. iterator insert(Type value){
  51. rb_node *y=_nil;
  52. rb_node *z=new rb_node; //create a node by the value
  53. //needn't set the z's color ,because red is rb_node's default color
  54. z->_value=value;
  55. z->_left=_nil;
  56. z->_right=_nil;
  57.  
  58. rb_node* x=_root; //x iterator from _root
  59. while(x !=_nil )
  60. {
  61. y=x;
  62. if(x->_value< z->_value)
  63. x=x->_right;
  64. else
  65. x=x->_left;
  66. }
  67. z->_parent=y;
  68. if(y==_nil) //determine z should be y's left or right
  69. _root=z;
  70. else
  71. if(y->_value < z->_value)
  72. y->_right=z;
  73. else
  74. y->_left=z;
  75.  
  76. rb_insert_fixup(z); //restore the red black properties
  77. return z;
  78. }
  79. iterator eraser(iterator iter){
  80. rb_node* z=iter.pointer();
  81. rb_node* y=z;
  82. RB_Color y_color=y->_color;
  83. rb_node *x=NULL;
  84.  
  85. if(z->_left==_nil ){ //case1: z's left child is nil
  86. x=z->_right;
  87. transplant(z, z->_right);
  88. }
  89. else{
  90. if(z->_right==_nil){// case2: z's right child is nil
  91. x=z->_left;
  92. transplant(z, z->_left);
  93. }
  94. else{//case3: both children of z are not nil
  95. y=sub_min(z->_right).pointer();
  96. y_color=y->_color;
  97. x=y->_right;
  98. if(y->_parent==z)
  99. x->_parent=y;
  100. else{
  101. transplant(y, y->_right);
  102. //link z's right subtree into y, only y isn't z's child;
  103. y->_right=z->_right;
  104. y->_right->_parent=y;
  105. }
  106. transplant(z, y);
  107. //link z's subtree into y.
  108. y->_left=z->_left;
  109. y->_left->_parent=y;
  110. y->_color=z->_color;
  111. }
  112. }
  113. iterator result = ++iterator(z);
  114. delete z;
  115. if(y_color==black)
  116. eraser_fixup(x);
  117. return result;
  118. };
  119.  
  120. private:
  121. void transplant(rb_node *u, rb_node *v){
  122. if(u->_parent == _nil)
  123. {
  124. _root=v;
  125. }
  126. else
  127. if(u== u->_parent->_left)
  128. u->_parent->_left=v;
  129. else
  130. u->_parent->_right=v;
  131. v->_parent=u->_parent;
  132. };
  133. void left_rotate(rb_node *x){
  134. rb_node* y=x->_right; //set y
  135. x->_right=y->_left; //turn y's left subtree into x's right subtree
  136. if(y->_left !=_nil)
  137. y->_left->_parent=x;
  138. y->_parent=x->_parent; //link y to x's parent
  139. if(x->_parent != _nil )
  140. {
  141. if(x->_parent->_left==x)
  142. x->_parent->_left=y;
  143. else
  144. x->_parent->_right=y;
  145. }
  146. else
  147. _root=y;
  148. y->_left=x; //put x on y's left
  149. x->_parent=y;
  150. }
  151. void right_rotate(rb_node *x)
  152. {
  153. rb_node* y=x->_left; //set y;
  154. x->_left=y->_right; //turn y's right subtree into x's left subtree
  155. if(y->_right != _nil)
  156. y->_right->_parent=x;
  157. y->_parent=x->_parent; //link y to x's parent
  158. if(x->_parent != _nil)
  159. {
  160. if(x==x->_parent->_left)
  161. x->_parent->_left=y;
  162. else
  163. x->_parent->_right=y;
  164. }
  165. else
  166. _root=y;
  167. y->_right=x; //put x on y's right;
  168. x->_parent=y;
  169. }
  170. void rb_insert_fixup(rb_node* z){
  171. while(z->_parent->_color==red){
  172. if(z->_parent==z->_parent->_parent->_left){
  173. rb_node* y=z->_parent->_parent->_right;
  174. if(y->_color==red){
  175. z->_parent->_color=black;
  176. y->_color=black;
  177. z->_parent->_parent->_color=red;
  178. z=z->_parent->_parent;
  179. }
  180. else{
  181. if(z==z->_parent->_right){
  182. z=z->_parent;
  183. left_rotate(z);
  184. }
  185. z->_parent->_color=black;
  186. z->_parent->_parent->_color=red;
  187. right_rotate(z->_parent->_parent);
  188. }
  189. }
  190. else{
  191. rb_node* y=z->_parent->_parent->_left;
  192. if(y->_color==red){
  193. z->_parent->_color=black;
  194. y->_color=black;
  195. z->_parent->_parent->_color=red;
  196. z=z->_parent->_parent;
  197. }
  198. else{
  199. if(z==z->_parent->_left){
  200. z=z->_parent;
  201. right_rotate(z);
  202. }
  203. z->_parent->_color=black;
  204. z->_parent->_parent->_color=red;
  205. left_rotate(z->_parent->_parent);
  206. }
  207. }
  208. }
  209. _root->_color=black;
  210. };;
  211. void eraser_fixup(rb_node* x){
  212. while(x != _root && x->_color ==black){
  213. if(x==x->_parent->_left){
  214. rb_node* w=x->_parent->_right;
  215. if(w->_color == red){ //case 1: x's sbling w is red.
  216. x->_parent->_color=red;
  217. w->_color=black;
  218. left_rotate(x->_parent); //convert case 1 to case 2.
  219. }
  220. else{//case 2 : x's sbling w is black.
  221. if(w->_left->_color == black && w->_right->_color == black){
  222. //case 2.1 : both children of w are black
  223. w->_color=red;
  224. x=x->_parent;
  225. }
  226. else{
  227. if(w->_left->_color==red && w->_right->_color==black){
  228. //case 2.2: w's left child is red and w's right child is black.
  229. //we convert this case to case 2.3.
  230. w->_left->_color=black;
  231. w->_color=red;
  232. right_rotate(w);
  233. w=x->_parent->_right;
  234. }
  235. //case 2.3: w's right child is red;
  236. w->_color=x->_parent->_color;
  237. w->_parent->_color=black;
  238. w->_right->_color= black;
  239. left_rotate(x->_parent);
  240. x=_root; //terminate the loop;
  241. }
  242. }
  243. }
  244. else{
  245. rb_node* w=x->_parent->_right;
  246. if(w->_color == red){
  247. x->_parent->_color=red;
  248. w->_color=black;
  249. left_rotate(x->_parent);
  250. }
  251. else{
  252. if(w->_right->_color == black && w->_left->_color == black){
  253. w->_color=red;
  254. x=x->_parent;
  255. }
  256. else{
  257. if(w->_right->_color==red && w->_left->_color == black){
  258. w->_right->_color=black;
  259. w->_color=red;
  260. left_rotate(w);
  261. w=x->_parent->_left;
  262. }
  263. w->_color=x->_parent->_color;
  264. w->_parent->_color=black;
  265. w->_left->_color= black;
  266. right_rotate(x->_parent);
  267. x=_root; //terminate the loop;
  268. }
  269. }
  270. }
  271. }
  272. x->_color=black;
  273. };
  274.  
  275. private:
  276. rb_node* _root;
  277. public:
  278. static rb_node* _nil;
  279. };
  280.  
  281. template<typename Type>
  282. struct RB_Tree<Type>::rb_node
  283. {
  284. Type _value;
  285. rb_node *_left;
  286. rb_node *_right;
  287. rb_node *_parent;
  288. RB_Color _color;
  289. rb_node()
  290. :_value(Type()),_left(NULL),_right(NULL),_parent(NULL),_color(red)
  291. {};
  292. };
  293.  
  294. template<typename Type>
  295. class RB_Tree<Type>::node_iterator:
  296. public std::iterator<std::bidirectional_iterator_tag ,rb_node>
  297. {
  298. public:
  299. node_iterator(rb_node* n): _node(n){};
  300.  
  301. Type& operator* () const{
  302. return _node->_value;
  303. };
  304.  
  305. rb_node* operator ->()const
  306. {
  307. return _node;
  308. };
  309.  
  310. node_iterator operator++ ()
  311. {
  312. if(_node==RB_Tree<Type>::_nil)
  313. return _node;
  314. if(_node->_right!=RB_Tree<Type>::_nil)
  315. {
  316. *this=RB_Tree<Type>::sub_min(_node->_right);
  317. }
  318. else
  319. {
  320. rb_node *parent=_node->_parent;
  321. while(parent !=RB_Tree<Type>::_nil&& _node==parent->_right)
  322. {
  323. _node=parent;
  324. parent=parent->_parent;
  325. }
  326. _node=parent;
  327. }
  328. return *this;
  329. }
  330.  
  331. node_iterator operator++(int){
  332. node_iterator ret(*this);
  333. ++*this;
  334. return ret;
  335. }
  336.  
  337. bool operator ==( node_iterator r_iter)
  338. {
  339. return _node == r_iter._node;
  340. };
  341.  
  342. bool operator !=( node_iterator r_iter){
  343. return _node != r_iter._node;
  344. }
  345.  
  346. rb_node* pointer()
  347. {
  348. return _node;
  349. }
  350. private:
  351. rb_node* _node;
  352. };
  353. #endif
  354. //各种

转载自:http://www.roading.org/algorithm/introductiontoalgorithm/c%E5%AE%9E%E7%8E%B0%E7%BA%A2%E9%BB%91%E6%A0%91%EF%BC%8C%E4%BB%BFstl%E5%B0%81%E8%A3%85.html

C++实现红黑树,仿STL封装的更多相关文章

  1. stl vector、红黑树、set、multiset、map、multimap、迭代器失效、哈希表(hash_table)、hashset、hashmap、unordered_map、list

    stl:即标准模板库,该库包含了诸多在计算机科学领域里所常用的基本数据结构和基本算法 六大组件: 容器.迭代器.算法.仿函数.空间配置器.迭代适配器 迭代器:迭代器(iterator)是一种抽象的设计 ...

  2. stl map底层之红黑树插入步骤详解与代码实现

    转载注明出处:http://blog.csdn.net/mxway/article/details/29216199 本篇文章并没有详细的讲解红黑树各方面的知识,只是以图形的方式对红黑树插入节点需要进 ...

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

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

  4. SGI STL红黑树中迭代器的边界值分析

    前言 一段程序最容易出错的就是在判断或者是情况分类的边界地方,所以,应该对于许多判断或者是情况分类的边界要格外的注意.下面,就分析下STL中红黑树的迭代器的各种边界情况.(注意:分析中STL使用的版本 ...

  5. 【stl学习笔记】红黑树

    转自维基百科 红黑树是一种平衡二叉搜索树,它可以在O(log n)时间内做查找,插入和删除,这里的n是树中元素的数目. 性质: 红黑树是每个节点都带有颜色属性的二叉查找树,颜色为红色或黑色.在二叉查找 ...

  6. 浅谈算法和数据结构: 七 二叉查找树 八 平衡查找树之2-3树 九 平衡查找树之红黑树 十 平衡查找树之B树

    http://www.cnblogs.com/yangecnu/p/Introduce-Binary-Search-Tree.html 前文介绍了符号表的两种实现,无序链表和有序数组,无序链表在插入的 ...

  7. 谈c++ pb_ds库(二) 红黑树大法好

    厉害了,没想到翻翻pb_ds库看到这么多好东西,封装好的.现成的splay.红黑树.avl... 即使不能在考场上使用也可以用来对拍哦 声明/头文件 #include <ext/pb_ds/tr ...

  8. 论AVL树与红黑树

    首先讲解一下AVL树: 例如,我们要输入这样一串数字,10,9,8,7,15,20这样一串数字来建立AVL树 1,首先输入10,得到一个根结点10 2,然后输入9, 得到10这个根结点一个左孩子结点9 ...

  9. map,hash_map, hash_table, 红黑树 的原理和使用

    在刷算法题的时候总是碰到好多题,号称可以用hash table来解题.然后就蒙圈了. 1.首先,map和hash_map的区别和使用: (1)map底层用红黑树实现,hash_map底层用hash_t ...

随机推荐

  1. 安装MongoDB -- Windows平台

    1. 安装MongoDB 2. 添加环境变量 将安装后的bin目录,添加至系统的Path环境变量中,例如我的安装路径为"C:\Program Files\MongoDB\Server\3.2 ...

  2. 查看线程linux cpu使用率

    Linux下如何查看高CPU占用率线程 LINUX CPU利用率计算 转 http://www.cnblogs.com/lidabo/p/4738113.html目录(?)[-] proc文件系统 p ...

  3. Huffman树及其应用

    哈夫曼树又称为最优二叉树,哈夫曼树的一个最主要的应用就是哈夫曼编码,本文通过简单的问题举例阐释哈夫曼编码的由来,并用哈夫曼树的方法构造哈夫曼编码,最终解决问题来更好的认识哈夫曼树的应用--哈夫曼编码. ...

  4. Adatper中获取宽高为0的问题

    但是我们想在getView()中获取ImageView的宽和高存在问题,在getView()里面刚开始显示item的时候利用ImageView.getWidth() 获取的都是0,为什么刚开始获取不到 ...

  5. 关于开发环境 git 重新部署

    apps  开发机器 多次因为升级出现无法登陆 下面就重新部署 流程做笔记 1   备份 根目录下的 那一堆shell 和 Cache/data 下的系统配置 2  shell : su www   ...

  6. Nginx+Keepalived 实现双击热备及负载均衡

    Nginx master : 10.1.58.191   Nginx负载均衡主机 Nginx  slave    : 10.1.58.181   Nginx负载均衡备机Nginx_VIP_TP: 10 ...

  7. [PWA] Keynote: Progressive Web Apps across all frameworks

    PWA: Add to home screen Angular Universal Server side rendering: for achieving better proference on ...

  8. hadoop文件的序列化

    目录 1.为什么要序列化? 2.什么是序列化? 3.为什么不用Java的序列化? 4.为什么序列化对Hadoop很重要? 5.Hadoop中定义哪些序列化相关的接口呢? 6.Hadoop 自定义Wri ...

  9. UNIX环境高级编程第二版代码笔记

    1. 第一个程序 gcc 1.1.c  /tmp/ccbnJqcB.o: In function `main': 1.1.c:(.text+0x17): undefined reference to ...

  10. windows和linux双系统删除linux

    装了Windows和linux双系统的朋友,在后期要删除linux是个比较头痛的问题,因为MBR已经被linux接管,本文的目的是如何在windows 和linux双系统下,简单,完美地卸载linux ...