C++进阶——STL源码之红黑树(_Rb_tree)

85 篇文章 19 订阅

STL源码之红黑树

红黑树(Red Black Tree) 是一种自平衡二叉查找树,是在计算机科学中用到的一种数据结构,典型的用途是实现关联数组;红黑树是在1972年由Rudolf Bayer发明的,当时被称为平衡二叉B树(symmetric binary B-trees)。后来,在1978年被 Leo J. Guibas 和 Robert Sedgewick 修改为如今的“红黑树”。

红黑树是一种特化的AVL树(平衡二叉树),都是在进行插入和删除操作时通过特定操作保持二叉查找树的平衡,从而获得较高的查找性能;它虽然是复杂的,但它的最坏情况运行时间也是非常良好的,并且在实践中是高效的: 它可以在O(log n)时间内做查找,插入和删除,这里的n 是树中元素的数目。

红黑树的性质

  1. 每个节点非红即黑;
  2. 根节点是黑的;
  3. 每个叶节点(叶节点即树尾端NULL指针或NULL节点)都是黑的;
  4. 如图所示,如果一个节点是红的,那么它的两儿子都是黑的;
  5. 对于任意节点而言,其到叶子点树NULL指针的每条路径都包含相同数目的黑节点。

_Rb_tree的结构图

_Rb_tree的结点结构

_Rb_tree_node的实现如下,几个实现也很简单,在_Rb_tree_node中定义了结点数据域,在基类_Rb_tree_node_base中分别定义了left、right、parent,另外还有一个表示颜色的标记常量。

另外在_Rb_tree_node_base实现了获取最大值与最小值的方法,根据红黑树的性质,获取最大值只需要在右子树上一直搜索,最小值在左子树上一直搜索。

 
  1. template<typename _Val>

  2. struct _Rb_tree_node : public _Rb_tree_node_base

  3. {

  4. typedef _Rb_tree_node<_Val>* _Link_type;

  5. #if __cplusplus < 201103L

  6. _Val _M_value_field;

  7. _Val*

  8. _M_valptr()

  9. { return std::__addressof(_M_value_field); }

  10. const _Val*

  11. _M_valptr() const

  12. { return std::__addressof(_M_value_field); }

  13. #else

  14. __gnu_cxx::__aligned_buffer<_Val> _M_storage;

  15. _Val*

  16. _M_valptr()

  17. { return _M_storage._M_ptr(); }

  18. const _Val*

  19. _M_valptr() const

  20. { return _M_storage._M_ptr(); }

  21. #endif

  22. };

_Rb_tree_node_base的实现如下:

 
  1. enum _Rb_tree_color { _S_red = false, _S_black = true };

  2. struct _Rb_tree_node_base

  3. {

  4. typedef _Rb_tree_node_base* _Base_ptr;

  5. typedef const _Rb_tree_node_base* _Const_Base_ptr;

  6. _Rb_tree_color _M_color;

  7. _Base_ptr _M_parent;

  8. _Base_ptr _M_left;

  9. _Base_ptr _M_right;

  10. static _Base_ptr

  11. _S_minimum(_Base_ptr __x) _GLIBCXX_NOEXCEPT

  12. {

  13. while (__x->_M_left != 0) __x = __x->_M_left;

  14. return __x;

  15. }

  16. static _Const_Base_ptr

  17. _S_minimum(_Const_Base_ptr __x) _GLIBCXX_NOEXCEPT

  18. {

  19. while (__x->_M_left != 0) __x = __x->_M_left;

  20. return __x;

  21. }

  22. static _Base_ptr

  23. _S_maximum(_Base_ptr __x) _GLIBCXX_NOEXCEPT

  24. {

  25. while (__x->_M_right != 0) __x = __x->_M_right;

  26. return __x;

  27. }

  28. static _Const_Base_ptr

  29. _S_maximum(_Const_Base_ptr __x) _GLIBCXX_NOEXCEPT

  30. {

  31. while (__x->_M_right != 0) __x = __x->_M_right;

  32. return __x;

  33. }

  34. };

