备注:
本读书笔记基于侯捷先生的《STL源码剖析》,截图和注释版权均属于原作者所有。
本读书笔记中的源码部分直接拷贝自SGI-STL,部分代码删除了头部的版权注释,但代码版权属于原作者。
小弟初看stl,很多代码都不是太懂,注释可能有很多错误,还请路过的各位大牛多多给予指导。
为了降低学习难度,作者这里换到了SGI-STL-2.91.57的源码来学习,代码下载地址为【 http://jjhou.boolan.com/jjwbooks-tass.htm 】
之前笔记了下【 维基百科中关于红黑树的介绍 】,这里笔记下STL中的代码实现,部分代码为了便于理解,使用了前面的图。
stl_tree.h:
typedef bool __rb_tree_color_type; |
const __rb_tree_color_type __rb_tree_red = false ; |
const __rb_tree_color_type __rb_tree_black = true ; |
struct __rb_tree_node_base |
typedef __rb_tree_color_type color_type; |
typedef __rb_tree_node_base* base_ptr; |
static base_ptr minimum(base_ptr x) |
while (x->left != 0) x = x->left; |
static base_ptr maximum(base_ptr x) |
while (x->right != 0) x = x->right; |
struct __rb_tree_node : public __rb_tree_node_base |
typedef __rb_tree_node<Value>* link_type; |
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 y = node->parent; |
while (node == y->right) { |
if (node->color == __rb_tree_red && |
node->parent->parent == node) |
else if (node->left != 0) { |
base_ptr y = node->parent; |
while (node == y->left) { |
increment和decrement的一些操作比较复杂,这里先画张图,将STL中的节点的关系标下,如下图:
template < class Value, class Ref, class Ptr> |
struct __rb_tree_iterator : public __rb_tree_base_iterator |
typedef Value value_type; |
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(link_type x) { node = x; } |
__rb_tree_iterator( const iterator& it) { node = it.node; } |
reference operator*() const { return link_type(node)->value_field; } |
#ifndef __SGI_STL_NO_ARROW_OPERATOR |
pointer operator->() const { return &(operator*()); } |
#endif /* __SGI_STL_NO_ARROW_OPERATOR */ |
self& operator++() { increment(); return * this ; } |
self& operator--() { decrement(); return * this ; } |
inline bool operator==( const __rb_tree_base_iterator& x, |
const __rb_tree_base_iterator& y) { |
inline bool operator!=( const __rb_tree_base_iterator& x, |
const __rb_tree_base_iterator& y) { |
#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION |
inline bidirectional_iterator_tag |
iterator_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>&) { |
#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ |
左旋:
__rb_tree_rotate_left(__rb_tree_node_base* x, __rb_tree_node_base*& root) |
__rb_tree_node_base* y = x->right; |
else if (x == x->parent->left) |
如下图:
右旋:
__rb_tree_rotate_right(__rb_tree_node_base* x, __rb_tree_node_base*& root) |
__rb_tree_node_base* y = x->left; |
else if (x == x->parent->right) |
如下图:
__rb_tree_rebalance(__rb_tree_node_base* x, __rb_tree_node_base*& root) |
x->color = __rb_tree_red; |
while (x != root && x->parent->color == __rb_tree_red) |
if (x->parent == x->parent->parent->left) { |
__rb_tree_node_base* y = x->parent->parent->right; |
if (y && y->color == __rb_tree_red) { |
x->parent->color = __rb_tree_black; |
y->color = __rb_tree_black; |
x->parent->parent->color = __rb_tree_red; |
if (x == x->parent->right) |
__rb_tree_rotate_left(x, root); |
x->parent->color = __rb_tree_black; |
x->parent->parent->color = __rb_tree_red; |
__rb_tree_rotate_right(x->parent->parent, root); |
__rb_tree_node_base* y = x->parent->parent->left; |
if (y && y->color == __rb_tree_red) { |
x->parent->color = __rb_tree_black; |
y->color = __rb_tree_black; |
x->parent->parent->color = __rb_tree_red; |
if (x == x->parent->left) { |
__rb_tree_rotate_right(x, root); |
x->parent->color = __rb_tree_black; |
x->parent->parent->color = __rb_tree_red; |
__rb_tree_rotate_left(x->parent->parent, root); |
root->color = __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 (x) x->parent = y->parent; |
else if (z->parent->left == z) |
__STD::swap(y->color, z->color); |
if (x) x->parent = y->parent; |
if (z->parent->left == z) |
leftmost = __rb_tree_node_base::minimum(x); |
rightmost = __rb_tree_node_base::maximum(x); |
if (y->color != __rb_tree_red) { |
while (x != root && (x == 0 || x->color == __rb_tree_black)) |
if (x == x_parent->left) { |
__rb_tree_node_base* w = x_parent->right; |
if (w->color == __rb_tree_red) { |
w->color = __rb_tree_black; |
x_parent->color = __rb_tree_red; |
__rb_tree_rotate_left(x_parent, root); |
if ((w->left == 0 || w->left->color == __rb_tree_black) && |
(w->right == 0 || w->right->color == __rb_tree_black)) { |
w->color = __rb_tree_red; |
x_parent = x_parent->parent; |
if (w->right == 0 || w->right->color == __rb_tree_black) { |
if (w->left) w->left->color = __rb_tree_black; |
w->color = __rb_tree_red; |
__rb_tree_rotate_right(w, root); |
w->color = x_parent->color; |
x_parent->color = __rb_tree_black; |
if (w->right) w->right->color = __rb_tree_black; |
__rb_tree_rotate_left(x_parent, root); |
__rb_tree_node_base* w = x_parent->left; |
if (w->color == __rb_tree_red) { |
w->color = __rb_tree_black; |
x_parent->color = __rb_tree_red; |
__rb_tree_rotate_right(x_parent, root); |
if ((w->right == 0 || w->right->color == __rb_tree_black) && |
(w->left == 0 || w->left->color == __rb_tree_black)) { |
w->color = __rb_tree_red; |
x_parent = x_parent->parent; |
if (w->left == 0 || w->left->color == __rb_tree_black) { |
if (w->right) w->right->color = __rb_tree_black; |
w->color = __rb_tree_red; |
__rb_tree_rotate_left(w, root); |
w->color = x_parent->color; |
x_parent->color = __rb_tree_black; |
if (w->left) w->left->color = __rb_tree_black; |
__rb_tree_rotate_right(x_parent, root); |
if (x) x->color = __rb_tree_black; |
备注:以下代码只做了部分笔记,后续补全吧。
template < class Key, class Value, class KeyOfValue, class Compare, |
typedef void * void_pointer; |
typedef __rb_tree_node_base* base_ptr; |
typedef __rb_tree_node<Value> rb_tree_node; |
typedef simple_alloc<rb_tree_node, Alloc> rb_tree_node_allocator; |
typedef __rb_tree_color_type color_type; |
typedef Value value_type; |
typedef value_type* pointer; |
typedef const value_type* const_pointer; |
typedef value_type& reference; |
typedef const value_type& const_reference; |
typedef rb_tree_node* link_type; |
typedef size_t size_type; |
typedef ptrdiff_t difference_type; |
link_type get_node() { return rb_tree_node_allocator::allocate(); } |
void put_node(link_type p) { rb_tree_node_allocator::deallocate(p); } |
link_type create_node( const value_type& x) { |
link_type tmp = get_node(); |
construct(&tmp->value_field, x); |
__STL_UNWIND(put_node(tmp)); |
link_type clone_node(link_type x) { |
link_type tmp = create_node(x->value_field); |
void destroy_node(link_type p) { |
destroy(&p->value_field); |
link_type& root() const { return (link_type&) header->parent; } |
link_type& leftmost() const { return (link_type&) header->left; } |
link_type& rightmost() const { return (link_type&) header->right; } |
static link_type& left(link_type x) { return (link_type&)(x->left); } |
static link_type& right(link_type x) { return (link_type&)(x->right); } |
static link_type& parent(link_type x) { return (link_type&)(x->parent); } |
static reference value(link_type x) { return x->value_field; } |
static const Key& key(link_type x) { return KeyOfValue()(value(x)); } |
static color_type& color(link_type x) { return (color_type&)(x->color); } |
static link_type& left(base_ptr x) { return (link_type&)(x->left); } |
static link_type& right(base_ptr x) { return (link_type&)(x->right); } |
static link_type& parent(base_ptr x) { return (link_type&)(x->parent); } |
static reference value(base_ptr x) { return ((link_type)x)->value_field; } |
static const Key& key(base_ptr x) { return KeyOfValue()(value(link_type(x)));} |
static color_type& color(base_ptr x) { return (color_type&)(link_type(x)->color); } |
static link_type minimum(link_type x) { |
return (link_type) __rb_tree_node_base::minimum(x); |
static link_type maximum(link_type x) { |
return (link_type) __rb_tree_node_base::maximum(x); |
typedef __rb_tree_iterator<value_type, reference, pointer> iterator; |
typedef __rb_tree_iterator<value_type, const_reference, const_pointer> |
#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION |
typedef reverse_iterator<const_iterator> const_reverse_iterator; |
typedef reverse_iterator<iterator> reverse_iterator; |
#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ |
typedef reverse_bidirectional_iterator<iterator, value_type, reference, |
typedef reverse_bidirectional_iterator<const_iterator, value_type, |
const_reference, difference_type> |
#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ |
iterator __insert(base_ptr x, base_ptr y, const value_type& v); |
link_type __copy(link_type x, link_type p); |
void __erase(link_type x); |
color(header) = __rb_tree_red; |
rb_tree( const Compare& comp = Compare()) |
: node_count(0), key_compare(comp) { init(); } |
rb_tree( const rb_tree<Key, Value, KeyOfValue, Compare, Alloc>& x) |
: node_count(0), key_compare(x.key_compare) |
color(header) = __rb_tree_red; |
root() = __copy(x.root(), header); |
__STL_UNWIND(put_node(header)); |
leftmost() = minimum(root()); |
rightmost() = maximum(root()); |
node_count = x.node_count; |
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>& |
operator=( const rb_tree<Key, Value, KeyOfValue, Compare, Alloc>& x); |
Compare key_comp() const { return key_compare; } |
iterator begin() { return leftmost(); } |
const_iterator begin() const { return leftmost(); } |
iterator end() { return header; } |
const_iterator end() const { return header; } |
reverse_iterator rbegin() { return reverse_iterator(end()); } |
const_reverse_iterator rbegin() const { |
return const_reverse_iterator(end()); |
reverse_iterator rend() { return reverse_iterator(begin()); } |
const_reverse_iterator rend() const { |
return const_reverse_iterator(begin()); |
bool empty() const { return node_count == 0; } |
size_type size() const { return node_count; } |
size_type max_size() const { return size_type(-1); } |
void swap(rb_tree<Key, Value, KeyOfValue, Compare, Alloc>& t) { |
__STD::swap(header, t.header); |
__STD::swap(node_count, t.node_count); |
__STD::swap(key_compare, t.key_compare); |
pair<iterator, bool > insert_unique( const value_type& x); |
iterator insert_equal( const value_type& x); |
iterator insert_unique(iterator position, const value_type& x); |
iterator insert_equal(iterator position, const value_type& x); |
#ifdef __STL_MEMBER_TEMPLATES |
template < class InputIterator> |
void insert_unique(InputIterator first, InputIterator last); |
template < class InputIterator> |
void insert_equal(InputIterator first, InputIterator last); |
#else /* __STL_MEMBER_TEMPLATES */ |
void insert_unique(const_iterator first, const_iterator last); |
void insert_unique( const value_type* first, const value_type* last); |
void insert_equal(const_iterator first, const_iterator last); |
void insert_equal( const value_type* first, const value_type* last); |
#endif /* __STL_MEMBER_TEMPLATES */ |
void erase(iterator position); |
size_type erase( const key_type& x); |
void erase(iterator first, iterator last); |
void erase( const key_type* first, const key_type* last); |
iterator find( const key_type& x); |
const_iterator find( const key_type& x) const ; |
size_type count( const key_type& x) const ; |
iterator lower_bound( const key_type& x); |
const_iterator lower_bound( const key_type& x) const ; |
iterator upper_bound( const key_type& x); |
const_iterator upper_bound( const key_type& x) const ; |
pair<iterator,iterator> equal_range( const key_type& x); |
pair<const_iterator, const_iterator> equal_range( const key_type& x) const ; |
bool __rb_verify() const ; |
template < class Key, class Value, class KeyOfValue, class Compare, class Alloc> |
inline bool operator==( const rb_tree<Key, Value, KeyOfValue, Compare, Alloc>& x, |
const rb_tree<Key, Value, KeyOfValue, Compare, Alloc>& y) { |
return x.size() == y.size() && equal(x.begin(), x.end(), y.begin()); |
template < class Key, class Value, class KeyOfValue, class Compare, class Alloc> |
inline bool operator<( const rb_tree<Key, Value, KeyOfValue, Compare, Alloc>& x, |
const rb_tree<Key, Value, KeyOfValue, Compare, Alloc>& y) { |
return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); |
#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER |
template < class Key, class Value, class KeyOfValue, class Compare, class Alloc> |
inline void swap(rb_tree<Key, Value, KeyOfValue, Compare, Alloc>& x, |
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>& y) { |
#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ |
template < class Key, class Value, class KeyOfValue, class Compare, class Alloc> |
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>& |
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>:: |
operator=( const rb_tree<Key, Value, KeyOfValue, Compare, Alloc>& x) { |
key_compare = x.key_compare; |
root() = __copy(x.root(), header); |
leftmost() = minimum(root()); |
rightmost() = maximum(root()); |
node_count = x.node_count; |
template < class Key, class Value, class KeyOfValue, class Compare, class Alloc> |
typename rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::iterator |
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>:: |
__insert(base_ptr x_, base_ptr y_, const Value& v) { |
link_type x = (link_type) x_; |
link_type y = (link_type) y_; |
if (y == header || x != 0 || key_compare(KeyOfValue()(v), key(y))) { |
else if (y == leftmost()) |
__rb_tree_rebalance(z, header->parent); |
template < class Key, class Value, class KeyOfValue, class Compare, class Alloc> |
typename rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::iterator |
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::insert_equal( const Value& v) |
x = key_compare(KeyOfValue()(v), key(x)) ? left(x) : right(x); |
return __insert(x, y, v); |
template < class Key, class Value, class KeyOfValue, class Compare, class Alloc> |
pair< typename rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::iterator, bool > |
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::insert_unique( const Value& v) |
comp = key_compare(KeyOfValue()(v), key(x)); |
x = comp ? left(x) : right(x); |
iterator j = iterator(y); |
return pair<iterator, bool >(__insert(x, y, v), true ); |
if (key_compare(key(j.node), KeyOfValue()(v))) |
return pair<iterator, bool >(__insert(x, y, v), true ); |
return pair<iterator, bool >(j, false ); |
template < class Key, class Val, class KeyOfValue, class Compare, class Alloc> |
typename rb_tree<Key, Val, KeyOfValue, Compare, Alloc>::iterator |
rb_tree<Key, Val, KeyOfValue, Compare, Alloc>::insert_unique(iterator position, |
if (position.node == header->left) |
if (size() > 0 && key_compare(KeyOfValue()(v), key(position.node))) |
return __insert(position.node, position.node, v); |
return insert_unique(v).first; |
else if (position.node == header) |
if (key_compare(key(rightmost()), KeyOfValue()(v))) |
return __insert(0, rightmost(), v); |
return insert_unique(v).first; |
iterator before = position; |
if (key_compare(key(before.node), KeyOfValue()(v)) |
&& key_compare(KeyOfValue()(v), key(position.node))) |
if (right(before.node) == 0) |
return __insert(0, before.node, v); |
return __insert(position.node, position.node, v); |
return insert_unique(v).first; |
template < class Key, class Val, class KeyOfValue, class Compare, class Alloc> |
typename rb_tree<Key, Val, KeyOfValue, Compare, Alloc>::iterator |
rb_tree<Key, Val, KeyOfValue, Compare, Alloc>::insert_equal(iterator position, |
if (position.node == header->left) |
if (size() > 0 && key_compare(KeyOfValue()(v), key(position.node))) |
return __insert(position.node, position.node, v); |
else if (position.node == header) |
if (!key_compare(KeyOfValue()(v), key(rightmost()))) |
return __insert(0, rightmost(), v); |
iterator before = position; |
if (!key_compare(KeyOfValue()(v), key(before.node)) |
&& !key_compare(key(position.node), KeyOfValue()(v))) |
if (right(before.node) == 0) |
return __insert(0, before.node, v); |
return __insert(position.node, position.node, v); |
#ifdef __STL_MEMBER_TEMPLATES |
template < class K, class V, class KoV, class Cmp, class Al> template < class II> |
void rb_tree<K, V, KoV, Cmp, Al>::insert_equal(II first, II last) { |
for ( ; first != last; ++first) |
template < class K, class V, class KoV, class Cmp, class Al> template < class II> |
void rb_tree<K, V, KoV, Cmp, Al>::insert_unique(II first, II last) { |
for ( ; first != last; ++first) |
#else /* __STL_MEMBER_TEMPLATES */ |
template < class K, class V, class KoV, class Cmp, class Al> |
rb_tree<K, V, KoV, Cmp, Al>::insert_equal( const V* first, const V* last) { |
for ( ; first != last; ++first) |
template < class K, class V, class KoV, class Cmp, class Al> |
rb_tree<K, V, KoV, Cmp, Al>::insert_equal(const_iterator first, |
for ( ; first != last; ++first) |
template < class K, class V, class KoV, class Cmp, class A> |
rb_tree<K, V, KoV, Cmp, A>::insert_unique( const V* first, const V* last) { |
for ( ; first != last; ++first) |
template < class K, class V, class KoV, class Cmp, class A> |
rb_tree<K, V, KoV, Cmp, A>::insert_unique(const_iterator first, |
for ( ; first != last; ++first) |
#endif /* __STL_MEMBER_TEMPLATES */ |
template < class Key, class Value, class KeyOfValue, class Compare, class Alloc> |
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::erase(iterator position) { |
link_type y = (link_type) __rb_tree_rebalance_for_erase(position.node, |
template < class Key, class Value, class KeyOfValue, class Compare, class Alloc> |
typename rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::size_type |
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::erase( const Key& x) { |
pair<iterator,iterator> p = equal_range(x); |
distance(p.first, p.second, n); |
erase(p.first, p.second); |
template < class K, class V, class KeyOfValue, class Compare, class Alloc> |
typename rb_tree<K, V, KeyOfValue, Compare, Alloc>::link_type |
rb_tree<K, V, KeyOfValue, Compare, Alloc>::__copy(link_type x, link_type p) { |
link_type top = clone_node(x); |
top->right = __copy(right(x), top); |
link_type y = clone_node(x); |
y->right = __copy(right(x), y); |
__STL_UNWIND(__erase(top)); |
template < class Key, class Value, class KeyOfValue, class Compare, class Alloc> |
void rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::__erase(link_type x) { |
template < class Key, class Value, class KeyOfValue, class Compare, class Alloc> |
void rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::erase(iterator first, |
if (first == begin() && last == end()) |
while (first != last) erase(first++); |
template < class Key, class Value, class KeyOfValue, class Compare, class Alloc> |
void rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::erase( const Key* first, |
while (first != last) erase(*first++); |
template < class Key, class Value, class KeyOfValue, class Compare, class Alloc> |
typename rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::iterator |
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::find( const Key& k) { |
if (!key_compare(key(x), k)) |
iterator j = iterator(y); |
return (j == end() || key_compare(k, key(j.node))) ? end() : j; |
template < class Key, class Value, class KeyOfValue, class Compare, class Alloc> |
typename rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::const_iterator |
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::find( const Key& k) const { |
if (!key_compare(key(x), k)) |
const_iterator j = const_iterator(y); |
return (j == end() || key_compare(k, key(j.node))) ? end() : j; |
template < class Key, class Value, class KeyOfValue, class Compare, class Alloc> |
typename rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::size_type |
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::count( const Key& k) const { |
pair<const_iterator, const_iterator> p = equal_range(k); |
distance(p.first, p.second, n); |
template < class Key, class Value, class KeyOfValue, class Compare, class Alloc> |
typename rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::iterator |
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::lower_bound( const Key& k) { |
if (!key_compare(key(x), k)) |
template < class Key, class Value, class KeyOfValue, class Compare, class Alloc> |
typename rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::const_iterator |
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::lower_bound( const Key& k) const { |
if (!key_compare(key(x), k)) |
return const_iterator(y); |
template < class Key, class Value, class KeyOfValue, class Compare, class Alloc> |
typename rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::iterator |
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::upper_bound( const Key& k) { |
if (key_compare(k, key(x))) |
template < class Key, class Value, class KeyOfValue, class Compare, class Alloc> |
typename rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::const_iterator |
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::upper_bound( const Key& k) const { |
if (key_compare(k, key(x))) |
return const_iterator(y); |
template < class Key, class Value, class KeyOfValue, class Compare, class Alloc> |
inline pair< typename rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::iterator, |
typename rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::iterator> |
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::equal_range( const Key& k) { |
return pair<iterator, iterator>(lower_bound(k), upper_bound(k)); |
template < class Key, class Value, class KoV, class Compare, class Alloc> |
inline pair< typename rb_tree<Key, Value, KoV, Compare, Alloc>::const_iterator, |
typename rb_tree<Key, Value, KoV, Compare, Alloc>::const_iterator> |
rb_tree<Key, Value, KoV, Compare, Alloc>::equal_range( const Key& k) const { |
return pair<const_iterator,const_iterator>(lower_bound(k), upper_bound(k)); |
inline int __black_count(__rb_tree_node_base* node, __rb_tree_node_base* root) |
int bc = node->color == __rb_tree_black ? 1 : 0; |
return bc + __black_count(node->parent, root); |
template < class Key, class Value, class KeyOfValue, class Compare, class Alloc> |
rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::__rb_verify() const |
if (node_count == 0 || begin() == end()) |
return node_count == 0 && begin() == end() && |
header->left == header && header->right == header; |
int len = __black_count(leftmost(), root()); |
for (const_iterator it = begin(); it != end(); ++it) { |
link_type x = (link_type) it.node; |
if (x->color == __rb_tree_red) |
if ((L && L->color == __rb_tree_red) || |
(R && R->color == __rb_tree_red)) |
if (L && key_compare(key(x), key(L))) |
if (R && key_compare(key(R), key(x))) |
if (!L && !R && __black_count(x, root()) != len) |
if (leftmost() != __rb_tree_node_base::minimum(root())) |
if (rightmost() != __rb_tree_node_base::maximum(root())) |
发表评论