您的位置:首页 > 编程语言 > C语言/C++

C++ young 程序库——y_binary_search_tree_base.hpp、y_red_black_tree_base.hpp 和 y_red_black_tree.hpp

2005-08-14 10:20 489 查看
文件位置:young/tree/y_binary_search_tree_base.hpp
/*
The young Library
Copyright (c) 2005 by 杨桓
Permission to use, copy, modify, distribute and sell this software 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.
The author make no representations about the suitability of this software
for any purpose. It is provided "as is" without express or implied warranty.
*/
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
#ifndef __MACRO_CPLUSPLUS_YOUNG_LIBRARY_BINARY_SEARCH_TREE_BASE_HEADER_FILE__
#define __MACRO_CPLUSPLUS_YOUNG_LIBRARY_BINARY_SEARCH_TREE_BASE_HEADER_FILE__
//-----------------------------------------------------------------------------
#include "../y_define.hpp"
//-----------------------------------------------------------------------------
__MACRO_CPLUSPLUS_YOUNG_LIBRARY_BEGIN_NAMESPACE__
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
struct bs_tree_node_base
{
bs_tree_node_base* parent;
bs_tree_node_base* left;
bs_tree_node_base* right;
};
typedef bs_tree_node_base* bs_node_base_ptr;
inline bs_tree_node_base* min_element( bs_tree_node_base* p )
{
if( p )
{
while( p->left )
p = p->left;
}
return p;
}
inline bs_tree_node_base* max_element( bs_tree_node_base* p )
{
if( p )
{
while( p->right )
p = p->right;
}
return p;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
inline
bs_tree_node_base* bs_tree_iterator_increment( bs_tree_node_base* node )
{
if( node->right )
{
node = node->right;
while( node->left )
node = node->left;
}
else
{
bs_tree_node_base* temp = node->parent;
while( node == temp->right )
{
node = temp;
temp = temp->parent;
}
if( node->right != temp )
node = temp;
}
return node;
}

inline
bs_tree_node_base* bs_tree_iterator_decrement( bs_tree_node_base* node )
{
bs_tree_node_base* temp;
if( node->left )
{
temp = node->left;
while( temp->right )
temp = temp->right;
node = temp;
}
else
{
temp = node->parent;
while( node == temp->left )
{
node = temp;
temp = temp->parent;
}
node = temp;
}
return node;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
inline
def_size_t bs_tree_node_height( const bs_tree_node_base* node,
const bs_tree_node_base* root )
{
if( !node || !root )
return 0;
def_size_t height = 0;
while( node != root )
{
node = node->parent;
++height;
}
return height;
}

inline bs_tree_node_base* bs_tree_rotate_left( bs_tree_node_base* position,
bs_tree_node_base* root )
{
bs_tree_node_base* rchild = position->right;
position->right = rchild->left;
if( rchild->left )
rchild->left->parent = position;
rchild->parent = position->parent;
if( position == root )
root = rchild;
else if( position == position->parent->left )
position->parent->left = rchild;
else
position->parent->right = rchild;
rchild->left = position;
position->parent = rchild;
return root;
}

inline bs_tree_node_base* bs_tree_rotate_right( bs_tree_node_base* position,
bs_tree_node_base* root )
{
bs_tree_node_base* lchild = position->left;
position->left = lchild->right;
if( lchild->right )
lchild->right->parent = position;
lchild->parent = position->parent;
if( position == root )
root = lchild;
else if( position == position->parent->right )
position->parent->right = lchild;
else
position->parent->left = lchild;
lchild->right = position;
position->parent = lchild;
return root;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
inline bs_node_base_ptr bs_tree_erase_adjust( bs_node_base_ptr erase_node,
bs_node_base_ptr& successor,
bs_node_base_ptr& succ_parent,
bs_node_base_ptr& root,
bs_node_base_ptr& leftmost,
bs_node_base_ptr& rightmost )
{
bs_node_base_ptr position = erase_node; //position将指向新节点
successor = NULL_POINTER;
succ_parent = NULL_POINTER;
//查找
if( !(position->left) ) //position有右子树或者没有子树
successor = position->right; //successor可能为空
else
{
if( !(position->right) ) //只有左子树
successor = position->left;
else //有左、右子树
{
position = position->right;
while( position->left )
position = position->left;
successor = position->right;
}
}
//替换
if( position != erase_node )
{
erase_node->left->parent = position;
position->left = erase_node->left;
if( position != erase_node->right )
{
if( successor )
successor->parent = position->parent;
succ_parent = position->parent;
position->parent->left = successor;
position->right = erase_node->right;
erase_node->right->parent = position;
}
else
succ_parent = position;
if( root == erase_node )
root = position;
if( erase_node->parent->left == erase_node )
erase_node->parent->left = position;
else
erase_node->parent->right = position;
position->parent = erase_node->parent;
}
else //position == erase_node
{
succ_parent = position->parent;
if( successor )
successor->parent = succ_parent;
if( root == erase_node )
root = successor;
else if( erase_node->parent->left == erase_node )
erase_node->parent->left = successor;
else
erase_node->parent->right = successor;
if( leftmost == erase_node )
{
if( !(erase_node->right) ) //leftmost左子树必为空
leftmost = erase_node->parent;
else
leftmost = min_element( successor );
}
if( rightmost == erase_node )
{
if( !(erase_node->left) ) //rightmost右子树必为空
rightmost = erase_node->parent;
else
rightmost = max_element( successor );
}
} //end else
return position;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
__MACRO_CPLUSPLUS_YOUNG_LIBRARY_END_NAMESPACE__
#endif
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------

文件位置:young/tree/y_red_black_tree_base.hpp
/*
The young Library
Copyright (c) 2005 by 杨桓
Permission to use, copy, modify, distribute and sell this software 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.
The author make no representations about the suitability of this software
for any purpose. It is provided "as is" without express or implied warranty.
*/
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
#ifndef __MACRO_CPLUSPLUS_YOUNG_LIBRARY_RED_BLACK_TREE_BASE_HEADER_FILE__
#define __MACRO_CPLUSPLUS_YOUNG_LIBRARY_RED_BLACK_TREE_BASE_HEADER_FILE__
//-----------------------------------------------------------------------------
#include "y_binary_search_tree_base.hpp"
//-----------------------------------------------------------------------------
__MACRO_CPLUSPLUS_YOUNG_LIBRARY_BEGIN_NAMESPACE__
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
typedef bool rb_tree_color;
const rb_tree_color red = false;
const rb_tree_color black = true;
struct rb_tree_node_base : public bs_tree_node_base
{
rb_tree_color color;
};
typedef rb_tree_node_base* rb_node_base_ptr;
template< typename Value >
struct rb_tree_node : public rb_tree_node_base
{
Value data;
};
//-----------------------------------------------------------------------------
def_size_t black_count( const rb_tree_node_base* node,
const rb_tree_node_base* root )
{
if( !node )
return 0;
def_size_t count = ( node->color == black ) ? 1 : 0;
if( node == root )
return count;
else
return ( black_count( static_cast<rb_tree_node_base*>( node->parent ),
root ) + count );
}
//-----------------------------------------------------------------------------
inline rb_tree_color& color( bs_tree_node_base* x )
{
return static_cast<rb_tree_node_base*>(x)->color;
}
//-----------------------------------------------------------------------------
void rb_tree_insert_rebalance( bs_tree_node_base* position,
bs_tree_node_base& header )
{
bs_tree_node_base*& root = header.parent;
color( position ) = red;
while( position != root && color( position->parent ) == red )
{
//position->parent is left child
if( position->parent == position->parent->parent->left )
{
bs_tree_node_base* runcle = position->parent->parent->right;
//处理第1种情况:只用更改颜色
if( runcle && color( runcle ) == red )
{
color( runcle ) = black;
color( position->parent ) = black;
color( position->parent->parent ) = red;
position = position->parent->parent;
}
else //right uncle == 0 or right uncle->color == black
{
if( position == position->parent->right ) //处理第2种情况:
{
position = position->parent;
root = bs_tree_rotate_left( position, root );
}
color( position->parent ) = black; //处理第3种情况:将终止循环
color( position->parent->parent ) = red;
root = bs_tree_rotate_right( position->parent->parent, root );
}
}
else //position->parent is right child
{
bs_tree_node_base* luncle = position->parent->parent->left;
//处理第1种情况:只用更改颜色
if( luncle && color( luncle ) == red )
{
color( luncle ) = black;
color( position->parent ) = black;
color( position->parent->parent ) = red;
position = position->parent->parent;
}
else //left uncle == 0 or left uncle->color == black
{
if( position == position->parent->left ) //处理第2种情况:
{
position = position->parent;
root = bs_tree_rotate_right( position, root );
}
color( position->parent ) = black; //处理第3种情况:将终止循环
color( position->parent->parent ) = red;
root = bs_tree_rotate_left( position->parent->parent, root );
}
}
} //end while
color( root ) = black;
}
//-----------------------------------------------------------------------------
void rb_tree_erase_rebalance( bs_tree_node_base* erase_node,
bs_tree_node_base& header )
{
bs_tree_node_base *successor, *succ_parent, *position;
bs_tree_node_base*& root = header.parent;
bs_tree_node_base*& leftmost = header.left;
bs_tree_node_base*& rightmost = header.right;
//调整节点
position = bs_tree_erase_adjust( erase_node,
successor,
succ_parent,
root,
leftmost,
rightmost );
//调整颜色
if( position != erase_node )
data_swap( color( position ), color( erase_node ) );
position; //避免编译器提出警告
if( color( erase_node ) != red )
{
while( ( successor != root )
&& ( !successor || color( successor ) == black ) )
{
//successor is left child
if( successor == succ_parent->left )
{
bs_tree_node_base* succ_rbrother = succ_parent->right;
//第1种情况:succ_rbrother->color is red
if( color( succ_rbrother ) == red )
{
color( succ_rbrother ) = black;
color( succ_parent ) = red;
root = bs_tree_rotate_left( succ_parent, root );
succ_rbrother = succ_parent->parent;
}
//第2种情况: succ_rbrother->children->color are black
if( ( !( succ_rbrother->left )
|| color( succ_rbrother->left ) == black )
&& ( !( succ_rbrother->right )
|| color( succ_rbrother->right ) == black ) )
{
color( succ_rbrother ) = red;
successor = succ_parent;
succ_parent = succ_parent->parent;
}
else
{
//第3种情况:succ_rbrother->right->color is black
if( !( succ_rbrother->right )
|| color( succ_rbrother->right ) == black )
{
color( succ_rbrother->left ) = black;
color( succ_rbrother ) = red;
root = bs_tree_rotate_right( succ_rbrother, root );
succ_rbrother = succ_parent->right;
}
//第4种情况:succ_rbrother->right->color is red
color( succ_rbrother ) = color( succ_parent );
color( succ_parent ) = black;
color( succ_rbrother->right ) = black;
root = bs_tree_rotate_left( succ_parent, root );
break;
}
} //end if : successor is left child
//successor is right child
else
{
bs_tree_node_base* succ_lbrother = succ_parent->left;
//第1种情况:succ_lbrother->color is red
if( color( succ_lbrother ) == red )
{
color( succ_lbrother ) = black;
color( succ_parent ) = red;
root = bs_tree_rotate_right( succ_parent, root );
succ_lbrother = succ_parent->left;
}
//第2种情况:succ_lbrother->children->color are black
if( ( !( succ_lbrother->right )
|| color( succ_lbrother->right ) == black )
&& ( !( succ_lbrother->left )
|| color( succ_lbrother->left ) == black ) )
{
color( succ_lbrother ) = red;
successor = succ_parent;
succ_parent = succ_parent->parent;
}
else
{
//第3种情况:succ_lbrother->left->color is black
if( !( succ_lbrother->left )
|| color( succ_lbrother->left ) == black )
{
color( succ_lbrother->left ) = black;
color( succ_lbrother ) = red;
root = bs_tree_rotate_left( succ_lbrother, root );
succ_lbrother = succ_parent->left;
}
//第4种情况:succ_lbrother->left->color is red
color( succ_lbrother ) = color( succ_parent );
color( succ_parent ) = black;
color( succ_lbrother->left ) = black;
root = bs_tree_rotate_right( succ_parent, root );
break;
}
} //end else : successor is right child
} //end while
if( successor )
color( successor ) = black;
} //end if
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
__MACRO_CPLUSPLUS_YOUNG_LIBRARY_END_NAMESPACE__
#endif
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------

文件位置:young/tree/y_red_black_tree.hpp

/*
The young Library
Copyright (c) 2005 by 杨桓
Permission to use, copy, modify, distribute and sell this software 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.
The author make no representations about the suitability of this software
for any purpose. It is provided "as is" without express or implied warranty.
*/
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
#ifndef __MACRO_CPLUSPLUS_YOUNG_LIBRARY_RED_BLACK_TREE_HEADER_FILE__
#define __MACRO_CPLUSPLUS_YOUNG_LIBRARY_RED_BLACK_TREE_HEADER_FILE__
//-----------------------------------------------------------------------------
#include "../y_allocator.hpp"
#include "../y_construct.hpp"
#include "../y_pair.hpp"
#include "../algorithm/y_algorithm_base.hpp"
#include "y_red_black_tree_base.hpp"
//-----------------------------------------------------------------------------
__MACRO_CPLUSPLUS_YOUNG_LIBRARY_BEGIN_NAMESPACE__
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
template< typename T, typename Ref, typename Ptr, typename Key,
typename ExtractKey, typename KeyCompare, typename Alloc >
class rb_tree_iterator;
template< typename Key, typename Value, typename ExtractKey,
typename KeyCompare, typename Allocator >
class rb_tree;
template< typename T, typename Key, typename ExtractKey, typename KeyCompare,
typename Alloc >
inline rb_tree_iterator<T, T&, T*, Key, ExtractKey, KeyCompare, Alloc>
const_iter_cast( const rb_tree_iterator<T, const T&, const T*, Key,
ExtractKey, KeyCompare, Alloc>& citer );

template< typename T, typename Ref, typename Ptr, typename Key,
typename ExtractKey, typename KeyCompare, typename Alloc >
class rb_tree_iterator
{
public:
typedef bidirectional_iterator_tag iterator_category;
typedef def_size_t size_type;
typedef def_ptrdiff_t difference_type;
typedef T value_type;
typedef Ref reference;
typedef Ptr pointer;
typedef rb_tree_iterator<T, Ref, Ptr, Key, ExtractKey,
KeyCompare, Alloc> self;
typedef rb_tree_iterator<T, T&, T*, Key, ExtractKey,
KeyCompare, Alloc> iterator;
typedef rb_tree_iterator<T, const T&, const T*, Key, ExtractKey,
KeyCompare, Alloc> const_iterator;
private:
typedef bs_tree_node_base* bs_ptr;
typedef rb_tree_node_base* base_ptr;
typedef rb_tree_node<T>* node_ptr;
typedef typename primal_type<Ref>::contrary_const_ref Ref_t;
typedef typename primal_type<Ptr>::contrary_const_ptr Ptr_t;
friend class rb_tree<Key, T, ExtractKey, KeyCompare, Alloc>;
friend class rb_tree_iterator<T, Ref_t, Ptr_t, Key, ExtractKey,
KeyCompare, Alloc>;
friend iterator const_iter_cast <> ( const const_iterator& );

base_ptr node;
public:
rb_tree_iterator() : node(NULL_POINTER) {}
rb_tree_iterator( base_ptr p ) : node(p) {}
rb_tree_iterator( node_ptr p ) : node(p) {}
rb_tree_iterator( const iterator& x ) : node(x.node) {}
self& operator=( def_nullptr_t n )
{
if( n == NULL_POINTER )
node = NULL_POINTER;
return *this;
}
bool operator!() const { return !node; }
bool operator==( const self& rhs ) const { return node == rhs.node; }
bool operator!=( const self& rhs ) const { return node != rhs.node; }
reference operator*() const
{ return static_cast<node_ptr>( node )->data; }
pointer operator->() const
{ return &( operator*() ); }
self& operator++()
{
if( node->color == red && node->parent->parent == node ) //is header
node = static_cast<base_ptr>( node->left );
else
node = static_cast<base_ptr>( bs_tree_iterator_increment(node) );
return *this;
}
self& operator--()
{
if( node->color == red && node->parent->parent == node ) //is header
node = static_cast<base_ptr>( node->right );
else
node = static_cast<base_ptr>( bs_tree_iterator_decrement(node) );
return *this;
}
self operator++(int) { self old = *this; ++( *this ); return old; }
self operator--(int) { self old = *this; --( *this ); return old; }
}; //end iterator

template< typename T, typename Key, typename ExtractKey, typename KeyCompare,
typename Alloc >
inline rb_tree_iterator<T, T&, T*, Key, ExtractKey, KeyCompare, Alloc>
const_iter_cast( const rb_tree_iterator<T, const T&, const T*, Key,
ExtractKey, KeyCompare, Alloc>& citer )
{
return rb_tree_iterator<T, T&, T*, Key, ExtractKey,
KeyCompare, Alloc>( citer.node );
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
template< typename Key, typename Value, typename ExtractKey, typename KeyCompare,
typename Allocator = allocator< rb_tree_node<Value> > >
class rb_tree
{
public:
typedef rb_tree<Key, Value, ExtractKey, KeyCompare, Allocator> self;
typedef rb_tree_color color_type;
typedef Key key_type;
typedef ExtractKey get_key;
typedef KeyCompare key_compare;
typedef Allocator allocator_type;
typedef Value value_type;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef value_type* pointer;
typedef const value_type* const_pointer;
typedef def_size_t size_type;
typedef def_ptrdiff_t difference_type;
typedef rb_tree_iterator<Value, Value&, Value*, Key, ExtractKey,
KeyCompare, Allocator> iterator;
typedef rb_tree_iterator<Value, const Value&, const Value*, Key, ExtractKey,
KeyCompare, Allocator> const_iterator;
typedef Reverse_Iterator<iterator> reverse_iterator;
typedef Reverse_Iterator<const_iterator> const_reverse_iterator;
typedef pair<iterator, iterator> pair_iterator;
typedef pair<const_iterator, const_iterator> pair_const_iterator;
typedef pair<iterator, bool> pair_iterator_bool;
protected:
typedef bs_tree_node_base bs_tree_node_type;
typedef rb_tree_node_base base_node_type;
typedef rb_tree_node<Value> rb_tree_node_type;
typedef bs_tree_node_type* bs_tree_ptr;
typedef base_node_type* base_ptr;
typedef rb_tree_node_type* node_ptr;
typedef const base_node_type* const_base_ptr;
typedef const rb_tree_node_type* const_node_ptr;
size_type m_node_count;
key_compare m_comp;
mutable base_node_type m_header;
allocator_type m_alloc;
public:
explicit rb_tree( const key_compare& compare = key_compare() )
: m_node_count(0), m_comp(compare)
{
init_header( m_header );
}
rb_tree( const self& rhs );
self& operator=( const self& rhs );
~rb_tree()
{
if( m_node_count > 0 )
destroy_tree( static_cast<node_ptr>(m_header.parent) );
}
key_compare key_comp() const { return m_comp; }
size_type size() const { return m_node_count; }
bool empty() const { return ( m_node_count == 0 ); }
size_type max_size() const { return size_t_max; }
iterator begin() { return leftmost(); }
iterator end() { return &m_header; }
const_iterator begin() const { return leftmost(); }
const_iterator end() const { return &m_header; }
reverse_iterator rbegin() { return end(); }
reverse_iterator rend() { return begin(); }
const_reverse_iterator rbegin() const { return end(); }
const_reverse_iterator rend() const { return begin(); }
value_type& front() { return *begin(); }
value_type& back() { return *(--end()); }
const value_type& front() const { return *begin(); }
const value_type& back() const { return *(--end()); }
pair_iterator_bool insert_unique( const value_type& v );
iterator insert_unique( iterator position, const value_type& v );
template< typename InputIterator >
void insert_unique( InputIterator first, InputIterator last );
iterator insert_equal( const value_type& v );
iterator insert_equal( iterator position, const value_type& v );
template< typename InputIterator >
void insert_equal( InputIterator first, InputIterator last );
iterator lower_bound( const key_type& k )
{ return iterator( lower_bound_node(k) ); }
const_iterator lower_bound( const key_type& k ) const
{ return const_iterator( lower_bound_node(k) ); }
iterator upper_bound( const key_type& k )
{ return iterator( upper_bound_node(k) ); }
const_iterator upper_bound( const key_type& k ) const
{ return const_iterator( upper_bound_node(k) ); }
pair_iterator equal_range( const key_type& k )
{ return pair_iterator( lower_bound(k), upper_bound(k) ); }
pair_const_iterator equal_range( const key_type& k ) const
{ return pair_const_iterator( lower_bound(k), upper_bound(k) ); }
void erase( iterator position );
size_type erase( const key_type& k );
void erase( iterator first, iterator last );
void erase( const key_type* first, const key_type* last );
void modify_key_equal( const key_type& k, const key_type& new_key );
void modify_key_equal( iterator position, const key_type& new_key )
{
if( position != end() )
modify_key_aux( position, new_key );
}
iterator modify_key_unique( const key_type& k, const key_type& new_key )
{
iterator result = find( k );
if( result != end() && find(new_key) == end() )
modify_key_aux( result, new_key );
return result;
}
bool modify_key_unique( iterator position, const key_type& new_key )
{
if( position == end() || find(new_key) != end() )
return false;
modify_key_aux( position, new_key );
return true;
}
iterator find( const key_type& k )
{
base_ptr x = find_node( k );
if( x == &m_header || m_comp( k, _key(x) ) )
return end();
else
return x;
}
const_iterator find( const key_type& k ) const
{
base_ptr x = find_node( k );
if( x == &m_header || m_comp( k, _key(x) ) )
return end();
else
return x;
}
bool verify_rb_tree() const;
void swap( self& rhs );
size_type node_height( iterator position ) const
{
return bs_tree_node_height( position.node, root() );
}
size_type count( const key_type& k ) const
{
pair_const_iterator pair_c_iter = equal_range( k );
return distance( pair_c_iter.first, pair_c_iter.second );
}
void clear()
{
if( m_node_count > 0 )
{
destroy_tree( root() );
m_header.parent = NULL_POINTER;
m_header.left = &m_header;
m_header.right = &m_header;
m_node_count = 0;
}
}
protected:
void destroy_tree( node_ptr x );
node_ptr copy_tree( node_ptr source, node_ptr destination );
iterator insert_node( base_ptr child, base_ptr parent, const value_type& v );
void modify_key_aux( iterator position, const key_type& new_key );
base_ptr find_node( const key_type& k ) const;
base_ptr lower_bound_node( const key_type& k ) const;
base_ptr upper_bound_node( const key_type& k ) const;
void init_header( base_node_type& x )
{
x.parent = NULL_POINTER;
x.left = &x;
x.right = &x;
x.color = red;
}
void rb_tree_swap( self& rhs )
{
data_swap( m_node_count, rhs.m_node_count );
data_swap( m_comp, rhs.m_comp );
data_swap( m_header.parent, rhs.m_header.parent );
data_swap( m_header.left, rhs.m_header.left );
data_swap( m_header.right, rhs.m_header.right );
data_swap( m_alloc, rhs.m_alloc );
}
node_ptr create_node( const value_type& x )
{
node_ptr ptr = m_alloc.allocate( 1 );
try
{
construct( &(ptr->data),x );
}
catch(...)
{
m_alloc.deallocate( ptr, 1 );
throw;
}
return ptr;
}
node_ptr copy_node( node_ptr x )
{
node_ptr ptr = create_node( x->data );
ptr->parent = NULL_POINTER;
ptr->left = NULL_POINTER;
ptr->right = NULL_POINTER;
ptr->color = x->color;
return ptr;
}
void destroy_node( node_ptr ptr )
{
destroy( &(ptr->data) );
m_alloc.deallocate( ptr, 1 );
}
node_ptr root() const
{ return static_cast<node_ptr>( m_header.parent ); }
node_ptr leftmost() const
{ return static_cast<node_ptr>( m_header.left ); }
node_ptr rightmost() const
{ return static_cast<node_ptr>( m_header.right ); }
static node_ptr min_node( node_ptr x )
{ return static_cast<node_ptr>( min_element(x) ); }
static node_ptr max_node( node_ptr x )
{ return static_cast<node_ptr>( max_element(x) ); }
static node_ptr _parent( node_ptr x )
{ return static_cast<node_ptr>( x->parent ); }
static node_ptr _left( node_ptr x )
{ return static_cast<node_ptr>( x->left ); }
static node_ptr _right( node_ptr x )
{ return static_cast<node_ptr>( x->right ); }
static value_type& _value( node_ptr x )
{ return x->data; }
static const key_type& _key( node_ptr x )
{ return get_key()( _value(x) ); }
static node_ptr _parent( base_ptr x )
{ return static_cast<node_ptr>( x->parent ); }
static node_ptr _left( base_ptr x )
{ return static_cast<node_ptr>( x->left ); }
static node_ptr _right( base_ptr x )
{ return static_cast<node_ptr>( x->right ); }
static value_type& _value( base_ptr x )
{ return static_cast<node_ptr>( x )->data; }
static const key_type& _key( base_ptr x )
{ return get_key()( _value(x) ); }
}; //end class
//-----------------------------------------------------------------------------
template< typename Key, typename Value, typename ExtractKey,
typename KeyCompare, typename Allocator >
void rb_tree<Key, Value, ExtractKey, KeyCompare, Allocator>::swap( self& rhs )
{
if( this != &rhs )
{
bool x = empty();
bool y = rhs.empty();
if( x )
{
if( y )
return;
rb_tree_swap( rhs );
m_header.parent->parent = &m_header; //将原rhs.root->parent指向header
init_header( rhs.m_header ); //将rhs.header置空
}
else
{
rb_tree_swap( rhs );
rhs.m_header.parent->parent = &(rhs.m_header); //将原root指向rhs.m_header
if( y )
init_header( m_header ); //将header置空
else
m_header.parent->parent = &m_header; //将原rhs.root->parent指向header
}
}
}
//-----------------------------------------------------------------------------
template< typename Key, typename Value, typename ExtractKey,
typename KeyCompare, typename Allocator >
rb_tree<Key, Value, ExtractKey, KeyCompare, Allocator>::
rb_tree( const self& rhs) : m_node_count(0), m_comp(rhs.m_comp)
{
init_header( m_header );
if( rhs.m_node_count > 0 )
{
m_header.parent = copy_tree( rhs.root(),
static_cast<node_ptr>(&m_header) );
m_header.left = min_node( root() );
m_header.right = max_node( root() );
}
m_node_count = rhs.m_node_count;
}
//-----------------------------------------------------------------------------
template< typename Key, typename Value, typename ExtractKey,
typename KeyCompare, typename Allocator >
rb_tree<Key, Value, ExtractKey, KeyCompare, Allocator>&
rb_tree<Key, Value, ExtractKey, KeyCompare, Allocator>::
operator=( const self& rhs)
{
if( this == &rhs )
return *this;
if( rhs.m_node_count > 0 )
{
self temp( rhs );
swap( temp );
}
else
{
clear();
m_header.parent = NULL_POINTER;
m_header.left = &m_header;
m_header.right = &m_header;
m_comp = rhs.m_comp;
}
return *this;
}
//-----------------------------------------------------------------------------
template< typename Key, typename Value, typename ExtractKey,
typename KeyCompare, typename Allocator >
typename rb_tree<Key, Value, ExtractKey, KeyCompare, Allocator>::node_ptr
rb_tree<Key, Value, ExtractKey, KeyCompare, Allocator>::
copy_tree( node_ptr source, node_ptr destination )
{
node_ptr top = copy_node( source );
top->parent = destination;
try
{
if( source->right )
top->right = copy_tree( _right(source), top );
destination = top;
source = _left( source );
while( source )
{
node_ptr temp = copy_node( source );
destination->left = temp;
temp->parent = destination;
if( source->right )
temp->right = copy_tree( _right(source), temp );
destination = temp;
source = _left( source );
}
}
catch(...)
{
destroy_tree( top );
}
return top;
}
//-----------------------------------------------------------------------------
template< typename Key, typename Value, typename ExtractKey,
typename KeyCompare, typename Allocator >
void rb_tree<Key, Value, ExtractKey, KeyCompare, Allocator>::
destroy_tree( node_ptr x )
{
while( x )
{
destroy_tree( _right(x) );
node_ptr y = _left( x );
destroy_node( x );
x = y;
}
}
//-----------------------------------------------------------------------------
template< typename Key, typename Value, typename ExtractKey,
typename KeyCompare, typename Allocator >
typename rb_tree<Key, Value, ExtractKey, KeyCompare, Allocator>::base_ptr
rb_tree<Key, Value, ExtractKey, KeyCompare, Allocator>::
find_node( const key_type& k ) const
{
base_ptr parent = &m_header;
node_ptr current = root();
while( current )
{
if( !m_comp( _key(current), k ) )
{
parent = current;
current = _left( current );
}
else
current = _right( current );
}
return parent;
}
//-----------------------------------------------------------------------------
template< typename Key, typename Value, typename ExtractKey,
typename KeyCompare, typename Allocator >
typename rb_tree<Key, Value, ExtractKey, KeyCompare, Allocator>::base_ptr
rb_tree<Key, Value, ExtractKey, KeyCompare, Allocator>::
lower_bound_node( const key_type& k ) const
{
base_ptr x = &m_header;
node_ptr current = root();
while( current )
{
if( !m_comp( _key(current), k ) ) // current >= k
{
x = current;
current = _left( current );
}
else
current = _right( current );
}
return x;
}
//-----------------------------------------------------------------------------
template< typename Key, typename Value, typename ExtractKey,
typename KeyCompare, typename Allocator >
typename rb_tree<Key, Value, ExtractKey, KeyCompare, Allocator>::base_ptr
rb_tree<Key, Value, ExtractKey, KeyCompare, Allocator>::
upper_bound_node( const key_type& k ) const
{
base_ptr x = &m_header;
node_ptr current = root();
while( current )
{
if( m_comp( k, _key(current) ) ) // k < current
{
x = current;
current = _left( current );
}
else
current = _right( current );
}
return x;
}
//-----------------------------------------------------------------------------
template< typename Key, typename Value, typename ExtractKey,
typename KeyCompare, typename Allocator >
typename
rb_tree<Key, Value, ExtractKey, KeyCompare, Allocator>::pair_iterator_bool
rb_tree<Key, Value, ExtractKey, KeyCompare, Allocator>::
insert_unique( const value_type& v )
{
base_ptr y = &m_header;
node_ptr current = root();
bool bcompare = true;
while( current )
{
y = current;
bcompare = m_comp( get_key()(v), _key(current) );
current = bcompare ? _left( current ) : _right( current );
}
iterator result( y );
if( bcompare ) //最后一次比较结果是: v < current
{
if( result == begin() )
return pair_iterator_bool( insert_node(current, y, v), true );
else
--result;
}
if( m_comp( _key(result.node), get_key()(v) ) ) // result < v
return pair_iterator_bool( insert_node(current, y, v), true );
return pair_iterator_bool( result, false );
}
//-----------------------------------------------------------------------------
template< typename Key, typename Value, typename ExtractKey,
typename KeyCompare, typename Allocator >
typename rb_tree<Key, Value, ExtractKey, KeyCompare, Allocator>::iterator
rb_tree<Key, Value, ExtractKey, KeyCompare, Allocator>::
insert_unique( iterator position, const value_type& v )
{
iterator result;
if( position == begin() )
{
if( size() > 0 && m_comp( get_key()(v), _key(position.node) ) )
result = insert_node( position.node, position.node, v );
else
result = insert_unique( v ).first;
}
else if( position == end() )
{
if( size() > 0 && m_comp( _key(rightmost()), get_key()(v) ) )
result = insert_node( NULL_POINTER, rightmost(), v );
else
result = insert_unique( v ).first;
}
else
{
iterator before = position;
--before;
if( m_comp( _key(before.node), get_key()(v) )
&& m_comp( get_key()(v), _key(position.node) ) ) // b < v < p
{
if( !(position.node->right) )
result = insert_node( NULL_POINTER, before.node, v );
else
result = insert_node( position.node, position.node, v );
}
else
result = insert_unique( v ).first;
}
return result;
}
//-----------------------------------------------------------------------------
template< typename Key, typename Value, typename ExtractKey,
typename KeyCompare, typename Allocator >
template< typename InputIterator >
void rb_tree<Key, Value, ExtractKey, KeyCompare, Allocator>::
insert_unique( InputIterator first, InputIterator last )
{
while( first != last )
insert_unique( *first++ );
}
//-----------------------------------------------------------------------------
template< typename Key, typename Value, typename ExtractKey,
typename KeyCompare, typename Allocator >
typename rb_tree<Key, Value, ExtractKey, KeyCompare, Allocator>::iterator
rb_tree<Key, Value, ExtractKey, KeyCompare, Allocator>::
insert_equal( const value_type& v )
{
base_ptr y = &m_header;
node_ptr current = root();
while( current )
{
y = current;
current = m_comp( get_key()(v), _key(current) )
? _left( current ) : _right( current );
}
return insert_node( current, y, v );
}
//-----------------------------------------------------------------------------
template< typename Key, typename Value, typename ExtractKey,
typename KeyCompare, typename Allocator >
typename rb_tree<Key, Value, ExtractKey, KeyCompare, Allocator>::iterator
rb_tree<Key, Value, ExtractKey, KeyCompare, Allocator>::
insert_equal( iterator position, const value_type& v )
{
iterator result;
if( position == begin() )
{
if( size() > 0 && m_comp( get_key()(v), _key(position.node) ) ) //v < p
result = insert_node( position.node, position.node, v );
else
result = insert_equal( v );
}
else if( position == end() )
{
if( size() > 0 && !m_comp( get_key()(v), _key(rightmost()) ) ) //v >= rightmost()
result = insert_node( NULL_POINTER, rightmost(), v );
else
result = insert_equal( v );
}
else
{
iterator before = position;
--before;
if( !m_comp( get_key()(v), _key(before.node) )
&& !m_comp( _key(position.node), get_key()(v) ) ) // p >= v >= b
{
if( !(position.node->right) )
result = insert_node( NULL_POINTER, before.node, v );
else
result = insert_node( position.node, position.node, v );
}
else
result = insert_equal( v );
}
return result;
}
//-----------------------------------------------------------------------------
template< typename Key, typename Value, typename ExtractKey,
typename KeyCompare, typename Allocator >
template< typename InputIterator >
void rb_tree<Key, Value, ExtractKey, KeyCompare, Allocator>::
insert_equal( InputIterator first, InputIterator last )
{
while( first != last )
insert_equal( *first++ );
}
//-----------------------------------------------------------------------------
template< typename Key, typename Value, typename ExtractKey,
typename KeyCompare, typename Allocator >
inline void rb_tree<Key, Value, ExtractKey, KeyCompare, Allocator>::
erase( iterator position )
{
if( position != end() )
{
rb_tree_erase_rebalance( position.node, m_header );
destroy_node( static_cast<node_ptr>( position.node ) );
--m_node_count;
}
}
//-----------------------------------------------------------------------------
template< typename Key, typename Value, typename ExtractKey,
typename KeyCompare, typename Allocator >
inline
typename rb_tree<Key, Value, ExtractKey, KeyCompare, Allocator>::size_type
rb_tree<Key, Value, ExtractKey, KeyCompare, Allocator>::
erase( const key_type& k )
{
pair_iterator pair_iter = equal_range(k);
size_type n = distance( pair_iter.first, pair_iter.second );
erase( pair_iter.first, pair_iter.second );
return n;
}
//-----------------------------------------------------------------------------
template< typename Key, typename Value, typename ExtractKey,
typename KeyCompare, typename Allocator >
void rb_tree<Key, Value, ExtractKey, KeyCompare, Allocator>::
erase( iterator first, iterator last )
{
if( first == begin() && last == end() )
clear();
else
{
while( first != last )
erase( first++ );
}
}
//-----------------------------------------------------------------------------
template< typename Key, typename Value, typename ExtractKey,
typename KeyCompare, typename Allocator >
void rb_tree<Key, Value, ExtractKey, KeyCompare, Allocator>::
erase( const key_type* first, const key_type* last )
{
while( first != last )
erase( *first++ );
}
//-----------------------------------------------------------------------------
template< typename Key, typename Value, typename ExtractKey,
typename KeyCompare, typename Allocator >
typename rb_tree<Key, Value, ExtractKey, KeyCompare, Allocator>::iterator
rb_tree<Key, Value, ExtractKey, KeyCompare, Allocator>::
insert_node( base_ptr child, base_ptr parent, const value_type& v )
{
node_ptr p = create_node( v );
// v < parent
if( parent == &m_header || child || m_comp( get_key()(v), _key(parent) ) )
{
parent->left = p;
if( parent == &m_header )
{
m_header.parent = p;
m_header.right = p;
}
else if( parent == leftmost() )
m_header.left = p;
}
else // v >= parent
{
parent->right = p;
if( rightmost() == parent )
m_header.right = p;
}
p->parent = parent;
p->left = NULL_POINTER;
p->right = NULL_POINTER;
rb_tree_insert_rebalance( p, m_header );
++m_node_count;
return iterator( p );
}
//-----------------------------------------------------------------------------
template< typename Key, typename Value, typename ExtractKey,
typename KeyCompare, typename Allocator >
void rb_tree<Key, Value, ExtractKey, KeyCompare, Allocator>::
modify_key_equal( const key_type& k, const key_type& new_key )
{
pair_iterator pair_iter = equal_range( k );
iterator first = pair_iter.first;
iterator last = pair_iter.second;
while( first != last )
{
modify_key_equal( first, new_key );
++first;
}
}
//-----------------------------------------------------------------------------
template< typename Key, typename Value, typename ExtractKey,
typename KeyCompare, typename Allocator >
void rb_tree<Key, Value, ExtractKey, KeyCompare, Allocator>::
modify_key_aux( iterator position, const key_type& new_key )
{
base_ptr x = position.node;
rb_tree_erase_rebalance( x, m_header );
try
{
const_cast<key_type&>( get_key()(_value(x)) ) = new_key;
}
catch(...)
{
destroy_node( static_cast<node_ptr>( x ) );
--m_node_count;
throw;
}
//寻找节点重新插入的位置
base_ptr parent = &m_header;
node_ptr current = root();
while( current )
{
parent = current;
current = m_comp( new_key, _key(current) )
? _left( current ) : _right( current );
}
if( m_comp( new_key, _key(parent) ) )
{
parent->left = x;
if( leftmost() == static_cast<node_ptr>( parent ) )
m_header.left = x;
}
else
{
parent->right = x;
if( rightmost() == static_cast<node_ptr>( parent ) )
m_header.right = x;
}
x->parent = parent;
x->left = NULL_POINTER;
x->right = NULL_POINTER;
rb_tree_insert_rebalance( x, m_header );
}
//-----------------------------------------------------------------------------
template< typename Key, typename Value, typename ExtractKey,
typename KeyCompare, typename Allocator >
bool rb_tree<Key, Value, ExtractKey, KeyCompare, Allocator>::
verify_rb_tree() const
{
if( m_node_count == 0 || begin() == end() )
return ( m_node_count == 0 && begin() == end()
&& m_header.left == &m_header && m_header.right == &m_header );
def_size_t black_num = black_count( leftmost(), root() );
const_iterator first = begin();
const_iterator last = end();
for( ; first != last; ++first )
{
node_ptr current = static_cast<node_ptr>( first.node );
node_ptr lchild = _left( current );
node_ptr rchild = _right( current );
if( current->color == red )
{
if( lchild && (lchild->color == red) )
return false;
if( rchild && (rchild->color == red) )
return false;
}
if( lchild && m_comp( _key(current), _key(lchild) ) )
return false;
if( rchild && m_comp( _key(rchild), _key(current) ) )
return false;
if( !lchild && !rchild && (black_count(current, root()) != black_num) )
return false;
}
if( leftmost() != min_element(root())
|| rightmost() != max_element(root()) )
return false;
return true;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
template< typename Key, typename Value, typename ExtractKey,
typename KeyCompare, typename Allocator >
inline
void swap( rb_tree<Key, Value, ExtractKey, KeyCompare, Allocator>& lhs,
rb_tree<Key, Value, ExtractKey, KeyCompare, Allocator>& rhs )
{
lhs.swap( rhs );
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
__MACRO_CPLUSPLUS_YOUNG_LIBRARY_END_NAMESPACE__
#endif
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: