当前位置:   article > 正文

RBTree(红黑树)

rbtree
                                                                                 红黑树
红黑树(Red Black Tree)和AVL树类似,都是在进行插入和删除操作时通过特定操作保持二叉查找树的平衡。
红黑树是一颗二叉搜索树,它的每一个节点增加了一个存储位用来表示颜色,可以是Red也可以是Black,通过对任意一条根到叶子节点的颜色来约束,红黑树保证最长路径是最短路径的两倍,因此近似平衡;
红黑树的性质:
1:每个节点不是红色就是黑色
2:根节点是黑色
3:如果一个节点时红,则它两个子节点是黑色的(没有连续的红色)
4:对每个节点,从该节点到其后代的所有叶子节点的简单路径,均有相同数目的黑节点(每条路径的黑色节点色数目相同)
两者的差别:AVL树是完全平衡树,更接近满二叉树,因此它的时间复杂度是O(lgN),在二叉树插入删除时旋转多,维护起来比较麻烦,但相比更直观。而RBT树是近似平衡树,时间复杂度是2O(log n),旋转较少,相对维护起来比较简单,但是相比更抽象。相对来说运用最多的还是RBTree。
红黑树的应用: 在C++ STL中,很多部分都运用了红黑树包括:Linux内核,java  c#  还有(包括set, multiset, map, multimap)应用了红黑树的变体(SGI STL中的红黑树有一些变化,这些修改提供了更好的性能,以及对set操作的支持)等等。
下面就是节点的颜色转换以及旋转的情况:



