_tree.c

来自「stl的源码」· C语言 代码 · 共 731 行 · 第 1/2 页

C
731
字号
    __new_node = _M_create_node(__val);    _S_left(__parent) = __new_node;    if (__parent == _M_leftmost())      _M_leftmost() = __new_node;   // maintain _M_leftmost() pointing to min node  }  else {    __new_node = _M_create_node(__val);    _S_right(__parent) = __new_node;    if (__parent == _M_rightmost())      _M_rightmost() = __new_node;  // maintain _M_rightmost() pointing to max node  }  _S_parent(__new_node) = __parent;  _Rb_global_inst::_Rebalance(__new_node, this->_M_header._M_data._M_parent);  ++_M_node_count;  return iterator(__new_node);}template <class _Key, class _Compare,          class _Value, class _KeyOfValue, class _Traits, class _Alloc>__iterator___Rb_tree<_Key,_Compare,_Value,_KeyOfValue,_Traits,_Alloc> ::insert_equal(const _Value& __val) {  _Base_ptr __y = &this->_M_header._M_data;  _Base_ptr __x = _M_root();  while (__x != 0) {    __y = __x;    if (_M_key_compare(_KeyOfValue()(__val), _S_key(__x))) {      __x = _S_left(__x);    }    else      __x = _S_right(__x);  }  return _M_insert(__y, __val, __x);}template <class _Key, class _Compare,          class _Value, class _KeyOfValue, class _Traits, class _Alloc>pair<__iterator__, bool>_Rb_tree<_Key,_Compare,_Value,_KeyOfValue,_Traits,_Alloc> ::insert_unique(const _Value& __val) {  _Base_ptr __y = &this->_M_header._M_data;  _Base_ptr __x = _M_root();  bool __comp = true;  while (__x != 0) {    __y = __x;    __comp = _M_key_compare(_KeyOfValue()(__val), _S_key(__x));    __x = __comp ? _S_left(__x) : _S_right(__x);  }  iterator __j = iterator(__y);  if (__comp) {    if (__j == begin())      return pair<iterator,bool>(_M_insert(__y, __val, /* __x*/ __y), true);    else      --__j;  }  if (_M_key_compare(_S_key(__j._M_node), _KeyOfValue()(__val))) {    return pair<iterator,bool>(_M_insert(__y, __val, __x), true);  }  return pair<iterator,bool>(__j, false);}// Modifications CRP 7/10/00 as noted to improve conformance and// efficiency.template <class _Key, class _Compare,          class _Value, class _KeyOfValue, class _Traits, class _Alloc>__iterator___Rb_tree<_Key,_Compare,_Value,_KeyOfValue,_Traits,_Alloc> ::insert_unique(iterator __position,                                                                          const _Value& __val) {  if (__position._M_node == this->_M_header._M_data._M_left) { // begin()    // if the container is empty, fall back on insert_unique.    if (empty())      return insert_unique(__val).first;    if (_M_key_compare(_KeyOfValue()(__val), _S_key(__position._M_node))) {      return _M_insert(__position._M_node, __val, __position._M_node);    }    // first argument just needs to be non-null    else {      bool __comp_pos_v = _M_key_compare( _S_key(__position._M_node), _KeyOfValue()(__val) );      if (__comp_pos_v == false)  // compare > and compare < both false so compare equal        return __position;      //Below __comp_pos_v == true      // Standard-conformance - does the insertion point fall immediately AFTER      // the hint?      iterator __after = __position;      ++__after;      // Check for only one member -- in that case, __position points to itself,      // and attempting to increment will cause an infinite loop.      if (__after._M_node == &this->_M_header._M_data)        // Check guarantees exactly one member, so comparison was already        // performed and we know the result; skip repeating it in _M_insert        // by specifying a non-zero fourth argument.        return _M_insert(__position._M_node, __val, 0, __position._M_node);      // All other cases:      // Optimization to catch insert-equivalent -- save comparison results,      // and we get this for free.      if (_M_key_compare( _KeyOfValue()(__val), _S_key(__after._M_node) )) {        if (_S_right(__position._M_node) == 0)          return _M_insert(__position._M_node, __val, 0, __position._M_node);        else          return _M_insert(__after._M_node, __val, __after._M_node);      }      else {        return insert_unique(__val).first;      }    }  }  else if (__position._M_node == &this->_M_header._M_data) { // end()    if (_M_key_compare(_S_key(_M_rightmost()), _KeyOfValue()(__val))) {        // pass along to _M_insert that it can skip comparing        // v, Key ; since compare Key, v was true, compare v, Key must be false.        return _M_insert(_M_rightmost(), __val, 0, __position._M_node); // Last argument only needs to be non-null    }    else      return insert_unique(__val).first;  }  else {    iterator __before = __position;    --__before;    bool __comp_v_pos = _M_key_compare(_KeyOfValue()(__val), _S_key(__position._M_node));    if (__comp_v_pos        && _M_key_compare( _S_key(__before._M_node), _KeyOfValue()(__val) )) {      if (_S_right(__before._M_node) == 0)        return _M_insert(__before._M_node, __val, 0, __before._M_node); // Last argument only needs to be non-null      else        return _M_insert(__position._M_node, __val, __position._M_node);      // first argument just needs to be non-null    }    else {      // Does the insertion point fall immediately AFTER the hint?      iterator __after = __position;      ++__after;      // Optimization to catch equivalent cases and avoid unnecessary comparisons      bool __comp_pos_v = !__comp_v_pos;  // Stored this result earlier      // If the earlier comparison was true, this comparison doesn't need to be      // performed because it must be false.  However, if the earlier comparison      // was false, we need to perform this one because in the equal case, both will      // be false.      if (!__comp_v_pos) {        __comp_pos_v = _M_key_compare(_S_key(__position._M_node), _KeyOfValue()(__val));      }      if ( (!__comp_v_pos) // comp_v_pos true implies comp_v_pos false          && __comp_pos_v          && (__after._M_node == &this->_M_header._M_data ||              _M_key_compare( _KeyOfValue()(__val), _S_key(__after._M_node) ))) {        if (_S_right(__position._M_node) == 0)          return _M_insert(__position._M_node, __val, 0, __position._M_node);        else          return _M_insert(__after._M_node, __val, __after._M_node);      } else {        // Test for equivalent case        if (__comp_v_pos == __comp_pos_v)          return __position;        else          return insert_unique(__val).first;      }    }  }}template <class _Key, class _Compare,          class _Value, class _KeyOfValue, class _Traits, class _Alloc>__iterator___Rb_tree<_Key,_Compare,_Value,_KeyOfValue,_Traits,_Alloc> ::insert_equal(iterator __position,                                                                         const _Value& __val) {  if (__position._M_node == this->_M_header._M_data._M_left) { // begin()    // Check for zero members    if (size() <= 0)        return insert_equal(__val);    if (!_M_key_compare(_S_key(__position._M_node), _KeyOfValue()(__val)))      return _M_insert(__position._M_node, __val, __position._M_node);    else {      // Check for only one member      if (__position._M_node->_M_left == __position._M_node)        // Unlike insert_unique, can't avoid doing a comparison here.        return _M_insert(__position._M_node, __val);      // All other cases:      // Standard-conformance - does the insertion point fall immediately AFTER      // the hint?      iterator __after = __position;      ++__after;      // Already know that compare(pos, v) must be true!      // Therefore, we want to know if compare(after, v) is false.      // (i.e., we now pos < v, now we want to know if v <= after)      // If not, invalid hint.      if ( __after._M_node == &this->_M_header._M_data ||           !_M_key_compare( _S_key(__after._M_node), _KeyOfValue()(__val) ) ) {        if (_S_right(__position._M_node) == 0)          return _M_insert(__position._M_node, __val, 0, __position._M_node);        else          return _M_insert(__after._M_node, __val, __after._M_node);      }      else { // Invalid hint        return insert_equal(__val);      }    }  }  else if (__position._M_node == &this->_M_header._M_data) { // end()    if (!_M_key_compare(_KeyOfValue()(__val), _S_key(_M_rightmost())))      return _M_insert(_M_rightmost(), __val, 0, __position._M_node); // Last argument only needs to be non-null    else {      return insert_equal(__val);    }  }  else {    iterator __before = __position;    --__before;    // store the result of the comparison between pos and v so    // that we don't have to do it again later.  Note that this reverses the shortcut    // on the if, possibly harming efficiency in comparisons; I think the harm will    // be negligible, and to do what I want to do (save the result of a comparison so    // that it can be re-used) there is no alternative.  Test here is for before <= v <= pos.    bool __comp_pos_v = _M_key_compare(_S_key(__position._M_node), _KeyOfValue()(__val));    if (!__comp_pos_v &&        !_M_key_compare(_KeyOfValue()(__val), _S_key(__before._M_node))) {      if (_S_right(__before._M_node) == 0)        return _M_insert(__before._M_node, __val, 0, __before._M_node); // Last argument only needs to be non-null      else        return _M_insert(__position._M_node, __val, __position._M_node);    }    else {      // Does the insertion point fall immediately AFTER the hint?      // Test for pos < v <= after      iterator __after = __position;      ++__after;      if (__comp_pos_v &&          ( __after._M_node == &this->_M_header._M_data ||            !_M_key_compare( _S_key(__after._M_node), _KeyOfValue()(__val) ) ) ) {        if (_S_right(__position._M_node) == 0)          return _M_insert(__position._M_node, __val, 0, __position._M_node);        else          return _M_insert(__after._M_node, __val, __after._M_node);      }      else { // Invalid hint        return insert_equal(__val);      }    }  }}template <class _Key, class _Compare,          class _Value, class _KeyOfValue, class _Traits, class _Alloc>_Rb_tree_node_base*_Rb_tree<_Key,_Compare,_Value,_KeyOfValue,_Traits,_Alloc> ::_M_copy(_Rb_tree_node_base* __x,                                                                    _Rb_tree_node_base* __p) {  // structural copy.  __x and __p must be non-null.  _Base_ptr __top = _M_clone_node(__x);  _S_parent(__top) = __p;  _STLP_TRY {    if (_S_right(__x))      _S_right(__top) = _M_copy(_S_right(__x), __top);    __p = __top;    __x = _S_left(__x);    while (__x != 0) {      _Base_ptr __y = _M_clone_node(__x);      _S_left(__p) = __y;      _S_parent(__y) = __p;      if (_S_right(__x))        _S_right(__y) = _M_copy(_S_right(__x), __y);      __p = __y;      __x = _S_left(__x);    }  }  _STLP_UNWIND(_M_erase(__top))  return __top;}// this has to stay out-of-line : it's recursivetemplate <class _Key, class _Compare,          class _Value, class _KeyOfValue, class _Traits, class _Alloc>void_Rb_tree<_Key,_Compare,_Value,_KeyOfValue,_Traits,_Alloc>::_M_erase(_Rb_tree_node_base *__x) {  // erase without rebalancing  while (__x != 0) {    _M_erase(_S_right(__x));    _Base_ptr __y = _S_left(__x);    _STLP_STD::_Destroy(&_S_value(__x));    this->_M_header.deallocate(__STATIC_CAST(_Link_type, __x),1);    __x = __y;  }}#if defined (_STLP_DEBUG)inline int__black_count(_Rb_tree_node_base* __node, _Rb_tree_node_base* __root) {  if (__node == 0)    return 0;  else {    int __bc = __node->_M_color == _S_rb_tree_black ? 1 : 0;    if (__node == __root)      return __bc;    else      return __bc + __black_count(__node->_M_parent, __root);  }}template <class _Key, class _Compare,          class _Value, class _KeyOfValue, class _Traits, class _Alloc>bool _Rb_tree<_Key,_Compare,_Value,_KeyOfValue,_Traits,_Alloc>::__rb_verify() const {  if (_M_node_count == 0 || begin() == end())    return ((_M_node_count == 0) &&            (begin() == end()) &&            (this->_M_header._M_data._M_left == &this->_M_header._M_data) &&            (this->_M_header._M_data._M_right == &this->_M_header._M_data));  int __len = __black_count(_M_leftmost(), _M_root());  for (const_iterator __it = begin(); __it != end(); ++__it) {    _Base_ptr __x = __it._M_node;    _Base_ptr __L = _S_left(__x);    _Base_ptr __R = _S_right(__x);    if (__x->_M_color == _S_rb_tree_red)      if ((__L && __L->_M_color == _S_rb_tree_red) ||          (__R && __R->_M_color == _S_rb_tree_red))        return false;    if (__L && _M_key_compare(_S_key(__x), _S_key(__L)))      return false;    if (__R && _M_key_compare(_S_key(__R), _S_key(__x)))      return false;    if (!__L && !__R && __black_count(__x, _M_root()) != __len)      return false;  }  if (_M_leftmost() != _Rb_tree_node_base::_S_minimum(_M_root()))    return false;  if (_M_rightmost() != _Rb_tree_node_base::_S_maximum(_M_root()))    return false;  return true;}#endif /* _STLP_DEBUG */_STLP_MOVE_TO_STD_NAMESPACE_STLP_END_NAMESPACE#undef _Rb_tree#undef __iterator__#undef iterator#undef __size_type__#endif /*  _STLP_TREE_C */// Local Variables:// mode:C++// End:

⌨️ 快捷键说明

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