/*
|
*
|
* 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.
|
*
|
*
|
* Copyright (c) 1996
|
* 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) 2007 Lao wen bo
|
|
This software is provided 'as-is', without any express or implied
|
warranty. In no event will the authors be held liable for any damages
|
arising from the use of this software.
|
|
Permission is granted to anyone to use this software for any purpose,
|
including commercial applications, and to alter it and redistribute it
|
freely, subject to the following restrictions:
|
|
1. The origin of this software must not be misrepresented; you must not
|
claim that you wrote the original software. If you use this software
|
in a product, an acknowledgment in the product documentation would be
|
appreciated but is not required.
|
|
2. Altered source versions must be plainly marked as such, and must not be
|
misrepresented as being the original software.
|
|
3. This notice may not be removed or altered from any source
|
distribution.
|
|
Lao wen bo
|
viewpl(at)gmail.com
|
*/
|
|
#include "c_tree.h"
|
#include "c_vector.h"
|
#include "c_algorithm.h"
|
|
static const _c_rb_tree_color_type _S_c_rb_tree_red = false;
|
static const _c_rb_tree_color_type _S_c_rb_tree_black = true;
|
|
static _base_ptr _S_minimum(_base_ptr val)
|
{
|
while(val->_A_left)
|
val = val->_A_left;
|
return val;
|
}
|
|
static _base_ptr _S_maximum(_base_ptr val)
|
{
|
while(val->_A_right)
|
val = val->_A_right;
|
return val;
|
}
|
|
static void _A_iterator_increment(c_piterator thiz)
|
{
|
if(((_base_ptr)(thiz->_i))->_A_right)
|
{
|
thiz->_i = ((_base_ptr)(thiz->_i))->_A_right;
|
while(((_base_ptr)(thiz->_i))->_A_left)
|
thiz->_i = ((_base_ptr)(thiz->_i))->_A_left;
|
}
|
else
|
{
|
_base_ptr val = ((_base_ptr)(thiz->_i))->_A_parent;
|
while(((_base_ptr)(thiz->_i)) == val->_A_right)
|
{
|
thiz->_i = val;
|
val = val->_A_parent;
|
}
|
if(((_base_ptr)(thiz->_i))->_A_right != val)
|
thiz->_i = val;
|
}
|
}
|
|
static void _A_iterator_decrement(c_piterator thiz)
|
{
|
if((((_base_ptr)(thiz->_i))->_A_color == _S_c_rb_tree_red) &&
|
((_base_ptr)(thiz->_i))->_A_parent->_A_parent == ((_base_ptr)(thiz->_i)))
|
thiz->_i = ((_base_ptr)(thiz->_i))->_A_right;
|
else if(((_base_ptr)(thiz->_i))->_A_left)
|
{
|
_base_ptr val = ((_base_ptr)(thiz->_i))->_A_left;
|
while(val->_A_right)
|
val = val->_A_right;
|
thiz->_i = val;
|
}
|
else
|
{
|
_base_ptr val = ((_base_ptr)(thiz->_i))->_A_parent;
|
while(((_base_ptr)(thiz->_i)) == val->_A_left)
|
{
|
thiz->_i = val;
|
val = val->_A_parent;
|
}
|
thiz->_i = val;
|
}
|
}
|
|
static void _A_reverse_iterator_increment(c_preverse_iterator thiz)
|
{
|
c_iterator iter;
|
iter._i = thiz->_i;
|
_A_iterator_decrement(&iter);
|
thiz->_i = iter._i;
|
}
|
|
static void _A_reverse_iterator_decrement(c_preverse_iterator thiz)
|
{
|
c_iterator iter;
|
iter._i = thiz->_i;
|
_A_iterator_increment(&iter);
|
thiz->_i = iter._i;
|
}
|
|
static c_iterator _c_rb_tree_iterator_assign(c_piterator thiz, const c_piterator val)
|
{
|
if(thiz != val)
|
thiz->_i = val->_i;
|
return *thiz;
|
}
|
|
static value_type _c_rb_tree_iterator_ref(c_piterator thiz)
|
{
|
return ((_base_ptr)(thiz->_i))->_A_value_field;
|
}
|
|
static value_type _c_rb_tree_iterator_ref_assign(c_piterator thiz, const value_type val)
|
{
|
return ((_base_ptr)(thiz->_i))->_A_value_field = val;
|
}
|
|
static c_iterator _c_rb_tree_iterator_inc(c_piterator thiz)
|
{
|
_A_iterator_increment(thiz);
|
return *thiz;
|
}
|
|
static c_iterator _c_rb_tree_iterator_dec(c_piterator thiz)
|
{
|
_A_iterator_decrement(thiz);
|
return *thiz;
|
}
|
|
static c_bool _c_rb_tree_iterator_equal(c_piterator thiz, const c_piterator val)
|
{
|
return (thiz->_i == val->_i &&
|
thiz->_pft == val->_pft);
|
}
|
|
static c_iterator_ft _c_rb_tree_iter_ft =
|
{
|
_c_rb_tree_iterator_assign,
|
_c_rb_tree_iterator_ref,
|
_c_rb_tree_iterator_ref_assign,
|
_c_rb_tree_iterator_inc,
|
NULL, /* _c_rb_tree_iterator_inc_n */
|
_c_rb_tree_iterator_dec,
|
NULL, /* _c_rb_tree_iterator_dec_n */
|
NULL, /* _c_rb_tree_iterator_diff */
|
NULL, /* _c_rb_tree_iterator_at */
|
NULL, /* _c_rb_tree_iterator_positive_n */
|
NULL, /* _c_rb_tree_iterator_negative_n */
|
_c_rb_tree_iterator_equal,
|
NULL /* _c_rb_tree_iterator_less */
|
};
|
|
static c_iterator _A_get_iterator(_base_ptr val)
|
{
|
c_iterator iter;
|
iter._pft = &_c_rb_tree_iter_ft;
|
iter._i = val;
|
return iter;
|
}
|
|
static c_reverse_iterator _c_rb_tree_reverse_iterator_assign(c_preverse_iterator thiz,
|
const c_preverse_iterator val)
|
{
|
if(thiz != val)
|
thiz->_i = val->_i;
|
return *thiz;
|
}
|
|
static value_type _c_rb_tree_reverse_iterator_ref(c_preverse_iterator thiz)
|
{
|
c_iterator iter = _A_get_iterator(thiz->_i);
|
_A_iterator_decrement(&iter);
|
return ((_base_ptr)(iter._i))->_A_value_field;
|
}
|
|
static value_type _c_rb_tree_reverse_iterator_ref_assign(c_preverse_iterator thiz, const value_type val)
|
{
|
c_iterator iter = _A_get_iterator(thiz->_i);
|
_A_iterator_decrement(&iter);
|
return ((_base_ptr)(iter._i))->_A_value_field = val;
|
}
|
|
static c_reverse_iterator _c_rb_tree_reverse_iterator_inc(c_preverse_iterator thiz)
|
{
|
_A_reverse_iterator_increment(thiz);
|
return *thiz;
|
}
|
|
static c_reverse_iterator _c_rb_tree_reverse_iterator_dec(c_preverse_iterator thiz)
|
{
|
_A_reverse_iterator_decrement(thiz);
|
return *thiz;
|
}
|
|
static c_bool _c_rb_tree_reverse_iterator_equal(c_preverse_iterator thiz, const c_preverse_iterator val)
|
{
|
return (thiz->_i == val->_i &&
|
thiz->_pft == val->_pft);
|
}
|
|
static c_reverse_iterator_ft _c_rb_tree_reverse_iter_ft =
|
{
|
_c_rb_tree_reverse_iterator_assign,
|
_c_rb_tree_reverse_iterator_ref,
|
_c_rb_tree_reverse_iterator_ref_assign,
|
_c_rb_tree_reverse_iterator_inc,
|
NULL, /* _c_rb_tree_reverse_iterator_inc_n */
|
_c_rb_tree_reverse_iterator_dec,
|
NULL, /* _c_rb_tree_reverse_iterator_dec_n */
|
NULL, /* _c_rb_tree_reverse_iterator_diff */
|
NULL, /* _c_rb_tree_reverse_iterator_at */
|
NULL, /* _c_rb_tree_reverse_iterator_positive_n */
|
NULL, /* _c_rb_tree_reverse_iterator_negative_n */
|
_c_rb_tree_reverse_iterator_equal,
|
NULL, /* _c_rb_tree_reverse_iterator_less */
|
};
|
|
static c_reverse_iterator _A_get_reverse_iterator(_base_ptr val)
|
{
|
c_reverse_iterator iter;
|
iter._pft = &_c_rb_tree_reverse_iter_ft;
|
iter._i = val;
|
return iter;
|
}
|
|
static void _c_rb_tree_rotate_left(_base_ptr val, _base_ptr * proot)
|
{
|
_base_ptr wal = val->_A_right;
|
val->_A_right = wal->_A_left;
|
if(wal->_A_left != NULL)
|
wal->_A_left->_A_parent = val;
|
wal->_A_parent = val->_A_parent;
|
|
if(val == *proot)
|
*proot = wal;
|
else if(val == val->_A_parent->_A_left)
|
val->_A_parent->_A_left = wal;
|
else
|
val->_A_parent->_A_right = wal;
|
wal->_A_left = val;
|
val->_A_parent = wal;
|
}
|
|
static void _c_rb_tree_rotate_right(_base_ptr val, _base_ptr * proot)
|
{
|
_base_ptr wal = val->_A_left;
|
val->_A_left = wal->_A_right;
|
if(wal->_A_right != NULL)
|
wal->_A_right->_A_parent = val;
|
wal->_A_parent = val->_A_parent;
|
|
if(val == *proot)
|
*proot = wal;
|
else if(val == val->_A_parent->_A_right)
|
val->_A_parent->_A_right = wal;
|
else
|
val->_A_parent->_A_left = wal;
|
wal->_A_right = val;
|
val->_A_parent = wal;
|
}
|
|
void _c_rb_tree_rebalance(_base_ptr val, _base_ptr * proot)
|
{
|
val->_A_color = _S_c_rb_tree_red;
|
while(val != *proot && val->_A_parent->_A_color == _S_c_rb_tree_red)
|
{
|
if(val->_A_parent == val->_A_parent->_A_parent->_A_left)
|
{
|
_base_ptr wal = val->_A_parent->_A_parent->_A_right;
|
if(wal && wal->_A_color == _S_c_rb_tree_red)
|
{
|
val->_A_parent->_A_color = _S_c_rb_tree_black;
|
wal->_A_color = _S_c_rb_tree_black;
|
val->_A_parent->_A_parent->_A_color = _S_c_rb_tree_red;
|
val = val->_A_parent->_A_parent;
|
}
|
else
|
{
|
if(val == val->_A_parent->_A_right)
|
{
|
val = val->_A_parent;
|
_c_rb_tree_rotate_left(val, proot);
|
}
|
val->_A_parent->_A_color = _S_c_rb_tree_black;
|
val->_A_parent->_A_parent->_A_color = _S_c_rb_tree_red;
|
_c_rb_tree_rotate_right(val->_A_parent->_A_parent, proot);
|
}
|
}
|
else
|
{
|
_base_ptr wal = val->_A_parent->_A_parent->_A_left;
|
if(wal && wal->_A_color == _S_c_rb_tree_red)
|
{
|
val->_A_parent->_A_color = _S_c_rb_tree_black;
|
wal->_A_color = _S_c_rb_tree_black;
|
val->_A_parent->_A_parent->_A_color = _S_c_rb_tree_red;
|
val = val->_A_parent->_A_parent;
|
}
|
else
|
{
|
if(val == val->_A_parent->_A_left)
|
{
|
val = val->_A_parent;
|
_c_rb_tree_rotate_right(val, proot);
|
}
|
val->_A_parent->_A_color = _S_c_rb_tree_black;
|
val->_A_parent->_A_parent->_A_color = _S_c_rb_tree_red;
|
_c_rb_tree_rotate_left(val->_A_parent->_A_parent, proot);
|
}
|
}
|
}
|
(*proot)->_A_color = _S_c_rb_tree_black;
|
}
|
|
static _base_ptr _c_rb_tree_rebalance_for_erase(_base_ptr z,
|
_base_ptr * root,
|
_base_ptr * leftmost,
|
_base_ptr * rightmost)
|
{
|
_base_ptr y = z;
|
_base_ptr x = NULL;
|
_base_ptr x_parent = NULL;
|
|
if(y->_A_left == NULL)
|
x = y->_A_right;
|
else
|
if(y->_A_right == NULL)
|
x = y->_A_left;
|
else
|
{
|
y = y->_A_right;
|
while(y->_A_left != NULL)
|
y = y->_A_left;
|
x = y->_A_right;
|
}
|
|
if(y != z)
|
{
|
_c_rb_tree_color_type tmp;
|
z->_A_left->_A_parent = y;
|
y->_A_left = z->_A_left;
|
if(y != z->_A_right)
|
{
|
x_parent = y->_A_parent;
|
if(x)
|
x->_A_parent = y->_A_parent;
|
y->_A_parent->_A_left = x;
|
y->_A_right = z->_A_right;
|
z->_A_right->_A_parent = y;
|
}
|
else
|
x_parent = y;
|
if(*root == z)
|
*root = y;
|
else if(z->_A_parent->_A_left == z)
|
z->_A_parent->_A_left = y;
|
else
|
z->_A_parent->_A_right = y;
|
y->_A_parent = z->_A_parent;
|
C_SWAP(y->_A_color, z->_A_color, tmp);
|
y = z;
|
}
|
else
|
{
|
x_parent = y->_A_parent;
|
if(x)
|
x->_A_parent = y->_A_parent;
|
if(*root == z)
|
*root = x;
|
else
|
{
|
if(z->_A_parent->_A_left == z)
|
z->_A_parent->_A_left = x;
|
else
|
z->_A_parent->_A_right = x;
|
}
|
if(*leftmost == z)
|
{
|
if(z->_A_right == NULL)
|
*leftmost = z->_A_parent;
|
else
|
*leftmost = _S_minimum(x);
|
}
|
if(*rightmost == z)
|
{
|
if(z->_A_left == NULL)
|
*rightmost = z->_A_parent;
|
else
|
*rightmost = _S_maximum(x);
|
}
|
}
|
if(y->_A_color != _S_c_rb_tree_red)
|
{
|
while(x != *root &&
|
(x == NULL ||
|
x->_A_color == _S_c_rb_tree_black))
|
if(x == x_parent->_A_left)
|
{
|
_base_ptr w = x_parent->_A_right;
|
if(w->_A_color == _S_c_rb_tree_red)
|
{
|
w->_A_color = _S_c_rb_tree_black;
|
x_parent->_A_color = _S_c_rb_tree_red;
|
_c_rb_tree_rotate_left(x_parent, root);
|
w = x_parent->_A_right;
|
}
|
if((w->_A_left == NULL ||
|
w->_A_left->_A_color == _S_c_rb_tree_black) &&
|
(w->_A_right == NULL ||
|
w->_A_right->_A_color == _S_c_rb_tree_black))
|
{
|
w->_A_color = _S_c_rb_tree_red;
|
x = x_parent;
|
x_parent = x_parent->_A_parent;
|
}
|
else
|
{
|
if(w->_A_right == NULL ||
|
w->_A_right->_A_color == _S_c_rb_tree_black)
|
{
|
if(w->_A_left)
|
w->_A_left->_A_color = _S_c_rb_tree_black;
|
w->_A_color = _S_c_rb_tree_red;
|
_c_rb_tree_rotate_right(w, root);
|
w = x_parent->_A_right;
|
}
|
w->_A_color = x_parent->_A_color;
|
x_parent->_A_color = _S_c_rb_tree_black;
|
if(w->_A_right)
|
w->_A_right->_A_color = _S_c_rb_tree_black;
|
_c_rb_tree_rotate_left(x_parent, root);
|
break;
|
}
|
}
|
else
|
{
|
_base_ptr w = x_parent->_A_left;
|
if(w->_A_color == _S_c_rb_tree_red)
|
{
|
w->_A_color = _S_c_rb_tree_black;
|
x_parent->_A_color = _S_c_rb_tree_red;
|
_c_rb_tree_rotate_right(x_parent, root);
|
w = x_parent->_A_left;
|
}
|
if((w->_A_right == NULL ||
|
w->_A_right->_A_color == _S_c_rb_tree_black) &&
|
(w->_A_left == NULL ||
|
w->_A_left->_A_color == _S_c_rb_tree_black))
|
{
|
w->_A_color = _S_c_rb_tree_red;
|
x = x_parent;
|
x_parent = x_parent->_A_parent;
|
}
|
else
|
{
|
if(w->_A_left == NULL ||
|
w->_A_left->_A_color == _S_c_rb_tree_black)
|
{
|
if(w->_A_right)
|
w->_A_right->_A_color = _S_c_rb_tree_black;
|
w->_A_color = _S_c_rb_tree_red;
|
_c_rb_tree_rotate_left(w, root);
|
w = x_parent->_A_left;
|
}
|
w->_A_color = x_parent->_A_color;
|
x_parent->_A_color = _S_c_rb_tree_black;
|
if(w->_A_left)
|
w->_A_left->_A_color = _S_c_rb_tree_black;
|
_c_rb_tree_rotate_right(x_parent, root);
|
break;
|
}
|
}
|
if(x)
|
x->_A_color = _S_c_rb_tree_black;
|
}
|
return y;
|
}
|
|
static _base_ptr _A_get_node()
|
{
|
_base_ptr tmp = __c_malloc(sizeof(_c_rb_tree_node));
|
memset(tmp, 0, sizeof(_c_rb_tree_node));
|
return tmp;
|
}
|
|
static void _A_put_node(_base_ptr val)
|
{
|
__c_free(val);
|
}
|
|
static _base_ptr _A_create_node(const value_type val)
|
{
|
_base_ptr tmp = _A_get_node();
|
tmp->_A_value_field = val;
|
return tmp;
|
}
|
|
static _base_ptr _A_clone_node(_base_ptr val)
|
{
|
_base_ptr tmp = _A_create_node(val->_A_value_field);
|
tmp->_A_color = val->_A_color;
|
tmp->_A_left = NULL;
|
tmp->_A_right = NULL;
|
return tmp;
|
}
|
|
static void _A_destroy_node(_base_ptr val)
|
{
|
_A_put_node(val);
|
}
|
|
static _base_ptr * _A_root(c_prb_tree thiz)
|
{
|
return &thiz->_A_header->_A_parent;
|
}
|
|
static _base_ptr * _A_leftmost(c_prb_tree thiz)
|
{
|
return &thiz->_A_header->_A_left;
|
}
|
|
static _base_ptr * _A_rightmost(c_prb_tree thiz)
|
{
|
return &thiz->_A_header->_A_right;
|
}
|
|
static _base_ptr * _S_left(_base_ptr val)
|
{
|
return &val->_A_left;
|
}
|
|
static _base_ptr * _S_right(_base_ptr val)
|
{
|
return &val->_A_right;
|
}
|
|
static _base_ptr * _S_parent(_base_ptr val)
|
{
|
return &val->_A_parent;
|
}
|
|
static value_type * _S_value(_base_ptr val)
|
{
|
return &val->_A_value_field;
|
}
|
|
static key_type _S_key(c_prb_tree thiz, _base_ptr val)
|
{
|
return thiz->_A_keyofvalue.O(&thiz->_A_keyofvalue, *_S_value(val));
|
}
|
|
static _color_type * _S_color(_base_ptr val)
|
{
|
return &val->_A_color;
|
}
|
|
static c_iterator _A_insert(c_prb_tree thiz, _base_ptr x, _base_ptr y, const value_type val)
|
{
|
_base_ptr _x = x;
|
_base_ptr _y = y;
|
_base_ptr _z = NULL;
|
if(_y == thiz->_A_header ||
|
_x != NULL ||
|
thiz->_A_key_compare(thiz->_A_keyofvalue.O(&thiz->_A_keyofvalue, val),
|
_S_key(thiz, _y)) < 0)
|
{
|
_z = _A_create_node(val);
|
*_S_left(_y) = _z;
|
|
if(_y == thiz->_A_header)
|
{
|
*_A_root(thiz) = _z;
|
*_A_rightmost(thiz) = _z;
|
}
|
else if(_y == *_A_leftmost(thiz))
|
*_A_leftmost(thiz) = _z;
|
}
|
else
|
{
|
_z = _A_create_node(val);
|
*_S_right(_y) = _z;
|
if(_y == *_A_rightmost(thiz))
|
*_A_rightmost(thiz) = _z;
|
}
|
|
*_S_parent(_z) = _y;
|
*_S_left(_z) = NULL;
|
*_S_right(_z) = NULL;
|
_c_rb_tree_rebalance(_z, &thiz->_A_header->_A_parent);
|
++ thiz->_A_node_count;
|
return _A_get_iterator(_z);
|
}
|
|
static _base_ptr _A_copy(_base_ptr x, _base_ptr p)
|
{
|
_base_ptr top = _A_clone_node(x);
|
top->_A_parent = p;
|
|
if(x->_A_right)
|
top->_A_right = _A_copy(*_S_right(x), top);
|
p = top;
|
x = *_S_left(x);
|
|
while(x != NULL)
|
{
|
_base_ptr y = _A_clone_node(x);
|
p->_A_left = y;
|
y->_A_parent = p;
|
if(x->_A_right)
|
y->_A_right = _A_copy(*_S_right(x), y);
|
p = y;
|
x = *_S_left(x);
|
}
|
|
return top;
|
}
|
|
static void _A_erase(_base_ptr x)
|
{
|
while(x != NULL)
|
{
|
_base_ptr y;
|
_A_erase(*_S_right(x));
|
y = *_S_left(x);
|
_A_destroy_node(x);
|
x = y;
|
}
|
}
|
|
static void _A_empty_initialize(c_prb_tree thiz)
|
{
|
*_S_color(thiz->_A_header) = _S_c_rb_tree_red;
|
*_A_root(thiz) = NULL;
|
*_A_leftmost(thiz) = thiz->_A_header;
|
*_A_rightmost(thiz) = thiz->_A_header;
|
}
|
|
void __c_rb_tree(c_prb_tree thiz, COMPARER pcmp)
|
{
|
thiz->_A_header = _A_get_node();
|
thiz->_A_node_count = 0;
|
thiz->_A_key_compare = pcmp;
|
_A_empty_initialize(thiz);
|
}
|
|
void __c_eert_br(c_prb_tree thiz)
|
{
|
c_rb_tree_clear(thiz);
|
_A_put_node(thiz->_A_header);
|
}
|
|
c_prb_tree c_rb_tree_assign(c_prb_tree thiz, const c_prb_tree T)
|
{
|
if(thiz != T)
|
{
|
c_rb_tree_clear(thiz);
|
thiz->_A_node_count = 0;
|
thiz->_A_key_compare = T->_A_key_compare;
|
if(*_A_root(T) == NULL)
|
{
|
*_A_root(thiz) = NULL;
|
*_A_leftmost(thiz) = thiz->_A_header;
|
*_A_rightmost(thiz) = thiz->_A_header;
|
}
|
else
|
{
|
*_A_root(thiz) = _A_copy(*_A_root(T), thiz->_A_header);
|
*_A_leftmost(thiz) = _S_minimum(*_A_root(thiz));
|
*_A_rightmost(thiz) = _S_maximum(*_A_root(thiz));
|
thiz->_A_node_count = T->_A_node_count;
|
}
|
}
|
return thiz;
|
}
|
|
c_iterator c_rb_tree_begin(c_prb_tree thiz)
|
{
|
return _A_get_iterator(*_A_leftmost(thiz));
|
}
|
|
c_iterator c_rb_tree_end(c_prb_tree thiz)
|
{
|
return _A_get_iterator(thiz->_A_header);
|
}
|
|
c_reverse_iterator c_rb_tree_rbegin(c_prb_tree thiz)
|
{
|
return _A_get_reverse_iterator(thiz->_A_header);
|
}
|
|
c_reverse_iterator c_rb_tree_rend(c_prb_tree thiz)
|
{
|
return _A_get_reverse_iterator(*_A_leftmost(thiz));
|
}
|
|
c_bool c_rb_tree_empty(c_prb_tree thiz)
|
{
|
return thiz->_A_node_count == 0;
|
}
|
|
size_type c_rb_tree_size(c_prb_tree thiz)
|
{
|
return thiz->_A_node_count;
|
}
|
|
size_type c_rb_tree_max_size(c_prb_tree thiz)
|
{
|
return (size_type)(-1);
|
}
|
|
void c_rb_tree_swap(c_prb_tree thiz, c_prb_tree T)
|
{
|
c_rb_tree tmp;
|
C_SWAP(*thiz, *T, tmp);
|
}
|
|
c_iter_bool_pair c_rb_tree_insert_unique(c_prb_tree thiz, const value_type val)
|
{
|
_base_ptr y = thiz->_A_header;
|
_base_ptr x = *_A_root(thiz);
|
c_bool comp = 1;
|
c_iterator j;
|
|
while(x != NULL)
|
{
|
y = x;
|
comp = thiz->_A_key_compare(thiz->_A_keyofvalue.O(&thiz->_A_keyofvalue, val),
|
_S_key(thiz, x)) < 0;
|
x = comp ? *_S_left(x) : *_S_right(x);
|
}
|
j = _A_get_iterator(y);
|
if(comp)
|
{
|
c_iterator beg = c_rb_tree_begin(thiz);
|
if(ITER_EQUAL(j, beg))
|
return c_make_iter_bool_pair(_A_insert(thiz, x, y, val), true);
|
else
|
ITER_DEC(j);
|
}
|
if(thiz->_A_key_compare(_S_key(thiz, j._i),
|
thiz->_A_keyofvalue.O(&thiz->_A_keyofvalue, val)) < 0)
|
return c_make_iter_bool_pair(_A_insert(thiz, x, y, val), true);
|
return c_make_iter_bool_pair(j, false);
|
}
|
|
c_iterator c_rb_tree_insert_equal(c_prb_tree thiz, const value_type val)
|
{
|
_base_ptr y = thiz->_A_header;
|
_base_ptr x = *_A_root(thiz);
|
while(x != NULL)
|
{
|
y = x;
|
x = thiz->_A_key_compare(thiz->_A_keyofvalue.O(&thiz->_A_keyofvalue, val),
|
_S_key(thiz, x)) < 0 ?
|
*_S_left(x) : *_S_right(x);
|
}
|
return _A_insert(thiz, x, y, val);
|
}
|
|
c_iterator c_rb_tree_insert_unique1(c_prb_tree thiz, c_iterator position, const value_type val)
|
{
|
if(position._i == thiz->_A_header->_A_left)
|
{
|
if(c_rb_tree_size(thiz) > 0 &&
|
thiz->_A_key_compare(thiz->_A_keyofvalue.O(&thiz->_A_keyofvalue, val),
|
_S_key(thiz, position._i)) < 0)
|
return _A_insert(thiz, position._i, position._i, val);
|
else
|
return c_rb_tree_insert_unique(thiz, val).first;
|
}
|
else if(position._i == thiz->_A_header)
|
{
|
if(thiz->_A_key_compare(_S_key(thiz, *_A_rightmost(thiz)),
|
thiz->_A_keyofvalue.O(&thiz->_A_keyofvalue,
|
val)) < 0)
|
return _A_insert(thiz, 0, *_A_rightmost(thiz), val);
|
else
|
return c_rb_tree_insert_unique(thiz, val).first;
|
}
|
else
|
{
|
c_iterator before = position;
|
ITER_DEC(before);
|
if(thiz->_A_key_compare(_S_key(thiz, before._i),
|
thiz->_A_keyofvalue.O(&thiz->_A_keyofvalue,
|
val)) < 0 &&
|
thiz->_A_key_compare(thiz->_A_keyofvalue.O(&thiz->_A_keyofvalue,
|
val),
|
_S_key(thiz, position._i)) < 0)
|
if(*_S_right(before._i) == NULL)
|
return _A_insert(thiz, 0, before._i, val);
|
else
|
return _A_insert(thiz, position._i, position._i, val);
|
else
|
return c_rb_tree_insert_unique(thiz, val).first;
|
}
|
}
|
|
c_iterator c_rb_tree_insert_equal1(c_prb_tree thiz, c_iterator position, const value_type val)
|
{
|
if(position._i == thiz->_A_header->_A_left)
|
{
|
if(c_rb_tree_size(thiz) > 0 &&
|
thiz->_A_key_compare(_S_key(thiz, position._i),
|
thiz->_A_keyofvalue.O(&thiz->_A_keyofvalue,
|
val)) >= 0)
|
return _A_insert(thiz, position._i, position._i, val);
|
else
|
return c_rb_tree_insert_equal(thiz, val);
|
}
|
else if(position._i == thiz->_A_header)
|
{
|
if(thiz->_A_key_compare(thiz->_A_keyofvalue.O(&thiz->_A_keyofvalue, val),
|
_S_key(thiz, *_A_rightmost(thiz))) >= 0)
|
return _A_insert(thiz, 0, *_A_rightmost(thiz), val);
|
else
|
return c_rb_tree_insert_equal(thiz, val);
|
}
|
else
|
{
|
c_iterator before = position;
|
ITER_DEC(before);
|
if(thiz->_A_key_compare(thiz->_A_keyofvalue.O(&thiz->_A_keyofvalue,
|
val),
|
_S_key(thiz, before._i)) >= 0 &&
|
thiz->_A_key_compare(_S_key(thiz, position._i),
|
thiz->_A_keyofvalue.O(&thiz->_A_keyofvalue,
|
val)) >= 0)
|
{
|
if(*_S_right(before._i) == NULL)
|
return _A_insert(thiz, 0, before._i, val);
|
else
|
return _A_insert(thiz, position._i, position._i, val);
|
}
|
else
|
return c_rb_tree_insert_equal(thiz, val);
|
|
}
|
}
|
|
void c_rb_tree_insert_unique2(c_prb_tree thiz, c_iterator first, c_iterator last)
|
{
|
for(; !ITER_EQUAL(first, last); ITER_INC(first))
|
c_rb_tree_insert_unique(thiz, ITER_REF(first));
|
}
|
|
void c_rb_tree_insert_equal2(c_prb_tree thiz, c_iterator first, c_iterator last)
|
{
|
for(; !ITER_EQUAL(first, last); ITER_INC(first))
|
c_rb_tree_insert_equal(thiz, ITER_REF(first));
|
}
|
|
void c_rb_tree_erase(c_prb_tree thiz, c_iterator position)
|
{
|
_base_ptr y = _c_rb_tree_rebalance_for_erase(position._i,
|
&thiz->_A_header->_A_parent,
|
&thiz->_A_header->_A_left,
|
&thiz->_A_header->_A_right);
|
_A_destroy_node(y);
|
-- thiz->_A_node_count;
|
}
|
|
size_type c_rb_tree_erase1(c_prb_tree thiz, key_type key)
|
{
|
c_iter_iter_pair p = c_rb_tree_equal_range(thiz, key);
|
difference_type n = 0;
|
c_distance1(p.first, p.second, &n);
|
c_rb_tree_erase2(thiz, p.first, p.second);
|
return n;
|
}
|
|
void c_rb_tree_erase2(c_prb_tree thiz, c_iterator first, c_iterator last)
|
{
|
c_iterator begin, end;
|
begin = c_rb_tree_begin(thiz);
|
end = c_rb_tree_end(thiz);
|
if(ITER_EQUAL(first, begin) &&
|
ITER_EQUAL(last, end))
|
c_rb_tree_clear(thiz);
|
else
|
while(!ITER_EQUAL(first, last))
|
{
|
c_rb_tree_erase(thiz, first);
|
ITER_INC(first);
|
}
|
}
|
|
void c_rb_tree_clear(c_prb_tree thiz)
|
{
|
if(thiz->_A_node_count != 0)
|
{
|
_A_erase(*_A_root(thiz));
|
*_A_leftmost(thiz) = thiz->_A_header;
|
*_A_root(thiz) = NULL;
|
*_A_rightmost(thiz) = thiz->_A_header;
|
thiz->_A_node_count = 0;
|
}
|
}
|
|
|
c_iterator c_rb_tree_find(c_prb_tree thiz, key_type key)
|
{
|
_base_ptr y = thiz->_A_header;
|
_base_ptr x = *_A_root(thiz);
|
c_iterator j;
|
c_iterator end = c_rb_tree_end(thiz);
|
|
while(x != NULL)
|
if(thiz->_A_key_compare(_S_key(thiz, x), key) >= 0)
|
{
|
y = x;
|
x = *_S_left(x);
|
}
|
else
|
x = *_S_right(x);
|
j = _A_get_iterator(y);
|
return (ITER_EQUAL(j, end) ||
|
thiz->_A_key_compare(key, _S_key(thiz, j._i)) < 0) ?
|
end : j;
|
}
|
|
size_type c_rb_tree_count(c_prb_tree thiz, key_type key)
|
{
|
c_iter_iter_pair p = c_rb_tree_equal_range(thiz, key);
|
difference_type n = 0;
|
c_distance1(p.first, p.second, &n);
|
return abs(n);
|
}
|
|
c_iterator c_rb_tree_lower_bound(c_prb_tree thiz, key_type key)
|
{
|
_base_ptr y = thiz->_A_header;
|
_base_ptr x = *_A_root(thiz);
|
|
while(x != NULL)
|
if(thiz->_A_key_compare(_S_key(thiz, x), key) >= 0)
|
{
|
y = x;
|
x = *_S_left(x);
|
}
|
else
|
x = *_S_right(x);
|
|
return _A_get_iterator(y);
|
}
|
|
c_iterator c_rb_tree_upper_bound(c_prb_tree thiz, key_type key)
|
{
|
_base_ptr y = thiz->_A_header;
|
_base_ptr x = *_A_root(thiz);
|
|
while(x != NULL)
|
if(thiz->_A_key_compare(key, _S_key(thiz, x)) < 0)
|
{
|
y = x;
|
x = *_S_left(x);
|
}
|
else
|
x = *_S_right(x);
|
|
return _A_get_iterator(y);
|
}
|
|
c_iter_iter_pair c_rb_tree_equal_range(c_prb_tree thiz, key_type key)
|
{
|
return c_make_iter_iter_pair(c_rb_tree_lower_bound(thiz, key),
|
c_rb_tree_upper_bound(thiz, key));
|
}
|
|
c_bool c_rb_tree_less(c_prb_tree thiz, const c_prb_tree T, COMPARER cmp)
|
{
|
return c_lexicographical_compare(c_rb_tree_begin(thiz),
|
c_rb_tree_end(thiz),
|
c_rb_tree_begin(T),
|
c_rb_tree_end(T),
|
cmp);
|
}
|
|
c_bool c_rb_tree_equal(c_prb_tree thiz, const c_prb_tree T, COMPARER cmp)
|
{
|
c_binary_predicate bpred = c_binary_negate(cmp);
|
return c_rb_tree_size(thiz) == c_rb_tree_size(T) &&
|
c_equal2(c_rb_tree_begin(thiz), c_rb_tree_end(thiz), c_rb_tree_begin(T), bpred);
|
}
|
|
static int __black_count(_base_ptr node, _base_ptr root)
|
{
|
if(node == NULL)
|
return 0;
|
else
|
{
|
int bc = node->_A_color == _S_c_rb_tree_black ? 1 : 0;
|
if(node == root)
|
return bc;
|
else
|
return bc + __black_count(node->_A_parent, root);
|
}
|
}
|
|
c_bool __c_rb_tree_verify(c_prb_tree thiz)
|
{
|
c_iterator begin = c_rb_tree_begin(thiz);
|
c_iterator end = c_rb_tree_end(thiz);
|
int len;
|
c_iterator iter;
|
|
if(thiz->_A_node_count == 0 || ITER_EQUAL(begin, end))
|
return thiz->_A_node_count == 0 && ITER_EQUAL(begin, end) &&
|
thiz->_A_header->_A_left == thiz->_A_header &&
|
thiz->_A_header->_A_right == thiz->_A_header;
|
|
len = __black_count(*_A_leftmost(thiz), *_A_root(thiz));
|
for(iter = c_rb_tree_begin(thiz); !ITER_EQUAL(iter, end); ITER_INC(iter))
|
{
|
_base_ptr x = iter._i;
|
_base_ptr L = *_S_left(x);
|
_base_ptr R = *_S_right(x);
|
|
if(x->_A_color == _S_c_rb_tree_red)
|
if((L && L->_A_color == _S_c_rb_tree_red) ||
|
(R && R->_A_color == _S_c_rb_tree_red))
|
return false;
|
|
if(L && thiz->_A_key_compare(_S_key(thiz, x), _S_key(thiz, L)) < 0)
|
return false;
|
if(R && thiz->_A_key_compare(_S_key(thiz, R), _S_key(thiz, x)) < 0)
|
return false;
|
|
if(!L && !R && __black_count(x, *_A_root(thiz)) != len)
|
return false;
|
}
|
|
if(*_A_leftmost(thiz) != _S_minimum(*_A_root(thiz)))
|
return false;
|
if(*_A_rightmost(thiz) != _S_maximum(*_A_root(thiz)))
|
return false;
|
|
return true;
|
}
|