当前位置:   article > 正文

C++之红黑树_c++ 红黑树

c++ 红黑树

目录

1.红黑树

1.1红黑树的概念

1.2红黑树的性质

1.3红黑树节点的定义

1.4红黑树的结构

1.5红黑树的插入操作

情况一

情况二

情况三

1.6红黑树的验证


红黑树的实现中使用了旋转的几个函数

C++之AVL树的使用以及原理详解-CSDN博客

 

1.红黑树

1.1红黑树的概念

红黑树,是一种二叉搜索树,但在每个结点上增加一个存储位表示结点的颜色,可以是Red或Black。 通过对任何一条从根到叶子的路径上各个结点着色方式的限制,红黑树确保没有一条路径会比其他路径长出俩倍,因而是接近平衡的。

1.2红黑树的性质

1. 每个结点不是红色就是黑色

2. 根节点是黑色的

3. 如果一个节点是红色的,则它的两个孩子结点是黑色的

4. 对于每个结点,从该结点到其所有后代叶结点的简单路径上,均包含相同数目的黑色结点

5. 每个叶子结点都是黑色的(此处的叶子结点指的是空结点)

以上红黑树的性质使得    其最长路径中节点个数不会超过最短路径节点个数的两倍

1.3红黑树节点的定义

  1. enum Colour
  2. {
  3. RED,
  4. BLACK
  5. };
  6. template<class K,class V>
  7. struct RBTreeNode
  8. {
  9. RBTreeNode<K, V>* _left;
  10. RBTreeNode<K, V>* _right;
  11. RBTreeNode<K, V>* _parent;
  12. pair<K, V> _kv;
  13. Colour _col;
  14. RBTreeNode(const pair<K, V>& kv)
  15. :_left(nullptr)
  16. , _right(nullptr)
  17. , parent(nullptr)
  18. , _kv(kv)
  19. , _col(RED)
  20. {}
  21. };

红黑树中新插入节点的颜色一般都初始化成为红色,因为如果插入黑色就会导致各个分支上黑色节点的数量不同,初始化成红色节点也方便向上调整

1.4红黑树的结构

为了后续实现关联式容器简单,红黑树的实现中增加一个头结点,因为跟节点必须为黑色,为了与根节点进行区分,将头结点给成黑色,并且让头结点的 pParent 域指向红黑树的根节点,pLeft域指向红黑树中最小的节点,_pRight域指向红黑树中最大的节点,如下:

1.5红黑树的插入操作

插入操作:

红黑树是在二叉搜索树的基础上加上其平衡限制条件,因此红黑树的插入可分为两步:

1. 按照二叉搜索的树规则插入新节点

2. 检测新节点插入后,红黑树的性质是否造到破坏

因为新节点的默认颜色是红色,因此:如果其双亲节点的颜色是黑色,没有违反红黑树任何性质,则不需要调整;但当新插入节点的双亲节点颜色为红色时,就违反了性质三不能有连在一起的红色节点,此时需要对红黑树分情况来讨论:

约定:cur为当前节点,p为父节点,g为祖父节点,u为叔叔节点情况一: cur为红,p为红,g为黑,u存在且为红

分为了几种情况:

情况一

cur为红,p为红,g为黑,u存在且为红

如果g是根节点,调整完成后,需要将g改为黑色如果g是子树,g一定有双亲,且g的双亲如果是红色,需要继续向上调整。

cur和p均为红,不符合红黑树的规则

所以将p,u改为黑,g改为红,然后把g当成cur,继续向上调整。

情况二

cur为红,p为红,g为黑,u不存在/u存在且为黑

u的情况有两种
1.如果u节点不存在,则cur一定是新插入节点,因为如果cur不是新插入节点则cur和p一定有一个节点的颜色是黑色,就不满足性质4:每条路径黑色节点个数相同。
2.如果u节点存在,则其一定是黑色的,那么cur节点原来的颜色一定是黑色的现在看到其是红色的原因是因为cur的子树在调整的过程中将cur节点的颜色由黑色改成红色

p为g的左孩子,cur为p的左孩子,则进行右单旋转;相反p为g的右孩子,cur为p的右孩子,则进行左单旋转p、g变色--p变黑,g变红

情况三

cur为红,p为红,g为黑,u不存在/u存在且为黑

