⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stl_tree.h

📁 c++ STL source code, hash and vector etc
💻 H
📖 第 1 页 / 共 3 页
字号:
/* * * Copyright (c) 1996,1997 * Silicon Graphics Computer Systems, Inc. * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation.  Silicon Graphics makes no * representations about the suitability of this software for any * purpose.  It is provided "as is" without express or implied warranty. * * * Copyright (c) 1994 * Hewlett-Packard Company * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation.  Hewlett-Packard Company makes no * representations about the suitability of this software for any * purpose.  It is provided "as is" without express or implied warranty. * * *//* NOTE: This is an internal header file, included by other STL headers. *   You should not attempt to use it directly. */#ifndef __SGI_STL_INTERNAL_TREE_H#define __SGI_STL_INTERNAL_TREE_H/*Red-black tree class, designed for use in implementing STLassociative containers (set, multiset, map, and multimap). Theinsertion and deletion algorithms are based on those in Cormen,Leiserson, and Rivest, Introduction to Algorithms (MIT Press, 1990),except that(1) the header cell is maintained with links not only to the rootbut also to the leftmost node of the tree, to enable constant timebegin(), and to the rightmost node of the tree, to enable linear timeperformance when used with the generic set algorithms (set_union,etc.);(2) when a node being deleted has two children its successor node isrelinked into its place, rather than copied, so that the onlyiterators invalidated are those referring to the deleted node.*/#include <stl_algobase.h>#include <stl_alloc.h>#include <stl_construct.h>#include <stl_function.h>__STL_BEGIN_NAMESPACE #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)#pragma set woff 1375#endiftypedef bool _Rb_tree_Color_type;const _Rb_tree_Color_type _S_rb_tree_red = false;const _Rb_tree_Color_type _S_rb_tree_black = true;struct _Rb_tree_node_base{  typedef _Rb_tree_Color_type _Color_type;  typedef _Rb_tree_node_base* _Base_ptr;  _Color_type _M_color;   _Base_ptr _M_parent;  _Base_ptr _M_left;  _Base_ptr _M_right;  static _Base_ptr _S_minimum(_Base_ptr __x)  {    while (__x->_M_left != 0) __x = __x->_M_left;    return __x;  }  static _Base_ptr _S_maximum(_Base_ptr __x)  {    while (__x->_M_right != 0) __x = __x->_M_right;    return __x;  }};template <class _Value>struct _Rb_tree_node : public _Rb_tree_node_base{  typedef _Rb_tree_node<_Value>* _Link_type;  _Value _M_value_field;};struct _Rb_tree_base_iterator{  typedef _Rb_tree_node_base::_Base_ptr _Base_ptr;  typedef bidirectional_iterator_tag iterator_category;  typedef ptrdiff_t difference_type;  _Base_ptr _M_node;  void _M_increment()  {    if (_M_node->_M_right != 0) {      _M_node = _M_node->_M_right;      while (_M_node->_M_left != 0)        _M_node = _M_node->_M_left;    }    else {      _Base_ptr __y = _M_node->_M_parent;      while (_M_node == __y->_M_right) {        _M_node = __y;        __y = __y->_M_parent;      }      if (_M_node->_M_right != __y)        _M_node = __y;    }  }  void _M_decrement()  {    if (_M_node->_M_color == _S_rb_tree_red &&        _M_node->_M_parent->_M_parent == _M_node)      _M_node = _M_node->_M_right;    else if (_M_node->_M_left != 0) {      _Base_ptr __y = _M_node->_M_left;      while (__y->_M_right != 0)        __y = __y->_M_right;      _M_node = __y;    }    else {      _Base_ptr __y = _M_node->_M_parent;      while (_M_node == __y->_M_left) {        _M_node = __y;        __y = __y->_M_parent;      }      _M_node = __y;    }  }};template <class _Value, class _Ref, class _Ptr>struct _Rb_tree_iterator : public _Rb_tree_base_iterator{  typedef _Value value_type;  typedef _Ref reference;  typedef _Ptr pointer;  typedef _Rb_tree_iterator<_Value, _Value&, _Value*>                 iterator;  typedef _Rb_tree_iterator<_Value, const _Value&, const _Value*>     const_iterator;  typedef _Rb_tree_iterator<_Value, _Ref, _Ptr>                       _Self;  typedef _Rb_tree_node<_Value>* _Link_type;  _Rb_tree_iterator() {}  _Rb_tree_iterator(_Link_type __x) { _M_node = __x; }  _Rb_tree_iterator(const iterator& __it) { _M_node = __it._M_node; }  reference operator*() const { return _Link_type(_M_node)->_M_value_field; }#ifndef __SGI_STL_NO_ARROW_OPERATOR  pointer operator->() const { return &(operator*()); }#endif /* __SGI_STL_NO_ARROW_OPERATOR */  _Self& operator++() { _M_increment(); return *this; }  _Self operator++(int) {    _Self __tmp = *this;    _M_increment();    return __tmp;  }      _Self& operator--() { _M_decrement(); return *this; }  _Self operator--(int) {    _Self __tmp = *this;    _M_decrement();    return __tmp;  }};inline bool operator==(const _Rb_tree_base_iterator& __x,                       const _Rb_tree_base_iterator& __y) {  return __x._M_node == __y._M_node;}inline bool operator!=(const _Rb_tree_base_iterator& __x,                       const _Rb_tree_base_iterator& __y) {  return __x._M_node != __y._M_node;}#ifndef __STL_CLASS_PARTIAL_SPECIALIZATIONinline bidirectional_iterator_tagiterator_category(const _Rb_tree_base_iterator&) {  return bidirectional_iterator_tag();}inline _Rb_tree_base_iterator::difference_type*distance_type(const _Rb_tree_base_iterator&) {  return (_Rb_tree_base_iterator::difference_type*) 0;}template <class _Value, class _Ref, class _Ptr>inline _Value* value_type(const _Rb_tree_iterator<_Value, _Ref, _Ptr>&) {  return (_Value*) 0;}#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */inline void _Rb_tree_rotate_left(_Rb_tree_node_base* __x, _Rb_tree_node_base*& __root){  _Rb_tree_node_base* __y = __x->_M_right;  __x->_M_right = __y->_M_left;  if (__y->_M_left !=0)    __y->_M_left->_M_parent = __x;  __y->_M_parent = __x->_M_parent;  if (__x == __root)    __root = __y;  else if (__x == __x->_M_parent->_M_left)    __x->_M_parent->_M_left = __y;  else    __x->_M_parent->_M_right = __y;  __y->_M_left = __x;  __x->_M_parent = __y;}inline void _Rb_tree_rotate_right(_Rb_tree_node_base* __x, _Rb_tree_node_base*& __root){  _Rb_tree_node_base* __y = __x->_M_left;  __x->_M_left = __y->_M_right;  if (__y->_M_right != 0)    __y->_M_right->_M_parent = __x;  __y->_M_parent = __x->_M_parent;  if (__x == __root)    __root = __y;  else if (__x == __x->_M_parent->_M_right)    __x->_M_parent->_M_right = __y;  else    __x->_M_parent->_M_left = __y;  __y->_M_right = __x;  __x->_M_parent = __y;}inline void _Rb_tree_rebalance(_Rb_tree_node_base* __x, _Rb_tree_node_base*& __root){  __x->_M_color = _S_rb_tree_red;  while (__x != __root && __x->_M_parent->_M_color == _S_rb_tree_red) {    if (__x->_M_parent == __x->_M_parent->_M_parent->_M_left) {      _Rb_tree_node_base* __y = __x->_M_parent->_M_parent->_M_right;      if (__y && __y->_M_color == _S_rb_tree_red) {        __x->_M_parent->_M_color = _S_rb_tree_black;        __y->_M_color = _S_rb_tree_black;        __x->_M_parent->_M_parent->_M_color = _S_rb_tree_red;        __x = __x->_M_parent->_M_parent;      }      else {        if (__x == __x->_M_parent->_M_right) {          __x = __x->_M_parent;          _Rb_tree_rotate_left(__x, __root);        }        __x->_M_parent->_M_color = _S_rb_tree_black;        __x->_M_parent->_M_parent->_M_color = _S_rb_tree_red;        _Rb_tree_rotate_right(__x->_M_parent->_M_parent, __root);      }    }    else {      _Rb_tree_node_base* __y = __x->_M_parent->_M_parent->_M_left;      if (__y && __y->_M_color == _S_rb_tree_red) {        __x->_M_parent->_M_color = _S_rb_tree_black;        __y->_M_color = _S_rb_tree_black;        __x->_M_parent->_M_parent->_M_color = _S_rb_tree_red;        __x = __x->_M_parent->_M_parent;      }      else {        if (__x == __x->_M_parent->_M_left) {          __x = __x->_M_parent;          _Rb_tree_rotate_right(__x, __root);        }        __x->_M_parent->_M_color = _S_rb_tree_black;        __x->_M_parent->_M_parent->_M_color = _S_rb_tree_red;        _Rb_tree_rotate_left(__x->_M_parent->_M_parent, __root);      }    }  }  __root->_M_color = _S_rb_tree_black;}inline _Rb_tree_node_base*_Rb_tree_rebalance_for_erase(_Rb_tree_node_base* __z,                             _Rb_tree_node_base*& __root,                             _Rb_tree_node_base*& __leftmost,                             _Rb_tree_node_base*& __rightmost){  _Rb_tree_node_base* __y = __z;  _Rb_tree_node_base* __x = 0;  _Rb_tree_node_base* __x_parent = 0;  if (__y->_M_left == 0)     // __z has at most one non-null child. y == z.    __x = __y->_M_right;     // __x might be null.  else    if (__y->_M_right == 0)  // __z has exactly one non-null child. y == z.      __x = __y->_M_left;    // __x is not null.    else {                   // __z has two non-null children.  Set __y to      __y = __y->_M_right;   //   __z's successor.  __x might be null.      while (__y->_M_left != 0)        __y = __y->_M_left;      __x = __y->_M_right;    }  if (__y != __z) {          // relink y in place of z.  y is z's successor    __z->_M_left->_M_parent = __y;     __y->_M_left = __z->_M_left;    if (__y != __z->_M_right) {      __x_parent = __y->_M_parent;      if (__x) __x->_M_parent = __y->_M_parent;      __y->_M_parent->_M_left = __x;      // __y must be a child of _M_left      __y->_M_right = __z->_M_right;      __z->_M_right->_M_parent = __y;    }    else      __x_parent = __y;      if (__root == __z)      __root = __y;    else if (__z->_M_parent->_M_left == __z)      __z->_M_parent->_M_left = __y;    else       __z->_M_parent->_M_right = __y;    __y->_M_parent = __z->_M_parent;    __STD::swap(__y->_M_color, __z->_M_color);    __y = __z;    // __y now points to node to be actually deleted  }  else {                        // __y == __z    __x_parent = __y->_M_parent;    if (__x) __x->_M_parent = __y->_M_parent;       if (__root == __z)      __root = __x;    else       if (__z->_M_parent->_M_left == __z)        __z->_M_parent->_M_left = __x;      else        __z->_M_parent->_M_right = __x;    if (__leftmost == __z)       if (__z->_M_right == 0)        // __z->_M_left must be null also        __leftmost = __z->_M_parent;    // makes __leftmost == _M_header if __z == __root      else        __leftmost = _Rb_tree_node_base::_S_minimum(__x);    if (__rightmost == __z)        if (__z->_M_left == 0)         // __z->_M_right must be null also        __rightmost = __z->_M_parent;      // makes __rightmost == _M_header if __z == __root      else                      // __x == __z->_M_left        __rightmost = _Rb_tree_node_base::_S_maximum(__x);  }  if (__y->_M_color != _S_rb_tree_red) {     while (__x != __root && (__x == 0 || __x->_M_color == _S_rb_tree_black))      if (__x == __x_parent->_M_left) {        _Rb_tree_node_base* __w = __x_parent->_M_right;        if (__w->_M_color == _S_rb_tree_red) {          __w->_M_color = _S_rb_tree_black;          __x_parent->_M_color = _S_rb_tree_red;          _Rb_tree_rotate_left(__x_parent, __root);          __w = __x_parent->_M_right;        }        if ((__w->_M_left == 0 ||              __w->_M_left->_M_color == _S_rb_tree_black) &&            (__w->_M_right == 0 ||              __w->_M_right->_M_color == _S_rb_tree_black)) {          __w->_M_color = _S_rb_tree_red;          __x = __x_parent;          __x_parent = __x_parent->_M_parent;        } else {          if (__w->_M_right == 0 ||               __w->_M_right->_M_color == _S_rb_tree_black) {            if (__w->_M_left) __w->_M_left->_M_color = _S_rb_tree_black;            __w->_M_color = _S_rb_tree_red;            _Rb_tree_rotate_right(__w, __root);            __w = __x_parent->_M_right;          }          __w->_M_color = __x_parent->_M_color;          __x_parent->_M_color = _S_rb_tree_black;          if (__w->_M_right) __w->_M_right->_M_color = _S_rb_tree_black;          _Rb_tree_rotate_left(__x_parent, __root);          break;        }      } else {                  // same as above, with _M_right <-> _M_left.        _Rb_tree_node_base* __w = __x_parent->_M_left;        if (__w->_M_color == _S_rb_tree_red) {          __w->_M_color = _S_rb_tree_black;          __x_parent->_M_color = _S_rb_tree_red;          _Rb_tree_rotate_right(__x_parent, __root);          __w = __x_parent->_M_left;        }        if ((__w->_M_right == 0 ||              __w->_M_right->_M_color == _S_rb_tree_black) &&            (__w->_M_left == 0 ||              __w->_M_left->_M_color == _S_rb_tree_black)) {          __w->_M_color = _S_rb_tree_red;          __x = __x_parent;          __x_parent = __x_parent->_M_parent;        } else {          if (__w->_M_left == 0 ||               __w->_M_left->_M_color == _S_rb_tree_black) {            if (__w->_M_right) __w->_M_right->_M_color = _S_rb_tree_black;            __w->_M_color = _S_rb_tree_red;            _Rb_tree_rotate_left(__w, __root);            __w = __x_parent->_M_left;          }          __w->_M_color = __x_parent->_M_color;          __x_parent->_M_color = _S_rb_tree_black;          if (__w->_M_left) __w->_M_left->_M_color = _S_rb_tree_black;          _Rb_tree_rotate_right(__x_parent, __root);          break;        }      }    if (__x) __x->_M_color = _S_rb_tree_black;  }  return __y;}// Base class to encapsulate the differences between old SGI-style// allocators and standard-conforming allocators.  In order to avoid// having an empty base class, we arbitrarily move one of rb_tree's// data members into the base class.#ifdef __STL_USE_STD_ALLOCATORS// _Base for general standard-conforming allocators.template <class _Tp, class _Alloc, bool _S_instanceless>class _Rb_tree_alloc_base {public:  typedef typename _Alloc_traits<_Tp, _Alloc>::allocator_type allocator_type;  allocator_type get_allocator() const { return _M_node_allocator; }  _Rb_tree_alloc_base(const allocator_type& __a)    : _M_node_allocator(__a), _M_header(0) {}protected:  typename _Alloc_traits<_Rb_tree_node<_Tp>, _Alloc>::allocator_type           _M_node_allocator;  _Rb_tree_node<_Tp>* _M_header;  _Rb_tree_node<_Tp>* _M_get_node()     { return _M_node_allocator.allocate(1); }  void _M_put_node(_Rb_tree_node<_Tp>* __p)     { _M_node_allocator.deallocate(__p, 1); }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -