当前位置:   article > 正文

红黑二叉搜索树(RB-Tree)_rbtree top-down insert

rbtree top-down insert

一、介绍

上一篇介绍了AVL-Tree,这里介绍另一个被广泛运用的平衡二叉搜索树(红黑树)(提示:知识是递进的,如果二叉搜索树都不了解,请学习相关内容再来)。

所谓的RB-Tree,不仅是一个二叉搜索树,还要满足以下条件:

(1)每个节点不是黑色就是红色。

(2)根节点是黑色。

(3)如果一个节点是红色的,则它的子节点必须是黑色的,也就是说不可能出现两个连续的红色节点,不过两个连续的黑色节点是可能出现的。

(4)从任意一个节点到NULL(树尾端)的任何路径,所包含的黑节点数必须相同。

根据规则4,新增节点必须为红;根据规则3,新增节点之父节点必须为黑。当心节点根据二叉搜索树的规则到达其插入点,却未能符合上述条件时,就必须调整颜色并旋转树形。如下图所示,(注意:深色表示黑,浅色表示红)

二、插入

要点:

1、红黑树在插入数据的时候,会先遍历数据应该插入到哪个位置,插入的位置肯定在底部,不可能在中间突然插入一个值。

2、插入的数据一定是红色的(因为要遵守红黑树的第4条规则,如果有一条分支增加了一个黑色节点,就会打破该规则)

3、插入之后,为了满足规则4,就需要用到换色与左旋、右旋的操作了

现在我们延续上图的状态,插入一些节点,看看会产生什么

假设我们对上图,插入3,8,35,75。根据二叉搜索树的规则,它们应该如下图所示。这样就破坏了红黑的规则,我们必须调整树形,也就是旋转树形并改变节点的颜色。

为了方便讨论,让我先为某些特殊节点定义一些代名.以下讨论都将沿用这些
代名.假设新节点为X,其父节点为P(Parent),祖父节点为G(Grand),伯父节点(父节点之兄弟节点)为S(Sibling),曾祖父节点为GG。现在,根据二叉搜索树的规则,新节点X必为叶子节点。根据红黑树规则4,X必为红。若P亦为红(这就违反了规则3,必须调整树形),则G必为黑(因为原为RB-tree,必须遵循规则3)。于是,根据Ⅹ的插入位置及外围节点(S和GG)的颜色,有了以下四种考虑 :

注意,此时可能产生不平衡状态(高度相差1以上)例如图中的A和B为null,D或E不为null。这倒没关系,因为RB-tree的平衡性本来就比AVL-tree弱,然而RB-tree通常能够导致良好的平衡状态。是的,经验告诉我们,RB-tree的搜寻平均效率和AVL-tree几乎相等 

最后一个步骤