p为g的左孩子,cur为p的右孩子,则针对p做左单旋转;相反,p为g的右孩子,cur为p的左孩子,则针对p做右单旋转,这样旋转完了之后就变成了我们上面所分析的情况二。

  1. bool Insert(const pair<K, V>& kv)
  2. {
  3. if (_root == nullptr)
  4. {
  5. _root = new Node(kv);
  6. _root->_col = BLACK;
  7. return true;
  8. }
  9. Node* parent = nullptr;
  10. Node* cur = _root;
  11. while (cur)
  12. {
  13. if (cur->_kv.first < kv.first)
  14. {
  15. parent = cur;
  16. cur = cur->_right;
  17. }
  18. else if (cur->_kv.first > kv.first)
  19. {
  20. parent = cur;
  21. cur = cur->_left;
  22. }
  23. else
  24. {
  25. return false;
  26. }
  27. }
  28. cur = new Node(kv); // 红色的
  29. if (parent->_kv.first < kv.first)
  30. {
  31. parent->_right = cur;
  32. }
  33. else
  34. {
  35. parent->_left = cur;
  36. }
  37. cur->_parent = parent;
  38. while (parent && parent->_col == RED)
  39. {
  40. Node* grandfather = parent->_parent;
  41. if (parent == grandfather->_left)
  42. {
  43. Node* uncle = grandfather->_right;
  44. // 情况一:叔叔存在且为红
  45. if (uncle && uncle->_col == RED)
  46. {
  47. // 变色
  48. parent->_col = uncle->_col = BLACK;
  49. grandfather->_col = RED;
  50. // 继续往上处理
  51. cur = grandfather;
  52. parent = cur->_parent;
  53. }
  54. else
  55. {
  56. // 情况二:叔叔不存在或者存在且为黑
  57. // 旋转+变色
  58. if (cur == parent->_left)
  59. {
  60. // g
  61. // p u
  62. // c
  63. RotateR(grandfather);
  64. parent->_col = BLACK;
  65. grandfather->_col = RED;
  66. }
  67. else
  68. {
  69. // g
  70. // p u
  71. // c
  72. RotateL(parent);
  73. RotateR(grandfather);
  74. cur->_col = BLACK;
  75. grandfather->_col = RED;
  76. }
  77. break;
  78. }
  79. }
  80. else
  81. {
  82. Node* uncle = grandfather->_left;
  83. // 情况一:叔叔存在且为红
  84. if (uncle && uncle->_col == RED)
  85. {
  86. // 变色
  87. parent->_col = uncle->_col = BLACK;
  88. grandfather->_col = RED;
  89. // 继续往上处理
  90. cur = grandfather;
  91. parent = cur->_parent;
  92. }
  93. else
  94. {
  95. // 情况二:叔叔不存在或者存在且为黑
  96. // 旋转+变色
  97. // g
  98. // u p
  99. // c
  100. if (cur == parent->_right)
  101. {
  102. RotateL(grandfather);
  103. parent->_col = BLACK;
  104. grandfather->_col = RED;
  105. }
  106. else
  107. {
  108. // g
  109. // u p
  110. // c
  111. RotateR(parent);
  112. RotateL(grandfather);
  113. cur->_col = BLACK;
  114. grandfather->_col = RED;
  115. }
  116. break;
  117. }
  118. }
  119. }
  120. _root->_col = BLACK;
  121. return true;
  122. }

1.6红黑树的验证

红黑树的验证就是 判断一下 这课树是否满足 红黑树的这几条性质, 但是 不能用这四条性质推出来的结论来判断这棵树是不是红黑树。

  1. bool Check(Node* cur)
  2. {
  3. if (cur == nullptr)
  4. return true; //空树也是红黑树
  5. if (cur->_col == RED && cur->_parent->_col == RED)
  6. {
  7. cout << cur->_kv.first << "存在连续的红色节点" << endl;
  8. return false;
  9. }//判断是否存在红色节点
  10. return Check(cur->_left)
  11. && Check(cur->_right);
  12. }
  13. bool IsBalance()
  14. {
  15. if (_root && _root->_col == RED)//判断根节点是否为黑色
  16. return false;
  17. return Check(_root);
  18. }