_Rb_tree的迭代器

_Rb_tree的迭代器首先包含了实现萃取机制的一些typedef,当然实现了一些操作符重载,主要来看下++ 和 -- 的重载。

 
  1. template<typename _Tp>

  2. struct _Rb_tree_iterator

  3. {

  4. typedef _Tp value_type;

  5. typedef _Tp& reference;

  6. typedef _Tp* pointer;

  7. typedef bidirectional_iterator_tag iterator_category;

  8. typedef ptrdiff_t difference_type;

  9. typedef _Rb_tree_iterator<_Tp> _Self;

  10. typedef _Rb_tree_node_base::_Base_ptr _Base_ptr;

  11. typedef _Rb_tree_node<_Tp>* _Link_type;

  12. _Rb_tree_iterator() _GLIBCXX_NOEXCEPT

  13. : _M_node() { }

  14. explicit

  15. _Rb_tree_iterator(_Link_type __x) _GLIBCXX_NOEXCEPT

  16. : _M_node(__x) { }

  17. reference

  18. operator*() const _GLIBCXX_NOEXCEPT

  19. { return *static_cast<_Link_type>(_M_node)->_M_valptr(); }

  20. pointer

  21. operator->() const _GLIBCXX_NOEXCEPT

  22. { return static_cast<_Link_type> (_M_node)->_M_valptr(); }

  23. _Self&

  24. operator++() _GLIBCXX_NOEXCEPT

  25. {

  26. _M_node = _Rb_tree_increment(_M_node);

  27. return *this;

  28. }

  29. _Self

  30. operator++(int) _GLIBCXX_NOEXCEPT

  31. {

  32. _Self __tmp = *this;

  33. _M_node = _Rb_tree_increment(_M_node);

  34. return __tmp;

  35. }

  36. _Self&

  37. operator--() _GLIBCXX_NOEXCEPT

  38. {

  39. _M_node = _Rb_tree_decrement(_M_node);

  40. return *this;

  41. }

  42. _Self

  43. operator--(int) _GLIBCXX_NOEXCEPT

  44. {

  45. _Self __tmp = *this;

  46. _M_node = _Rb_tree_decrement(_M_node);

  47. return __tmp;

  48. }

  49. bool

  50. operator==(const _Self& __x) const _GLIBCXX_NOEXCEPT

  51. { return _M_node == __x._M_node; }

  52. bool

  53. operator!=(const _Self& __x) const _GLIBCXX_NOEXCEPT

  54. { return _M_node != __x._M_node; }

  55. _Base_ptr _M_node;

  56. };

前++的重载

 
  1. _Self&

  2. operator++() _GLIBCXX_NOEXCEPT

  3. {

  4. _M_node = _Rb_tree_increment(_M_node);

  5. return *this;

  6. }

前++的实现是通过_Rb_tree_increment(libstdc++-v3\src\c++98\tree.cc)来完成,其实现如下:

 
  1. _Rb_tree_node_base*

  2. _Rb_tree_increment(_Rb_tree_node_base* __x) throw ()

  3. {

  4. return local_Rb_tree_increment(__x);

  5. }

 
  1. static _Rb_tree_node_base*

  2. local_Rb_tree_increment(_Rb_tree_node_base* __x) throw ()

  3. {

  4. /*

  5. 如果当前结点有右子节点,那么右子树的最左结点就是++所需的结点

  6. */

  7. if (__x->_M_right != 0)

  8. {

  9. __x = __x->_M_right;

  10. while (__x->_M_left != 0)

  11. __x = __x->_M_left;

  12. }

  13. else

  14. {

  15. /*

  16. 1. 如果当前结点是左子树结点,那么++的结果就是当前结点的父结点

  17. 2. 如果当前结点是右子树结点,那么++的结果就是父结点的父结点

  18. */

  19. _Rb_tree_node_base* __y = __x->_M_parent;

  20. while (__x == __y->_M_right)

  21. {

  22. __x = __y;

  23. __y = __y->_M_parent;

  24. }

  25. if (__x->_M_right != __y)

  26. __x = __y;

  27. }

  28. return __x;

  29. }