为了避免状况4——父子节点皆为红色”的情况。持续向RB-tree的上层结构发展,形成处理时效上的瓶颈,我们可以施行一个由上而下的步骤( top-downprocedure):假设新增节点为A,那么就延着A的路径,只要看到有某节点X的两个子节点皆为红色,就把X改为红色,并把两个子节点改为黑色,如图5-15e所示 

 三、代码实现

  1. #ifndef CM_RBTREE_HPP
  2. #define CM_RBTREE_HPP
  3. #include "BinarySearchTree.hpp"
  4. namespace cm
  5. {
  6. template<typename T> class RBTreeNode;
  7. template<typename T> class RBTreeIterator;
  8. template<typename T> class RBTree;
  9. template<typename T>
  10. class RBTreeNode
  11. {
  12. public:
  13. typedef T VALUE_TYPE;
  14. enum Color_t {
  15. COLOR_BLACK,
  16. COLOR_RED
  17. };
  18. public:
  19. explicit RBTreeNode(const T& v=T(), Color_t c=COLOR_BLACK)
  20. : value_(v)
  21. , left_(NIL)
  22. , right_(NIL)
  23. , parent_(NIL)
  24. , color_(c)
  25. {
  26. }
  27. RBTreeNode<T>* left() { return left_; }
  28. RBTreeNode<T>* right() { return right_; }
  29. RBTreeNode<T>* parent(){ return parent_; }
  30. RBTreeNode<T>* left() const { return left_; }
  31. RBTreeNode<T>* right() const { return right_; }
  32. RBTreeNode<T>* parent() const { return parent_; }
  33. const T& value() const { return value_; }
  34. Color_t color() const { return color_; }
  35. void left(RBTreeNode<T>* node) { left_ = node; }
  36. void right(RBTreeNode<T>* node) { right_ = node; }
  37. void parent(RBTreeNode<T>* node){ parent_ = node; }
  38. void value(const T& value) { value_ = value; }
  39. void color(Color_t c) { color_ = c; }
  40. operator bool() const
  41. {
  42. return this != NIL;
  43. }
  44. bool operator !() const
  45. {
  46. return this == NIL;
  47. }
  48. public:
  49. static RBTreeNode<T>* NIL;
  50. private:
  51. T value_;
  52. RBTreeNode<T>* left_;
  53. RBTreeNode<T>* right_;
  54. RBTreeNode<T>* parent_;
  55. Color_t color_;
  56. };
  57. template<typename T>
  58. RBTreeNode<T>* RBTreeNode<T>::NIL(new RBTreeNode<T>());
  59. template<typename T>
  60. class RBTree: public BinarySearchTree_T< RBTreeNode<T> >
  61. {
  62. public:
  63. typedef RBTreeNode<T> Node;
  64. public:
  65. size_t bh() const
  66. {
  67. return this->bh(this->getRoot());
  68. }
  69. size_t bh(const Node* node) const
  70. {
  71. Node* n = node;
  72. size_t h = ;
  73. while (n) {
  74. if (n->color() == Node::COLOR_BLACK) {
  75. ++h;
  76. }
  77. n = n->left();
  78. }
  79. return h;
  80. }
  81. size_t insert(const T& key)
  82. {
  83. Node* z = new Node(key, Node::COLOR_RED); // 要插入的节点
  84. Node* y = Node::NIL; // y 是 x 的父节点
  85. Node* x = this->root();
  86. while (x != Node::NIL) {
  87. y = x;
  88. if (key == x->value()) {
  89. return 0;
  90. }
  91. if (key < x->value()) {
  92. x = x->left();
  93. }
  94. else {
  95. x = x->right();
  96. }
  97. }
  98. z->parent(y);
  99. if (y == Node::NIL) {
  100. this->root_ = z;
  101. this->root_->parent(Node::NIL);
  102. }
  103. else {
  104. if(key < y->value()) {
  105. y->left(z);
  106. }
  107. else {
  108. y->right(z);
  109. }
  110. }
  111. z->left(Node::NIL);
  112. z->right(Node::NIL);
  113. insert_fixup(z);
  114. ++this->size_;
  115. return ;
  116. }
  117. void remove(Node* z)
  118. {
  119. Node* y = Node::NIL;
  120. Node* x = Node::NIL;
  121. if (z->left() == Node::NIL || z->right() == Node::NIL) {
  122. y = z;
  123. }
  124. else {
  125. //y = this->successor(z);
  126. y = z->right();
  127. while (y->left() != Node::NIL) {
  128. y = y->left();
  129. }
  130. }
  131. // x 是 y的唯一孩子
  132. if (y->left() != Node::NIL) {
  133. x = y->left();
  134. }
  135. else {
  136. x = y->right();
  137. }
  138. x->parent(y->parent());
  139. if(y->parent() == Node::NIL) {
  140. this->root_ = x;
  141. }
  142. else {
  143. if (y == y->parent()->left()) {
  144. y->parent()->left(x);
  145. }
  146. else {
  147. y->parent()->right(x);
  148. }
  149. }
  150. if (y != z) {
  151. z->value(y->value());
  152. }
  153. if (y->color() == Node::COLOR_BLACK) {
  154. this->delete_fixup(x);
  155. }
  156. delete y;
  157. --this->size_;
  158. }
  159. /// 如果key存在,删除并返回 ,否则返回
  160. size_t remove(const T& key)
  161. {
  162. Node* node = this->find(key);
  163. if (node != Node::NIL) {
  164. this->remove(node);
  165. return ;
  166. }
  167. return ;
  168. }
  169. private:
  170. void left_rotate(Node* x)
  171. {
  172. Node* y = x->right();
  173. // 把y的左子数变成x的右子树
  174. x->right(y->left());
  175. if (y->left() != Node::NIL) {
  176. y->left()->parent(x);
  177. }
  178. if (y != Node::NIL) {
  179. y->parent(x->parent());
  180. }
  181. if (x->parent() == Node::NIL) {
  182. this->root_ = y;
  183. }
  184. else {
  185. if (x == x->parent()->left()) {
  186. x->parent()->left(y);
  187. }
  188. else {
  189. x->parent()->right(y);
  190. }
  191. }
  192. // 把x变成y的左子节点
  193. y->left(x);
  194. if (x != Node::NIL) {
  195. x->parent(y);
  196. }
  197. }
  198. void right_rotate(Node* x)
  199. {
  200. Node* y = x->left();
  201. x->left(y->right());
  202. if (y->right() != Node::NIL) {
  203. y->right()->parent(x);
  204. }
  205. if (y != Node::NIL) {
  206. y->parent(x->parent());
  207. }
  208. if (x->parent() == Node::NIL) {
  209. this->root_ = y;
  210. }
  211. else {
  212. if (x == x->parent()->left()) {
  213. x->parent()->left(y);
  214. }
  215. else {
  216. x->parent()->right(y);
  217. }
  218. }
  219. y->right(x);
  220. if (x != Node::NIL) {
  221. x->parent(y);
  222. }
  223. }
  224. void insert_fixup(Node* z)
  225. {
  226. Node* y = Node::NIL;
  227. while (z != this->root() && z->parent()->color() == Node::COLOR_RED) {
  228. if (z->parent() == z->parent()->parent()->left()) {
  229. y = z->parent()->parent()->right();
  230. if (y->color() == Node::COLOR_RED) {
  231. z->parent()->color(Node::COLOR_BLACK);
  232. y->color(Node::COLOR_BLACK);
  233. z->parent()->parent()->color(Node::COLOR_RED);
  234. z = z->parent()->parent();
  235. }
  236. else {
  237. if (z == z->parent()->right()) {
  238. z = z->parent();
  239. this->left_rotate(z);
  240. }
  241. z->parent()->color(Node::COLOR_BLACK);
  242. z->parent()->parent()->color(Node::COLOR_RED);
  243. this->right_rotate(z->parent()->parent());
  244. }
  245. }
  246. else {
  247. y = z->parent()->parent()->left();
  248. if (y->color() == Node::COLOR_RED) {
  249. z->parent()->color(Node::COLOR_BLACK);
  250. y->color(Node::COLOR_BLACK);
  251. z->parent()->parent()->color(Node::COLOR_RED);
  252. z = z->parent()->parent();
  253. }
  254. else {
  255. if (z == z->parent()->left()) {
  256. z = z->parent();
  257. this->right_rotate(z);
  258. }
  259. z->parent()->color(Node::COLOR_BLACK);
  260. z->parent()->parent()->color(Node::COLOR_RED);
  261. this->left_rotate(z->parent()->parent());
  262. }
  263. }
  264. }
  265. this->root()->color(Node::COLOR_BLACK);
  266. }
  267. void delete_fixup(Node* x)
  268. {
  269. Node* w = Node::NIL;
  270. while (x != this->root() && x->color() == Node::COLOR_BLACK) {
  271. if (x == x->parent()->left()) {
  272. w = x->parent()->right();
  273. if (w->color() == Node::COLOR_RED) {
  274. w->color(Node::COLOR_BLACK);
  275. x->parent()->color(Node::COLOR_RED);
  276. this->left_rotate(x->parent());
  277. w = x->parent()->right();
  278. }
  279. if (w->left()->color() == Node::COLOR_BLACK && w->right()->color() == Node::COLOR_BLACK) {
  280. w->color(Node::COLOR_RED);
  281. x = x->parent();
  282. } else {
  283. if (w->right()->color() == Node::COLOR_BLACK) {
  284. w->left()->color(Node::COLOR_BLACK);
  285. w->color(Node::COLOR_RED);
  286. right_rotate(w);
  287. w = x->parent()->right();
  288. }
  289. w->color(x->parent()->color());
  290. x->parent()->color(Node::COLOR_BLACK);
  291. w->right()->color(Node::COLOR_BLACK);
  292. left_rotate(x->parent());
  293. x = this->root();
  294. }
  295. } else {
  296. w = x->parent()->left();
  297. if (w->color() == Node::COLOR_RED) {
  298. w->color(Node::COLOR_BLACK);
  299. x->parent()->color(Node::COLOR_RED);
  300. right_rotate(x->parent());
  301. w = x->parent()->left();
  302. }
  303. if (w->right()->color() == Node::COLOR_BLACK && w->left()->color() == Node::COLOR_BLACK) {
  304. w->color(Node::COLOR_RED);
  305. x = x->parent();
  306. } else {
  307. if (w->left()->color() == Node::COLOR_BLACK) {
  308. w->right()->color(Node::COLOR_BLACK);
  309. w->color(Node::COLOR_RED);
  310. left_rotate(w);
  311. w = x->parent()->left();
  312. }
  313. w->color(x->parent()->color());
  314. x->parent()->color(Node::COLOR_BLACK);
  315. w->left()->color(Node::COLOR_BLACK);
  316. right_rotate(x->parent());
  317. x = this->root();
  318. }
  319. }
  320. }
  321. x->color(Node::COLOR_BLACK);
  322. }
  323. };
  324. template<typename T>
  325. class RBTreeIterator
  326. {
  327. public:
  328. RBTreeIterator()
  329. : tree_(RBTreeNode<T>::NIL), current_(RBTreeNode<T>::NIL)
  330. {
  331. }
  332. RBTreeIterator(RBTree<T>& tree, typename RBTree<T>::Node* current)
  333. : tree_(tree), current_(current)
  334. {
  335. }
  336. const T& operator*() const
  337. {
  338. return current_->value();
  339. }
  340. T* operator->()
  341. {
  342. return current_;
  343. }
  344. bool operator==(const RBTreeIterator& rhs) const
  345. {
  346. return current_ == rhs.current_;
  347. }
  348. bool operator!=(const RBTreeIterator& rhs) const
  349. {
  350. return current_ != rhs.current_;
  351. }
  352. RBTreeIterator& operator++()
  353. {
  354. current_ = tree_.successor(current_);
  355. return *this;
  356. }
  357. private:
  358. RBTree<T>& tree_;
  359. typename RBTree<T>::Node* current_;
  360. };
  361. } // end namespace cm
  362. #endif // CM_RBTREE_HPP

 参考:

【算法】红黑树插入数据(变色,左旋、右旋)(二)_lsr40的博客-CSDN博客_红黑树左旋右旋

深入理解红黑树及C++实现 - 守功 - 博客园

红黑树的C++实现与解析_wang11chao01的博客-CSDN博客_c++红黑树案例

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