1.7总体实现

  1. enum Colour
  2. {
  3. RED,
  4. BLACK
  5. };
  6. template<class K, class V>
  7. struct RBTreeNode
  8. {
  9. RBTreeNode<K, V>* _left;
  10. RBTreeNode<K, V>* _right;
  11. RBTreeNode<K, V>* _parent;
  12. pair<K, V> _kv;
  13. Colour _col;
  14. RBTreeNode(const pair<K, V>& kv)
  15. :_left(nullptr)
  16. , _right(nullptr)
  17. , _parent(nullptr)
  18. , _kv(kv)
  19. ,_col(RED)
  20. {}
  21. };
  22. template<class K, class V>
  23. class RBTree
  24. {
  25. typedef RBTreeNode<K, V> Node;
  26. public:
  27. bool Insert(const pair<K, V>& kv)
  28. {
  29. if (_root == nullptr)
  30. {
  31. _root = new Node(kv);
  32. _root->_col = BLACK;
  33. return true;
  34. }
  35. Node* parent = nullptr;
  36. Node* cur = _root;
  37. while (cur)
  38. {
  39. if (cur->_kv.first < kv.first)
  40. {
  41. parent = cur;
  42. cur = cur->_right;
  43. }
  44. else if (cur->_kv.first > kv.first)
  45. {
  46. parent = cur;
  47. cur = cur->_left;
  48. }
  49. else
  50. {
  51. return false;
  52. }
  53. }
  54. cur = new Node(kv); // 红色的
  55. if (parent->_kv.first < kv.first)
  56. {
  57. parent->_right = cur;
  58. }
  59. else
  60. {
  61. parent->_left = cur;
  62. }
  63. cur->_parent = parent;
  64. while (parent && parent->_col == RED)
  65. {
  66. Node* grandfather = parent->_parent;
  67. if (parent == grandfather->_left)
  68. {
  69. Node* uncle = grandfather->_right;
  70. // 情况一:叔叔存在且为红
  71. if (uncle && uncle->_col == RED)
  72. {
  73. // 变色
  74. parent->_col = uncle->_col = BLACK;
  75. grandfather->_col = RED;
  76. // 继续往上处理
  77. cur = grandfather;
  78. parent = cur->_parent;
  79. }
  80. else
  81. {
  82. // 情况二:叔叔不存在或者存在且为黑
  83. // 旋转+变色
  84. if (cur == parent->_left)
  85. {
  86. // g
  87. // p u
  88. // c
  89. RotateR(grandfather);
  90. parent->_col = BLACK;
  91. grandfather->_col = RED;
  92. }
  93. else
  94. {
  95. // g
  96. // p u
  97. // c
  98. RotateL(parent);
  99. RotateR(grandfather);
  100. cur->_col = BLACK;
  101. grandfather->_col = RED;
  102. }
  103. break;
  104. }
  105. }
  106. else
  107. {
  108. Node* uncle = grandfather->_left;
  109. // 情况一:叔叔存在且为红
  110. if (uncle && uncle->_col == RED)
  111. {
  112. // 变色
  113. parent->_col = uncle->_col = BLACK;
  114. grandfather->_col = RED;
  115. // 继续往上处理
  116. cur = grandfather;
  117. parent = cur->_parent;
  118. }
  119. else
  120. {
  121. // 情况二:叔叔不存在或者存在且为黑
  122. // 旋转+变色
  123. // g
  124. // u p
  125. // c
  126. if (cur == parent->_right)
  127. {
  128. RotateL(grandfather);
  129. parent->_col = BLACK;
  130. grandfather->_col = RED;
  131. }
  132. else
  133. {
  134. // g
  135. // u p
  136. // c
  137. RotateR(parent);
  138. RotateL(grandfather);
  139. cur->_col = BLACK;
  140. grandfather->_col = RED;
  141. }
  142. break;
  143. }
  144. }
  145. }
  146. _root->_col = BLACK;
  147. return true;
  148. }
  149. void RotateL(Node* parent)
  150. {
  151. Node* subR = parent->_right;
  152. Node* subRL = subR->_left;
  153. parent->_right = subRL;
  154. if (subRL)
  155. subRL->_parent = parent;
  156. subR->_left = parent;
  157. Node* ppnode = parent->_parent;
  158. parent->_parent = subR;
  159. if (parent == _root)
  160. {
  161. _root = subR;
  162. subR->_parent = nullptr;
  163. }
  164. else
  165. {
  166. if (ppnode->_left == parent)
  167. {
  168. ppnode->_left = subR;
  169. }
  170. else
  171. {
  172. ppnode->_right = subR;
  173. }
  174. subR->_parent = ppnode;
  175. }
  176. }
  177. void RotateR(Node* parent)
  178. {
  179. Node* subL = parent->_left;
  180. Node* subLR = subL->_right;
  181. parent->_left = subLR;
  182. if (subLR)
  183. subLR->_parent = parent;
  184. subL->_right = parent;
  185. Node* ppnode = parent->_parent;
  186. parent->_parent = subL;
  187. if (parent == _root)
  188. {
  189. _root = subL;
  190. subL->_parent = nullptr;
  191. }
  192. else
  193. {
  194. if (ppnode->_left == parent)
  195. {
  196. ppnode->_left = subL;
  197. }
  198. else
  199. {
  200. ppnode->_right = subL;
  201. }
  202. subL->_parent = ppnode;
  203. }
  204. }
  205. void _InOrder(Node* root)
  206. {
  207. if (root == nullptr)
  208. return;
  209. _InOrder(root->_left);
  210. cout << root->_kv.first << endl;
  211. _InOrder(root->_right);
  212. }
  213. void InOrder()
  214. {
  215. _InOrder(_root);
  216. }
  217. bool Check(Node* cur)
  218. {
  219. if (cur == nullptr)
  220. return true;
  221. if (cur->_col == RED && cur->_parent->_col == RED)
  222. {
  223. cout << cur->_kv.first << "存在连续的红色节点" << endl;
  224. return false;
  225. }
  226. return Check(cur->_left)
  227. && Check(cur->_right);
  228. }
  229. bool IsBalance()
  230. {
  231. if (_root && _root->_col == RED)
  232. return false;
  233. return Check(_root);
  234. }
  235. private:
  236. Node* _root = nullptr;
  237. };

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

闽ICP备14008679号