前--的重载

 
  1. _Self&

  2. operator--() _GLIBCXX_NOEXCEPT

  3. {

  4. _M_node = _Rb_tree_decrement(_M_node);

  5. return *this;

  6. }

_Rb_tree_decrement的实现:

 
  1. _Rb_tree_node_base*

  2. _Rb_tree_decrement(_Rb_tree_node_base* __x) throw ()

  3. {

  4. return local_Rb_tree_decrement(__x);

  5. }

 
  1. static _Rb_tree_node_base*

  2. local_Rb_tree_decrement(_Rb_tree_node_base* __x) throw ()

  3. {

  4. /*

  5. 从上面的结构图,我们知道,header是红色,并且parent为root,而root的parent为header

  6. */

  7. if (__x->_M_color == _S_red

  8. && __x->_M_parent->_M_parent == __x)

  9. __x = __x->_M_right;

  10. else if (__x->_M_left != 0)

  11. {/*左子树的最大值*/

  12. _Rb_tree_node_base* __y = __x->_M_left;

  13. while (__y->_M_right != 0)

  14. __y = __y->_M_right;

  15. __x = __y;

  16. }

  17. else

  18. {

  19. _Rb_tree_node_base* __y = __x->_M_parent;

  20. while (__x == __y->_M_left)

  21. {

  22. __x = __y;

  23. __y = __y->_M_parent;

  24. }

  25. __x = __y;

  26. }

  27. return __x;

  28. }

_Rb_tree的成员构成

通过上述的类结构图可知,_Rb_tree 的具体实现是在 _Rb_tree_impl中,主要定义了三个成员变量:

  •  _Key_compare        _M_key_compare;
  •  _Rb_tree_node_base     _M_header;
  •  size_type         _M_node_count; 

_Rb_tree_impl还负责红黑树的初始化操作与内存管理。

 
  1. template<typename _Key_compare,

  2. bool _Is_pod_comparator = __is_pod(_Key_compare)>

  3. struct _Rb_tree_impl : public _Node_allocator

  4. {

  5. _Key_compare _M_key_compare;

  6. _Rb_tree_node_base _M_header;

  7. size_type _M_node_count; // Keeps track of size of tree.

  8. _Rb_tree_impl()

  9. : _Node_allocator(), _M_key_compare(), _M_header(),

  10. _M_node_count(0)

  11. { _M_initialize(); }

  12. _Rb_tree_impl(const _Key_compare& __comp, const _Node_allocator& __a)

  13. : _Node_allocator(__a), _M_key_compare(__comp), _M_header(),

  14. _M_node_count(0)

  15. { _M_initialize(); }

  16. #if __cplusplus >= 201103L

  17. _Rb_tree_impl(const _Key_compare& __comp, _Node_allocator&& __a)

  18. : _Node_allocator(std::move(__a)), _M_key_compare(__comp),

  19. _M_header(), _M_node_count(0)

  20. { _M_initialize(); }

  21. #endif

  22. private:

  23. void

  24. _M_initialize()

  25. {

  26. this->_M_header._M_color = _S_red;

  27. this->_M_header._M_parent = 0;

  28. this->_M_header._M_left = &this->_M_header;

  29. this->_M_header._M_right = &this->_M_header;

  30. }

  31. };

_Rb_tree的内存管理

