小言_互联网的博客

C++——红黑树

241人阅读  评论(0)

目录

红黑树介绍

 红黑树实现

节点的插入 

完整代码 


 

红黑树介绍

 红黑树,是一种二叉搜索树,但在每个结点上增加一个存储位表示结点的颜色,可以是Red或Black。

通过对任何一条从根到叶子的路径上各个结点着色方式的限制,红黑树确保没有一条路径会比其他路径长出俩倍,因而是接近平衡的。

最长路径不超过最短路径的二倍

红黑树的性质:
1. 每个结点不是红色就是黑色
2. 根节点是黑色的
3. 如果一个节点是红色的,则它的两个孩子结点是黑色的(树中没有连续的红色节点)
4. 对于每个结点,从该结点到其所有后代叶结点的简单路径上,均包含相同数目的黑色结点。(每条路径的黑色节点数量相等)
5. 每个叶子结点都是黑色的(此处的叶子结点指的是空结点
 

 红黑树实现

节点的插入 

当有新节点要插入时,我们尽量遵守规则4,因此插入新节点时,我们插入红色节点。

情况一: cur为红,p为红,g为黑,u存在且为红

abcde是符合红黑树的子树。

如果u存在且为红,p和u变黑,g变红,继续往上处理或者g变黑

新增可以在ab的任意孩子位置

情况二: cur为红,p为红,g为黑,u不存在/u存在且为黑。

 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做右单旋转
则转换成了情况2
 

完整代码 


   
  1. #include<iostream>
  2. #include <map>
  3. #include <string>
  4. #include <algorithm>
  5. using namespace std;
  6. #include<time.h>
  7. #include <assert.h>
  8. enum Colour
  9. {
  10. RED,
  11. BLACK
  12. };
  13. template< class K, class V>
  14. struct RBTreeNode
  15. {
  16. RBTreeNode<K, V>* _left;
  17. RBTreeNode<K, V>* _right;
  18. RBTreeNode<K, V>* _parent;
  19. pair<K, V> _kv;
  20. Colour _col;
  21. RBTreeNode( const pair<K, V>& kv)
  22. :_left( nullptr)
  23. , _right( nullptr)
  24. , _parent( nullptr)
  25. , _kv(kv)
  26. {}
  27. };
  28. template< class K, class V>
  29. struct RBTree
  30. {
  31. typedef RBTreeNode<K, V> Node;
  32. public:
  33. bool Insert(const pair<K, V>& kv)
  34. {
  35. if (_root == nullptr)
  36. {
  37. _root = new Node(kv);
  38. _root->_col = BLACK;
  39. return true;
  40. }
  41. Node* parent = nullptr;
  42. Node* cur = _root;
  43. while (cur)
  44. {
  45. if (cur->_kv.first < kv.first)
  46. {
  47. parent = cur;
  48. cur = cur->_right;
  49. }
  50. else if (cur->_kv.first > kv.first)
  51. {
  52. parent = cur;
  53. cur = cur->_left;
  54. }
  55. else
  56. {
  57. return false;
  58. }
  59. }
  60. cur = new Node(kv);
  61. cur->_col = RED;
  62. if (parent->_kv.first < kv.first)
  63. {
  64. parent->_right = cur;
  65. }
  66. else
  67. {
  68. parent->_left = cur;
  69. }
  70. cur->_parent = parent;
  71. while (parent && parent->_col == RED)
  72. {
  73. Node* grandfater = parent->_parent;
  74. assert(grandfater);
  75. assert(grandfater->_col == BLACK);
  76. // 关键看叔叔
  77. if (parent == grandfater->_left)
  78. {
  79. Node* uncle = grandfater->_right;
  80. // 情况一 : uncle存在且为红,变色+继续往上处理
  81. if (uncle && uncle->_col == RED)
  82. {
  83. parent->_col = uncle->_col = BLACK;
  84. grandfater->_col = RED;
  85. // 继续往上处理
  86. cur = grandfater;
  87. parent = cur->_parent;
  88. } // 情况二+三:uncle不存在 + 存在且为黑
  89. else
  90. {
  91. // 情况二:右单旋+变色
  92. // g
  93. // p u
  94. // c
  95. if (cur == parent->_left)
  96. {
  97. RotateR(grandfater);
  98. parent->_col = BLACK;
  99. grandfater->_col = RED;
  100. }
  101. else
  102. {
  103. // 情况三:左右单旋+变色
  104. // g
  105. // p u
  106. // c
  107. RotateL(parent);
  108. RotateR(grandfater);
  109. cur->_col = BLACK;
  110. grandfater->_col = RED;
  111. }
  112. break;
  113. }
  114. }
  115. else // (parent == grandfater->_right)
  116. {
  117. Node* uncle = grandfater->_left;
  118. // 情况一
  119. if (uncle && uncle->_col == RED)
  120. {
  121. parent->_col = uncle->_col = BLACK;
  122. grandfater->_col = RED;
  123. // 继续往上处理
  124. cur = grandfater;
  125. parent = cur->_parent;
  126. }
  127. else
  128. {
  129. // 情况二:左单旋+变色
  130. // g
  131. // u p
  132. // c
  133. if (cur == parent->_right)
  134. {
  135. RotateL(grandfater);
  136. parent->_col = BLACK;
  137. grandfater->_col = RED;
  138. }
  139. else
  140. {
  141. // 情况三:右左单旋+变色
  142. // g
  143. // u p
  144. // c
  145. RotateR(parent);
  146. RotateL(grandfater);
  147. cur->_col = BLACK;
  148. grandfater->_col = RED;
  149. }
  150. break;
  151. }
  152. }
  153. }
  154. _root->_col = BLACK;
  155. return true;
  156. }
  157. void InOrder()
  158. {
  159. _InOrder(_root);
  160. cout << endl;
  161. }
  162. bool IsBalance()
  163. {
  164. if (_root == nullptr)
  165. {
  166. return true;
  167. }
  168. if (_root->_col == RED)
  169. {
  170. cout << "根节点不是黑色" << endl;
  171. return false;
  172. }
  173. // 黑色节点数量基准值
  174. int benchmark = 0;
  175. /*Node* cur = _root;
  176. while (cur)
  177. {
  178. if (cur->_col == BLACK)
  179. ++benchmark;
  180. cur = cur->_left;
  181. }*/
  182. return PrevCheck(_root, 0, benchmark);
  183. }
  184. private:
  185. bool PrevCheck(Node* root, int blackNum, int& benchmark)
  186. {
  187. if (root == nullptr)
  188. {
  189. //cout << blackNum << endl;
  190. //return;
  191. if (benchmark == 0) //黑色节点数量的基准值
  192. {
  193. benchmark = blackNum;
  194. return true;
  195. }
  196. if (blackNum != benchmark)
  197. {
  198. cout << "某条黑色节点的数量不相等" << endl;
  199. return false;
  200. }
  201. else
  202. {
  203. return true;
  204. }
  205. }
  206. if (root->_col == BLACK)
  207. {
  208. ++blackNum;
  209. }
  210. if (root->_col == RED && root->_parent->_col == RED) //如果有连续红色节点,则不是红黑树
  211. {
  212. cout << "存在连续的红色节点" << endl;
  213. return false;
  214. }
  215. return PrevCheck(root->_left, blackNum, benchmark)
  216. && PrevCheck(root->_right, blackNum, benchmark);
  217. }
  218. void _InOrder(Node* root)
  219. {
  220. if (root == nullptr)
  221. {
  222. return;
  223. }
  224. _InOrder(root->_left);
  225. cout << root->_kv.first << ":" << root->_kv.second << endl;
  226. _InOrder(root->_right);
  227. }
  228. void RotateL(Node* parent)
  229. {
  230. Node* subR = parent->_right;
  231. Node* subRL = subR->_left;
  232. parent->_right = subRL;
  233. if (subRL)
  234. subRL->_parent = parent;
  235. Node* ppNode = parent->_parent;
  236. subR->_left = parent;
  237. parent->_parent = subR;
  238. if (_root == parent)
  239. {
  240. _root = subR;
  241. subR->_parent = nullptr;
  242. }
  243. else
  244. {
  245. if (ppNode->_left == parent)
  246. {
  247. ppNode->_left = subR;
  248. }
  249. else
  250. {
  251. ppNode->_right = subR;
  252. }
  253. subR->_parent = ppNode;
  254. }
  255. }
  256. void RotateR(Node* parent)
  257. {
  258. Node* subL = parent->_left;
  259. Node* subLR = subL->_right;
  260. parent->_left = subLR;
  261. if (subLR)
  262. {
  263. subLR->_parent = parent;
  264. }
  265. Node* ppNode = parent->_parent;
  266. subL->_right = parent;
  267. parent->_parent = subL;
  268. if (_root == parent)
  269. {
  270. _root = subL;
  271. subL->_parent = nullptr;
  272. }
  273. else
  274. {
  275. if (ppNode->_left == parent)
  276. {
  277. ppNode->_left = subL;
  278. }
  279. else
  280. {
  281. ppNode->_right = subL;
  282. }
  283. subL->_parent = ppNode;
  284. }
  285. }
  286. private:
  287. Node* _root = nullptr;
  288. };
  289. void TestRBTree1()
  290. {
  291. size_t N = 1000;
  292. srand( time( 0));
  293. RBTree< int, int> t1;
  294. for ( size_t i = 0; i < N; ++i)
  295. {
  296. int x = rand();
  297. cout << "Insert:" << x << ":" << i << endl;
  298. t1. Insert( make_pair(x, i));
  299. }
  300. cout << "IsBalance:" << t1. IsBalance() << endl;
  301. }
  302. int main()
  303. {
  304. TestRBTree1();
  305. return 0;
  306. }


转载:https://blog.csdn.net/weixin_49449676/article/details/127675382
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场