在此只展示了parent为孩子的情况,parent为右孩子情况类似。
具体实现源码如下:
  1. #include <math.h>
  2. #include <iostream>
  3. using namespace std;
  4. enum colour
  5. {
  6. BLACK,
  7. RED,
  8. };
  9. template<class K, class V>
  10. struct RBTreeNode
  11. {
  12. K _key;
  13. V _val;
  14. colour _col;
  15. RBTreeNode<K, V>* _left;
  16. RBTreeNode<K, V>* _right;
  17. RBTreeNode<K, V>* _parent;
  18. int _bf;
  19. RBTreeNode(const K& key, const V& value)
  20. :_left(NULL)
  21. , _right(NULL)
  22. , _parent(NULL)
  23. , _key(key)
  24. , _val(value)
  25. , _bf(0)
  26. , _col(RED)
  27. {}
  28. };
  29. template<class K, class V>
  30. class RBTree
  31. {
  32. typedef RBTreeNode<K, V> Node;
  33. public:
  34. RBTree()
  35. :_root(NULL)
  36. {}
  37. ~RBTree()
  38. {}
  39. bool Insert(const K& key, const V& value)
  40. {
  41. if (_root == NULL)
  42. {
  43. _root = new Node(key, value);
  44. _root->_col = BLACK;
  45. return true;
  46. }
  47. Node* parent = NULL;
  48. Node* cur = _root;
  49. while (cur)
  50. {
  51. if (cur->_key < key)//右边
  52. {
  53. parent = cur;
  54. cur = cur->_right;
  55. }
  56. else if (cur->_key>key)//左边
  57. {
  58. parent = cur;
  59. cur = cur->_left;
  60. }
  61. else
  62. {
  63. return false;//不存在
  64. }
  65. }
  66. cur = new Node(key, value);
  67. if (key > parent->_key)
  68. {
  69. parent->_right = cur;
  70. cur->_parent = parent;
  71. }
  72. else
  73. {
  74. parent->_left = cur;
  75. cur->_parent = parent;
  76. }
  77. while (parent && parent->_col==RED)
  78. {
  79. Node* grandparent = parent->_parent;
  80. if (grandparent->_left==parent) //父亲在左边
  81. {
  82. Node* uncle = grandparent->_right;
  83. if (uncle&&uncle->_col==RED)
  84. {
  85. parent->_col = BLACK;
  86. uncle->_col = BLACK;
  87. grandparent->_col = RED;
  88. cur = grandparent; //向上调整
  89. parent = cur->_parent; //
  90. }
  91. else //叔叔不存在或者叔叔为黑,需要旋转
  92. {
  93. if (cur==parent->_right)
  94. {
  95. RotateL(parent);
  96. swap(parent,cur);
  97. }
  98. RotateR(grandparent);
  99. parent->_col = BLACK;
  100. grandparent->_col = RED;
  101. break;
  102. }
  103. }
  104. else //parent = grandparent->_right;
  105. {
  106. Node* uncle = grandparent->_left;
  107. if (uncle&&uncle->_col == RED)
  108. {
  109. parent->_col = BLACK;
  110. uncle->_col = BLACK;
  111. grandparent->_col = RED;
  112. cur = grandparent; //向上调整
  113. parent = cur->_parent; //
  114. }
  115. else //叔叔不存在或者叔叔为黑,需要旋转
  116. {
  117. if (cur == parent->_left)
  118. {
  119. RotateR(parent);
  120. swap(parent, cur); // 若cur在parent的左,cur->_key < parent->_key,旋转后必须交换才符合_key值得排布规则。
  121. }
  122. RotateL(grandparent);
  123. parent->_col = BLACK;
  124. grandparent->_col = RED;
  125. }
  126. }
  127. }
  128. _root->_col = BLACK;
  129. return true;
  130. }
  131. bool Isbalance()
  132. {
  133. if (_root==NULL)
  134. {
  135. return true;
  136. }
  137. if (_root->_col==RED)
  138. {
  139. return false;
  140. }
  141. int Blacknum = 0;
  142. Node* left = _root;
  143. while (left) //遍历任意一边,计算出黑色节点的个数,作为一个基准,将此数与其他路上的书做较,只要不相等就可以说明此树不是平衡红黑树
  144. {
  145. if (left->_col==BLACK)
  146. {
  147. Blacknum++;
  148. }
  149. left = left->_left;
  150. }
  151. int num = 0;
  152. return _IsBalance(_root, Blacknum, num);
  153. }
  154. bool _IsBalance(Node* root, const int Blacknum, int num)
  155. {
  156. if (root == NULL)
  157. {
  158. if (num != Blacknum)
  159. {
  160. cout << "黑节点个数不等" << endl;
  161. return false;
  162. }
  163. else
  164. {
  165. return true;
  166. }
  167. }
  168. if (root->_col == BLACK)
  169. {
  170. num++;
  171. }
  172. if ((root->_col == RED) && (root->_parent->_col == RED))
  173. {
  174. cout << root->_key << " " << root->_parent->_key << " " << endl;
  175. return false;
  176. }
  177. return _IsBalance(root->_left, Blacknum, num) && _IsBalance(root->_right, Blacknum, num);
  178. }
  179. void RotateL(Node* parent)// 左单旋
  180. {
  181. Node* subR = parent->_right;
  182. Node* subRL = subR->_left;
  183. parent->_right = subRL;
  184. if (subRL) //开始旋转
  185. {
  186. subRL->_parent = parent;
  187. } //
  188. subR->_left = parent;
  189. subR->_parent = parent->_parent;
  190. Node* ppnode = parent->_parent;
  191. parent->_parent = subR;/
  192. if (ppnode == NULL)
  193. {
  194. _root = subR;
  195. subR->_parent = NULL;
  196. }
  197. else if (parent == ppnode->_left)
  198. {
  199. ppnode->_left = subR;
  200. }
  201. else
  202. {
  203. ppnode->_right = subR;
  204. }
  205. subR->_parent = ppnode;
  206. }
  207. void RotateR(Node* parent)
  208. {
  209. Node* subL = parent->_left;
  210. Node* subLR = subL->_right;
  211. parent->_left = subLR;
  212. if (subLR)
  213. {
  214. subLR->_parent = parent;
  215. }
  216. subL->_right = parent;
  217. subL->_parent = parent->_parent;
  218. Node* ppnode = parent->_parent;
  219. parent->_parent = subL;
  220. if (ppnode == NULL)
  221. {
  222. _root = subL;
  223. subL->_parent = NULL;
  224. }
  225. else if (ppnode->_left == parent)
  226. {
  227. ppnode->_left = subL;
  228. }
  229. else
  230. {
  231. ppnode->_right = subL;
  232. }
  233. subL->_parent = ppnode;
  234. }
  235. void InOrder()
  236. {
  237. _InOrder(_root);
  238. cout << endl;
  239. }
  240. protected:
  241. void _InOrder(Node* root)
  242. {
  243. if (root == NULL)
  244. {
  245. return;
  246. }
  247. _InOrder(root->_left);
  248. cout << root->_key << " ";
  249. _InOrder(root->_right);
  250. }
  251. private:
  252. Node* _root;
  253. };
  254. void Test()
  255. {
  256. int a[] = { 5, 3, 4, 1, 7, 8, 2, 6, 0, 9 };
  257. //int a[] = { 4, 2, 6, 1, 3, 5, 15, 7, 16, 14 };
  258. //int a[] = {2,3,1,4,5};
  259. //int a[] = { 16, 3, 7, 11, 9, 26, 18, 14, 15 };
  260. RBTree<int, int> t;
  261. for (size_t i = 0; i < sizeof(a) / sizeof(a[0]); i++)
  262. {
  263. //t.Insert(a[i], i);
  264. t.Insert(a[i],i);
  265. cout << t.Isbalance()<< endl;
  266. }
  267. t.InOrder();
  268. }


声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/246058
推荐阅读
  

闽ICP备14008679号