通过获取_M_impl的构造器来完成节点的创建和销毁,这里和我们之前看到的是一致的,内存分配和构造是分开的,在_M_create_node中,先通过构造器去分配,然后通过construct来构造。

 
  1. _Node_allocator&

  2. _M_get_Node_allocator() _GLIBCXX_NOEXCEPT

  3. { return *static_cast<_Node_allocator*>(&this->_M_impl); }

  4. const _Node_allocator&

  5. _M_get_Node_allocator() const _GLIBCXX_NOEXCEPT

  6. { return *static_cast<const _Node_allocator*>(&this->_M_impl); }

  7. allocator_type

  8. get_allocator() const _GLIBCXX_NOEXCEPT

  9. { return allocator_type(_M_get_Node_allocator()); }

  10. protected:

  11. _Link_type

  12. _M_get_node()

  13. { return _Alloc_traits::allocate(_M_get_Node_allocator(), 1); }

  14. void

  15. _M_put_node(_Link_type __p) _GLIBCXX_NOEXCEPT

  16. { _Alloc_traits::deallocate(_M_get_Node_allocator(), __p, 1); }

  17. #if __cplusplus < 201103L

  18. _Link_type

  19. _M_create_node(const value_type& __x)

  20. {

  21. _Link_type __tmp = _M_get_node();

  22. __try

  23. { get_allocator().construct(__tmp->_M_valptr(), __x); }

  24. __catch(...)

  25. {

  26. _M_put_node(__tmp);

  27. __throw_exception_again;

  28. }

  29. return __tmp;

  30. }

  31. void

  32. _M_destroy_node(_Link_type __p)

  33. {

  34. get_allocator().destroy(__p->_M_valptr());

  35. _M_put_node(__p);

  36. }

  37. #else

  38. template<typename... _Args>

  39. _Link_type

  40. _M_create_node(_Args&&... __args)

  41. {

  42. _Link_type __tmp = _M_get_node();

  43. __try

  44. {

  45. ::new(__tmp) _Rb_tree_node<_Val>;

  46. _Alloc_traits::construct(_M_get_Node_allocator(),

  47. __tmp->_M_valptr(),

  48. std::forward<_Args>(__args)...);

  49. }

  50. __catch(...)

  51. {

  52. _M_put_node(__tmp);

  53. __throw_exception_again;

  54. }

  55. return __tmp;

  56. }

  57. void

  58. _M_destroy_node(_Link_type __p) noexcept

  59. {

  60. _Alloc_traits::destroy(_M_get_Node_allocator(), __p->_M_valptr());

  61. __p->~_Rb_tree_node<_Val>();

  62. _M_put_node(__p);

  63. }

  64. #endif

  65. _Link_type

  66. _M_clone_node(_Const_Link_type __x)

  67. {

  68. _Link_type __tmp = _M_create_node(*__x->_M_valptr());

  69. __tmp->_M_color = __x->_M_color;

  70. __tmp->_M_left = 0;

  71. __tmp->_M_right = 0;

  72. return __tmp;

  73. }

_Rb_tree的元素操作

在看源码之前先看下以下几个接口:

 
  1. _Link_type

  2. _M_begin() _GLIBCXX_NOEXCEPT

  3. { return static_cast<_Link_type>(this->_M_impl._M_header._M_parent); }

  4. _Const_Link_type

  5. _M_begin() const _GLIBCXX_NOEXCEPT

  6. {

  7. return static_cast<_Const_Link_type>

  8. (this->_M_impl._M_header._M_parent);

  9. }

  10. _Link_type

  11. _M_end() _GLIBCXX_NOEXCEPT

  12. { return static_cast<_Link_type>(&this->_M_impl._M_header); }

  13. _Const_Link_type

  14. _M_end() const _GLIBCXX_NOEXCEPT

  15. { return static_cast<_Const_Link_type>(&this->_M_impl._M_header); }

_M_insert_equal的元素插入操作

 
  1. template<typename _Key, typename _Val, typename _KeyOfValue,

  2. typename _Compare, typename _Alloc>

  3. #if __cplusplus >= 201103L

  4. template<typename _Arg>

  5. #endif

  6. typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator

  7. _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::

  8. #if __cplusplus >= 201103L

  9. _M_insert_equal(_Arg&& __v)

  10. #else

  11. _M_insert_equal(const _Val& __v)

  12. #endif

  13. {

  14. pair<_Base_ptr, _Base_ptr> __res

  15. = _M_get_insert_equal_pos(_KeyOfValue()(__v));

  16. return _M_insert_(__res.first, __res.second, _GLIBCXX_FORWARD(_Arg, __v));

  17. }

上述代码中调用了_M_get_insert_equal_pos,其中的实现是从根节点开始,往下寻找适当的插入点:

 
  1. template<typename _Key, typename _Val, typename _KeyOfValue,

  2. typename _Compare, typename _Alloc>

  3. pair<typename _Rb_tree<_Key, _Val, _KeyOfValue,

  4. _Compare, _Alloc>::_Base_ptr,

  5. typename _Rb_tree<_Key, _Val, _KeyOfValue,

  6. _Compare, _Alloc>::_Base_ptr>

  7. _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::

  8. _M_get_insert_equal_pos(const key_type& __k)

  9. {

  10. typedef pair<_Base_ptr, _Base_ptr> _Res;

  11. _Link_type __x = _M_begin();

  12. _Link_type __y = _M_end();

  13. while (__x != 0)//寻找合适的插入点

  14. {

  15. __y = __x;

  16. __x = _M_impl._M_key_compare(__k, _S_key(__x)) ?

  17. _S_left(__x) : _S_right(__x);//遇大往左,遇小往右

  18. }

  19. return _Res(__x, __y);//x为插入点,y为插入点的父结点

  20. }

_M_insert_unique的元素插入操作

 
  1. template<typename _Key, typename _Val, typename _KeyOfValue,

  2. typename _Compare, typename _Alloc>

  3. #if __cplusplus >= 201103L

  4. template<typename _Arg>

  5. #endif

  6. pair<typename _Rb_tree<_Key, _Val, _KeyOfValue,

  7. _Compare, _Alloc>::iterator, bool>

  8. _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::

  9. #if __cplusplus >= 201103L

  10. _M_insert_unique(_Arg&& __v)

  11. #else

  12. _M_insert_unique(const _Val& __v)

  13. #endif

  14. {

  15. typedef pair<iterator, bool> _Res;

  16. pair<_Base_ptr, _Base_ptr> __res

  17. = _M_get_insert_unique_pos(_KeyOfValue()(__v));

  18. if (__res.second)

  19. return _Res(_M_insert_(__res.first, __res.second,

  20. _GLIBCXX_FORWARD(_Arg, __v)),

  21. true);

  22. return _Res(iterator(static_cast<_Link_type>(__res.first)), false);

  23. }

看下_M_get_insert_unique_pos的主要实现:

1. 插入新值,不允许重复,若重复插入无效
2. 返回值是个pair:第一个元素是rb-tree迭代器指向新增结点;第二个表示成功与否

 
  1. template<typename _Key, typename _Val, typename _KeyOfValue,

  2. typename _Compare, typename _Alloc>

  3. pair<typename _Rb_tree<_Key, _Val, _KeyOfValue,

  4. _Compare, _Alloc>::_Base_ptr,

  5. typename _Rb_tree<_Key, _Val, _KeyOfValue,

  6. _Compare, _Alloc>::_Base_ptr>

  7. _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::

  8. _M_get_insert_unique_pos(const key_type& __k)

  9. {

  10. typedef pair<_Base_ptr, _Base_ptr> _Res;

  11. _Link_type __x = _M_begin();

  12. _Link_type __y = _M_end();

  13. bool __comp = true;

  14. while (__x != 0)//从根节点开始,寻找合适的插入点

  15. {

  16. __y = __x;

  17. __comp = _M_impl._M_key_compare(__k, _S_key(__x));

  18. __x = __comp ? _S_left(__x) : _S_right(__x);

  19. }

  20. iterator __j = iterator(__y);//指向插入点的父结点

  21. if (__comp)//comp为true,说明插在左侧

  22. {

  23. if (__j == begin())//插入结点的父结点为最左侧结点

  24. return _Res(__x, __y);

  25. else

  26. --__j;

  27. }

  28. //新键值不与既有结点重复,于是执行安插

  29. if (_M_impl._M_key_compare(_S_key(__j._M_node), __k))

  30. return _Res(__x, __y);

  31. return _Res(__j._M_node, 0);

  32. }

_M_insert_的插入操作

__x,__p,__v分别为插入点,插入点父结点,以及新值。

 
  1. template<typename _Key, typename _Val, typename _KeyOfValue,

  2. typename _Compare, typename _Alloc>

  3. #if __cplusplus >= 201103L

  4. template<typename _Arg>

  5. #endif

  6. typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator

  7. _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::

  8. #if __cplusplus >= 201103L

  9. _M_insert_(_Base_ptr __x, _Base_ptr __p, _Arg&& __v)

  10. #else

  11. _M_insert_(_Base_ptr __x, _Base_ptr __p, const _Val& __v)

  12. #endif

  13. {

  14. bool __insert_left = (__x != 0 || __p == _M_end()

  15. || _M_impl._M_key_compare(_KeyOfValue()(__v),

  16. _S_key(__p)));

  17. _Link_type __z = _M_create_node(_GLIBCXX_FORWARD(_Arg, __v));

  18. _Rb_tree_insert_and_rebalance(__insert_left, __z, __p,

  19. this->_M_impl._M_header);

  20. ++_M_impl._M_node_count;

  21. return iterator(__z);

  22. }

_Rb_tree_insert_and_rebalance这个函数才是实现的重点,在这里会更新插入结点之后的leftmost、rightmost的更新;以及如果不满足红黑树的性质,就进行调整。

在这里需要结合:数据结构与算法——红黑树(Red Black Tree)中的几种插入情况。

 
  1. void

  2. _Rb_tree_insert_and_rebalance(const bool __insert_left,

  3. _Rb_tree_node_base* __x,

  4. _Rb_tree_node_base* __p,

  5. _Rb_tree_node_base& __header) throw ()

  6. {

  7. _Rb_tree_node_base *& __root = __header._M_parent;

  8. // Initialize fields in new node to insert.

  9. __x->_M_parent = __p;

  10. __x->_M_left = 0;

  11. __x->_M_right = 0;

  12. __x->_M_color = _S_red;

  13. // Insert.

  14. // Make new node child of parent and maintain root, leftmost and

  15. // rightmost nodes.

  16. // N.B. First node is always inserted left.

  17. if (__insert_left)

  18. {

  19. __p->_M_left = __x; // also makes leftmost = __x when __p == &__header

  20. if (__p == &__header)

  21. {

  22. __header._M_parent = __x;

  23. __header._M_right = __x;

  24. }

  25. else if (__p == __header._M_left)

  26. __header._M_left = __x; // maintain leftmost pointing to min node

  27. }

  28. else

  29. {

  30. __p->_M_right = __x;

  31. if (__p == __header._M_right)

  32. __header._M_right = __x; // maintain rightmost pointing to max node

  33. }

  34. // Rebalance.

  35. while (__x != __root

  36. && __x->_M_parent->_M_color == _S_red) //父结点为红

  37. {

  38. _Rb_tree_node_base* const __xpp = __x->_M_parent->_M_parent;//获取祖父结点

  39. if (__x->_M_parent == __xpp->_M_left) //父结点为祖父结点的左子结点

  40. {

  41. _Rb_tree_node_base* const __y = __xpp->_M_right;

  42. if (__y && __y->_M_color == _S_red) //对应状况1

  43. {

  44. __x->_M_parent->_M_color = _S_black;

  45. __y->_M_color = _S_black;

  46. __xpp->_M_color = _S_red;

  47. __x = __xpp;

  48. }

  49. else

  50. {//无伯父结点

  51. if (__x == __x->_M_parent->_M_right) //新结点为父结点的右子结点,对应状况2

  52. {

  53. __x = __x->_M_parent;

  54. local_Rb_tree_rotate_left(__x, __root);

  55. }

  56. __x->_M_parent->_M_color = _S_black;//经过左旋之后,对应状况3,需要再做一次右旋

  57. __xpp->_M_color = _S_red;

  58. local_Rb_tree_rotate_right(__xpp, __root);

  59. }

  60. }

  61. else

  62. {

  63. _Rb_tree_node_base* const __y = __xpp->_M_left;

  64. if (__y && __y->_M_color == _S_red) //类似于状况1,只不过为祖父结点的右子结点

  65. {

  66. __x->_M_parent->_M_color = _S_black;

  67. __y->_M_color = _S_black;

  68. __xpp->_M_color = _S_red;

  69. __x = __xpp;

  70. }

  71. else

  72. {

  73. if (__x == __x->_M_parent->_M_left) //类似于2,3,只不过是做相反的旋转

  74. {

  75. __x = __x->_M_parent;

  76. local_Rb_tree_rotate_right(__x, __root);

  77. }

  78. __x->_M_parent->_M_color = _S_black;

  79. __xpp->_M_color = _S_red;

  80. local_Rb_tree_rotate_left(__xpp, __root);

  81. }

  82. }

  83. }

  84. __root->_M_color = _S_black;

  85. }

状况1:

此时将当前结点的父结点和叔叔节点涂黑,祖父结点涂红;并把当前结点指向祖父结点,从新的当前结点重新开始计算。

状况2:

当前结点的父结点作为新的当前结点,以新当前结点为支点进行左旋。

状况3:

此时将父结点变为黑色,祖父结点变为红色,祖父结点作为支点进行右旋。

右旋的实现local_Rb_tree_rotate_right:

 
  1. static void

  2. local_Rb_tree_rotate_right(_Rb_tree_node_base* const __x,

  3. _Rb_tree_node_base*& __root)

  4. {

  5. _Rb_tree_node_base* const __y = __x->_M_left;

  6. __x->_M_left = __y->_M_right;

  7. if (__y->_M_right != 0)

  8. __y->_M_right->_M_parent = __x;

  9. __y->_M_parent = __x->_M_parent;

  10. if (__x == __root)

  11. __root = __y;

  12. else if (__x == __x->_M_parent->_M_right)

  13. __x->_M_parent->_M_right = __y;

  14. else

  15. __x->_M_parent->_M_left = __y;

  16. __y->_M_right = __x;

  17. __x->_M_parent = __y;

  18. }

旋转

左旋的实现local_Rb_tree_rotate_left:

 
  1. static void

  2. local_Rb_tree_rotate_left(_Rb_tree_node_base* const __x,

  3. _Rb_tree_node_base*& __root)

  4. {

  5. _Rb_tree_node_base* const __y = __x->_M_right;

  6. __x->_M_right = __y->_M_left;

  7. if (__y->_M_left !=0)

  8. __y->_M_left->_M_parent = __x;

  9. __y->_M_parent = __x->_M_parent;

  10. if (__x == __root)

  11. __root = __y;

  12. else if (__x == __x->_M_parent->_M_left)

  13. __x->_M_parent->_M_left = __y;

  14. else

  15. __x->_M_parent->_M_right = __y;

  16. __y->_M_left = __x;

  17. __x->_M_parent = __y;

  18. }

以上参考:

(1742条消息) C++进阶——STL源码之红黑树(_Rb_tree)__m_get_insert_unique_pos_&动感超人的博客-CSDN博客

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值