You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
655 lines
30 KiB
655 lines
30 KiB
// tree internal header
|
|
#ifndef _TREE_
|
|
#define _TREE_
|
|
#include <cstddef>
|
|
#include <iterator>
|
|
#include <memory>
|
|
#include <xutility>
|
|
|
|
#ifdef _MSC_VER
|
|
#pragma pack(push,8)
|
|
#endif /* _MSC_VER */
|
|
_STD_BEGIN
|
|
// TEMPLATE CLASS _Tree
|
|
template<class _K, class _Ty, class _Kfn, class _Pr, class _A>
|
|
class _Tree {
|
|
protected:
|
|
typedef _POINTER_X(void, _A) _Genptr;
|
|
enum _Redbl {_Red, _Black};
|
|
struct _Node;
|
|
friend struct _Node;
|
|
struct _Node {
|
|
_Genptr _Left, _Parent, _Right;
|
|
_Ty _Value;
|
|
_Redbl _Color;
|
|
};
|
|
typedef _POINTER_X(_Node, _A) _Nodeptr;
|
|
typedef _REFERENCE_X(_Nodeptr, _A) _Nodepref;
|
|
typedef _REFERENCE_X(const _K, _A) _Keyref;
|
|
typedef _REFERENCE_X(_Redbl, _A) _Rbref;
|
|
typedef _REFERENCE_X(_Ty, _A) _Vref;
|
|
static _Rbref _Color(_Nodeptr _P)
|
|
{return ((_Rbref)(*_P)._Color); }
|
|
static _Keyref _Key(_Nodeptr _P)
|
|
{return (_Kfn()(_Value(_P))); }
|
|
static _Nodepref _Left(_Nodeptr _P)
|
|
{return ((_Nodepref)(*_P)._Left); }
|
|
static _Nodepref _Parent(_Nodeptr _P)
|
|
{return ((_Nodepref)(*_P)._Parent); }
|
|
static _Nodepref _Right(_Nodeptr _P)
|
|
{return ((_Nodepref)(*_P)._Right); }
|
|
static _Vref _Value(_Nodeptr _P)
|
|
{return ((_Vref)(*_P)._Value); }
|
|
public:
|
|
typedef _Tree<_K, _Ty, _Kfn, _Pr, _A> _Myt;
|
|
typedef _K key_type;
|
|
typedef _Ty value_type;
|
|
typedef typename _A::size_type size_type;
|
|
typedef typename _A::difference_type difference_type;
|
|
typedef _POINTER_X(_Ty, _A) _Tptr;
|
|
typedef _POINTER_X(const _Ty, _A) _Ctptr;
|
|
typedef _REFERENCE_X(_Ty, _A) reference;
|
|
typedef _REFERENCE_X(const _Ty, _A) const_reference;
|
|
// CLASS iterator
|
|
class iterator;
|
|
friend class iterator;
|
|
class iterator : public _Bidit<_Ty, difference_type> {
|
|
public:
|
|
iterator()
|
|
{}
|
|
iterator(_Nodeptr _P)
|
|
: _Ptr(_P) {}
|
|
reference operator*() const
|
|
{return (_Value(_Ptr)); }
|
|
_Tptr operator->() const
|
|
{return (&**this); }
|
|
iterator& operator++()
|
|
{_Inc();
|
|
return (*this); }
|
|
iterator operator++(int)
|
|
{iterator _Tmp = *this;
|
|
++*this;
|
|
return (_Tmp); }
|
|
iterator& operator--()
|
|
{_Dec();
|
|
return (*this); }
|
|
iterator operator--(int)
|
|
{iterator _Tmp = *this;
|
|
--*this;
|
|
return (_Tmp); }
|
|
bool operator==(const iterator& _X) const
|
|
{return (_Ptr == _X._Ptr); }
|
|
bool operator!=(const iterator& _X) const
|
|
{return (!(*this == _X)); }
|
|
void _Dec()
|
|
{if (_Color(_Ptr) == _Red
|
|
&& _Parent(_Parent(_Ptr)) == _Ptr)
|
|
_Ptr = _Right(_Ptr);
|
|
else if (_Left(_Ptr) != _Nil)
|
|
_Ptr = _Max(_Left(_Ptr));
|
|
else
|
|
{_Nodeptr _P;
|
|
while (_Ptr == _Left(_P = _Parent(_Ptr)))
|
|
_Ptr = _P;
|
|
_Ptr = _P; }}
|
|
void _Inc()
|
|
{if (_Right(_Ptr) != _Nil)
|
|
_Ptr = _Min(_Right(_Ptr));
|
|
else
|
|
{_Nodeptr _P;
|
|
while (_Ptr == _Right(_P = _Parent(_Ptr)))
|
|
_Ptr = _P;
|
|
if (_Right(_Ptr) != _P)
|
|
_Ptr = _P; }}
|
|
_Nodeptr _Mynode() const
|
|
{return (_Ptr); }
|
|
protected:
|
|
_Nodeptr _Ptr;
|
|
};
|
|
// CLASS const_iterator
|
|
class const_iterator;
|
|
friend class const_iterator;
|
|
class const_iterator : public iterator {
|
|
public:
|
|
const_iterator()
|
|
{}
|
|
const_iterator(_Nodeptr _P)
|
|
: iterator(_P) {}
|
|
const_iterator(const iterator& _X)
|
|
: iterator(_X) {}
|
|
const_reference operator*() const
|
|
{return (_Value(_Ptr)); }
|
|
_Ctptr operator->() const
|
|
{return (&**this); }
|
|
const_iterator& operator++()
|
|
{_Inc();
|
|
return (*this); }
|
|
const_iterator operator++(int)
|
|
{iterator _Tmp = *this;
|
|
++*this;
|
|
return (_Tmp); }
|
|
const_iterator& operator--()
|
|
{_Dec();
|
|
return (*this); }
|
|
const_iterator operator--(int)
|
|
{iterator _Tmp = *this;
|
|
--*this;
|
|
return (_Tmp); }
|
|
bool operator==(const const_iterator& _X) const
|
|
{return (_Ptr == _X._Ptr); }
|
|
bool operator!=(const const_iterator& _X) const
|
|
{return (!(*this == _X)); }
|
|
};
|
|
typedef reverse_bidirectional_iterator<iterator,
|
|
value_type, reference, _Tptr, difference_type>
|
|
reverse_iterator;
|
|
typedef reverse_bidirectional_iterator<const_iterator,
|
|
value_type, const_reference, _Ctptr, difference_type>
|
|
const_reverse_iterator;
|
|
typedef pair<iterator, bool> _Pairib;
|
|
typedef pair<iterator, iterator> _Pairii;
|
|
typedef pair<const_iterator, const_iterator> _Paircc;
|
|
explicit _Tree(const _Pr& _Parg, bool _Marg = true,
|
|
const _A& _Al = _A())
|
|
: allocator(_Al),
|
|
key_compare(_Parg), _Multi(_Marg)
|
|
{_Init(); }
|
|
_Tree(const _Ty *_F, const _Ty *_L,
|
|
const _Pr& _Parg, bool _Marg = true,
|
|
const _A& _Al = _A())
|
|
: allocator(_Al),
|
|
key_compare(_Parg), _Multi(_Marg)
|
|
{_Init();
|
|
insert(_F, _L); }
|
|
_Tree(const _Myt& _X)
|
|
: allocator(_X.allocator),
|
|
key_compare(_X.key_compare), _Multi(_X._Multi)
|
|
{_Init();
|
|
_Copy(_X); }
|
|
~_Tree()
|
|
{erase(begin(), end());
|
|
_Freenode(_Head);
|
|
_Head = 0, _Size = 0;
|
|
_Nodeptr _Tmp = 0;
|
|
{_Lockit _Lk;
|
|
if (--_Nilrefs == 0)
|
|
{_Tmp = _Nil;
|
|
_Nil = 0; }}
|
|
if (_Tmp != 0)
|
|
_Freenode(_Tmp); }
|
|
_Myt& operator=(const _Myt& _X)
|
|
{if (this != &_X)
|
|
{erase(begin(), end());
|
|
key_compare = _X.key_compare;
|
|
_Copy(_X); }
|
|
return (*this); }
|
|
iterator begin()
|
|
{return (iterator(_Lmost())); }
|
|
const_iterator begin() const
|
|
{return (const_iterator(_Lmost())); }
|
|
iterator end()
|
|
{return (iterator(_Head)); }
|
|
const_iterator end() const
|
|
{return (const_iterator(_Head)); }
|
|
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())); }
|
|
size_type size() const
|
|
{return (_Size); }
|
|
size_type max_size() const
|
|
{return (allocator.max_size()); }
|
|
bool empty() const
|
|
{return (size() == 0); }
|
|
_A get_allocator() const
|
|
{return (allocator); }
|
|
_Pr key_comp() const
|
|
{return (key_compare); }
|
|
_Pairib insert(const value_type& _V)
|
|
{_Nodeptr _X = _Root();
|
|
_Nodeptr _Y = _Head;
|
|
bool _Ans = true;
|
|
while (_X != _Nil)
|
|
{_Y = _X;
|
|
_Ans = key_compare(_Kfn()(_V), _Key(_X));
|
|
_X = _Ans ? _Left(_X) : _Right(_X); }
|
|
if (_Multi)
|
|
return (_Pairib(_Insert(_X, _Y, _V), true));
|
|
iterator _P = iterator(_Y);
|
|
if (!_Ans)
|
|
;
|
|
else if (_P == begin())
|
|
return (_Pairib(_Insert(_X, _Y, _V), true));
|
|
else
|
|
--_P;
|
|
if (key_compare(_Key(_P._Mynode()), _Kfn()(_V)))
|
|
return (_Pairib(_Insert(_X, _Y, _V), true));
|
|
return (_Pairib(_P, false)); }
|
|
iterator insert(iterator _P, const value_type& _V)
|
|
{if (size() == 0)
|
|
;
|
|
else if (_P == begin())
|
|
{if (key_compare(_Kfn()(_V), _Key(_P._Mynode())))
|
|
return (_Insert(_Head, _P._Mynode(), _V)); }
|
|
else if (_P == end())
|
|
{if (key_compare(_Key(_Rmost()), _Kfn()(_V)))
|
|
return (_Insert(_Nil, _Rmost(), _V)); }
|
|
else
|
|
{iterator _Pb = _P;
|
|
if (key_compare(_Key((--_Pb)._Mynode()), _Kfn()(_V))
|
|
&& key_compare(_Kfn()(_V), _Key(_P._Mynode())))
|
|
{if (_Right(_Pb._Mynode()) == _Nil)
|
|
return (_Insert(_Nil, _Pb._Mynode(), _V));
|
|
else
|
|
return (_Insert(_Head, _P._Mynode(), _V)); }}
|
|
return (insert(_V).first); }
|
|
void insert(iterator _F, iterator _L)
|
|
{for (; _F != _L; ++_F)
|
|
insert(*_F); }
|
|
void insert(const value_type *_F, const value_type *_L)
|
|
{for (; _F != _L; ++_F)
|
|
insert(*_F); }
|
|
iterator erase(iterator _P)
|
|
{_Nodeptr _X;
|
|
_Nodeptr _Y = (_P++)._Mynode();
|
|
_Nodeptr _Z = _Y;
|
|
if (_Left(_Y) == _Nil)
|
|
_X = _Right(_Y);
|
|
else if (_Right(_Y) == _Nil)
|
|
_X = _Left(_Y);
|
|
else
|
|
_Y = _Min(_Right(_Y)), _X = _Right(_Y);
|
|
{ _Lockit _Lk;
|
|
if (_Y != _Z)
|
|
{_Parent(_Left(_Z)) = _Y;
|
|
_Left(_Y) = _Left(_Z);
|
|
if (_Y == _Right(_Z))
|
|
_Parent(_X) = _Y;
|
|
else
|
|
{_Parent(_X) = _Parent(_Y);
|
|
_Left(_Parent(_Y)) = _X;
|
|
_Right(_Y) = _Right(_Z);
|
|
_Parent(_Right(_Z)) = _Y; }
|
|
if (_Root() == _Z)
|
|
_Root() = _Y;
|
|
else if (_Left(_Parent(_Z)) == _Z)
|
|
_Left(_Parent(_Z)) = _Y;
|
|
else
|
|
_Right(_Parent(_Z)) = _Y;
|
|
_Parent(_Y) = _Parent(_Z);
|
|
std::swap(_Color(_Y), _Color(_Z));
|
|
_Y = _Z; }
|
|
else
|
|
{_Parent(_X) = _Parent(_Y);
|
|
if (_Root() == _Z)
|
|
_Root() = _X;
|
|
else if (_Left(_Parent(_Z)) == _Z)
|
|
_Left(_Parent(_Z)) = _X;
|
|
else
|
|
_Right(_Parent(_Z)) = _X;
|
|
if (_Lmost() != _Z)
|
|
;
|
|
else if (_Right(_Z) == _Nil)
|
|
_Lmost() = _Parent(_Z);
|
|
else
|
|
_Lmost() = _Min(_X);
|
|
if (_Rmost() != _Z)
|
|
;
|
|
else if (_Left(_Z) == _Nil)
|
|
_Rmost() = _Parent(_Z);
|
|
else
|
|
_Rmost() = _Max(_X); }
|
|
if (_Color(_Y) == _Black)
|
|
{while (_X != _Root() && _Color(_X) == _Black)
|
|
if (_X == _Left(_Parent(_X)))
|
|
{_Nodeptr _W = _Right(_Parent(_X));
|
|
if (_Color(_W) == _Red)
|
|
{_Color(_W) = _Black;
|
|
_Color(_Parent(_X)) = _Red;
|
|
_Lrotate(_Parent(_X));
|
|
_W = _Right(_Parent(_X)); }
|
|
if (_Color(_Left(_W)) == _Black
|
|
&& _Color(_Right(_W)) == _Black)
|
|
{_Color(_W) = _Red;
|
|
_X = _Parent(_X); }
|
|
else
|
|
{if (_Color(_Right(_W)) == _Black)
|
|
{_Color(_Left(_W)) = _Black;
|
|
_Color(_W) = _Red;
|
|
_Rrotate(_W);
|
|
_W = _Right(_Parent(_X)); }
|
|
_Color(_W) = _Color(_Parent(_X));
|
|
_Color(_Parent(_X)) = _Black;
|
|
_Color(_Right(_W)) = _Black;
|
|
_Lrotate(_Parent(_X));
|
|
break; }}
|
|
else
|
|
{_Nodeptr _W = _Left(_Parent(_X));
|
|
if (_Color(_W) == _Red)
|
|
{_Color(_W) = _Black;
|
|
_Color(_Parent(_X)) = _Red;
|
|
_Rrotate(_Parent(_X));
|
|
_W = _Left(_Parent(_X)); }
|
|
if (_Color(_Right(_W)) == _Black
|
|
&& _Color(_Left(_W)) == _Black)
|
|
{_Color(_W) = _Red;
|
|
_X = _Parent(_X); }
|
|
else
|
|
{if (_Color(_Left(_W)) == _Black)
|
|
{_Color(_Right(_W)) = _Black;
|
|
_Color(_W) = _Red;
|
|
_Lrotate(_W);
|
|
_W = _Left(_Parent(_X)); }
|
|
_Color(_W) = _Color(_Parent(_X));
|
|
_Color(_Parent(_X)) = _Black;
|
|
_Color(_Left(_W)) = _Black;
|
|
_Rrotate(_Parent(_X));
|
|
break; }}
|
|
_Color(_X) = _Black; }
|
|
}
|
|
_Destval(&_Value(_Y));
|
|
_Freenode(_Y);
|
|
--_Size;
|
|
return (_P); }
|
|
iterator erase(iterator _F, iterator _L)
|
|
{if (size() == 0 || _F != begin() || _L != end())
|
|
{while (_F != _L)
|
|
erase(_F++);
|
|
return (_F); }
|
|
else
|
|
{_Erase(_Root());
|
|
_Root() = _Nil, _Size = 0;
|
|
_Lmost() = _Head, _Rmost() = _Head;
|
|
return (begin()); }}
|
|
size_type erase(const _K& _X)
|
|
{_Pairii _P = equal_range(_X);
|
|
size_type _N = 0;
|
|
_Distance(_P.first, _P.second, _N);
|
|
erase(_P.first, _P.second);
|
|
return (_N); }
|
|
void erase(const _K *_F, const _K *_L)
|
|
{for (; _F != _L; ++_F)
|
|
erase(*_F); }
|
|
void clear()
|
|
{erase(begin(), end()); }
|
|
iterator find(const _K& _Kv)
|
|
{iterator _P = lower_bound(_Kv);
|
|
return (_P == end()
|
|
|| key_compare(_Kv, _Key(_P._Mynode()))
|
|
? end() : _P); }
|
|
const_iterator find(const _K& _Kv) const
|
|
{const_iterator _P = lower_bound(_Kv);
|
|
return (_P == end()
|
|
|| key_compare(_Kv, _Key(_P._Mynode()))
|
|
? end() : _P); }
|
|
size_type count(const _K& _Kv) const
|
|
{_Paircc _Ans = equal_range(_Kv);
|
|
size_type _N = 0;
|
|
_Distance(_Ans.first, _Ans.second, _N);
|
|
return (_N); }
|
|
iterator lower_bound(const _K& _Kv)
|
|
{return (iterator(_Lbound(_Kv))); }
|
|
const_iterator lower_bound(const _K& _Kv) const
|
|
{return (const_iterator(_Lbound(_Kv))); }
|
|
iterator upper_bound(const _K& _Kv)
|
|
{return (iterator(_Ubound(_Kv))); }
|
|
const_iterator upper_bound(const _K& _Kv) const
|
|
{return (iterator(_Ubound(_Kv))); }
|
|
_Pairii equal_range(const _K& _Kv)
|
|
{return (_Pairii(lower_bound(_Kv), upper_bound(_Kv))); }
|
|
_Paircc equal_range(const _K& _Kv) const
|
|
{return (_Paircc(lower_bound(_Kv), upper_bound(_Kv))); }
|
|
void swap(_Myt& _X)
|
|
{std::swap(key_compare, _X.key_compare);
|
|
if (allocator == _X.allocator)
|
|
{std::swap(_Head, _X._Head);
|
|
std::swap(_Multi, _X._Multi);
|
|
std::swap(_Size, _X._Size); }
|
|
else
|
|
{_Myt _Ts = *this; *this = _X, _X = _Ts; }}
|
|
friend void swap(_Myt& _X, _Myt& _Y)
|
|
{_X.swap(_Y); }
|
|
protected:
|
|
static _Nodeptr _Nil;
|
|
static size_t _Nilrefs;
|
|
void _Copy(const _Myt& _X)
|
|
{_Root() = _Copy(_X._Root(), _Head);
|
|
_Size = _X.size();
|
|
if (_Root() != _Nil)
|
|
{_Lmost() = _Min(_Root());
|
|
_Rmost() = _Max(_Root()); }
|
|
else
|
|
_Lmost() = _Head, _Rmost() = _Head; }
|
|
_Nodeptr _Copy(_Nodeptr _X, _Nodeptr _P)
|
|
{_Nodeptr _R = _X;
|
|
for (; _X != _Nil; _X = _Left(_X))
|
|
{_Nodeptr _Y = _Buynode(_P, _Color(_X));
|
|
if (_R == _X)
|
|
_R = _Y;
|
|
_Right(_Y) = _Copy(_Right(_X), _Y);
|
|
_Consval(&_Value(_Y), _Value(_X));
|
|
_Left(_P) = _Y;
|
|
_P = _Y; }
|
|
_Left(_P) = _Nil;
|
|
return (_R); }
|
|
void _Erase(_Nodeptr _X)
|
|
{for (_Nodeptr _Y = _X; _Y != _Nil; _X = _Y)
|
|
{_Erase(_Right(_Y));
|
|
_Y = _Left(_Y);
|
|
_Destval(&_Value(_X));
|
|
_Freenode(_X); }}
|
|
void _Init()
|
|
{_Nodeptr _Tmp = _Buynode(0, _Black);
|
|
{_Lockit _Lk;
|
|
if (_Nil == 0)
|
|
{_Nil = _Tmp;
|
|
_Tmp = 0;
|
|
_Left(_Nil) = 0, _Right(_Nil) = 0; }
|
|
++_Nilrefs; }
|
|
if (_Tmp != 0)
|
|
_Freenode(_Tmp);
|
|
_Head = _Buynode(_Nil, _Red), _Size = 0;
|
|
_Lmost() = _Head, _Rmost() = _Head; }
|
|
iterator _Insert(_Nodeptr _X, _Nodeptr _Y, const _Ty& _V)
|
|
{_Nodeptr _Z = _Buynode(_Y, _Red);
|
|
_Left(_Z) = _Nil, _Right(_Z) = _Nil;
|
|
_Consval(&_Value(_Z), _V);
|
|
++_Size;
|
|
if (_Y == _Head || _X != _Nil
|
|
|| key_compare(_Kfn()(_V), _Key(_Y)))
|
|
{_Left(_Y) = _Z;
|
|
if (_Y == _Head)
|
|
{_Root() = _Z;
|
|
_Rmost() = _Z; }
|
|
else if (_Y == _Lmost())
|
|
_Lmost() = _Z; }
|
|
else
|
|
{_Right(_Y) = _Z;
|
|
if (_Y == _Rmost())
|
|
_Rmost() = _Z; }
|
|
for (_X = _Z; _X != _Root()
|
|
&& _Color(_Parent(_X)) == _Red; )
|
|
if (_Parent(_X) == _Left(_Parent(_Parent(_X))))
|
|
{_Y = _Right(_Parent(_Parent(_X)));
|
|
if (_Color(_Y) == _Red)
|
|
{_Color(_Parent(_X)) = _Black;
|
|
_Color(_Y) = _Black;
|
|
_Color(_Parent(_Parent(_X))) = _Red;
|
|
_X = _Parent(_Parent(_X)); }
|
|
else
|
|
{if (_X == _Right(_Parent(_X)))
|
|
{_X = _Parent(_X);
|
|
_Lrotate(_X); }
|
|
_Color(_Parent(_X)) = _Black;
|
|
_Color(_Parent(_Parent(_X))) = _Red;
|
|
_Rrotate(_Parent(_Parent(_X))); }}
|
|
else
|
|
{_Y = _Left(_Parent(_Parent(_X)));
|
|
if (_Color(_Y) == _Red)
|
|
{_Color(_Parent(_X)) = _Black;
|
|
_Color(_Y) = _Black;
|
|
_Color(_Parent(_Parent(_X))) = _Red;
|
|
_X = _Parent(_Parent(_X)); }
|
|
else
|
|
{if (_X == _Left(_Parent(_X)))
|
|
{_X = _Parent(_X);
|
|
_Rrotate(_X); }
|
|
_Color(_Parent(_X)) = _Black;
|
|
_Color(_Parent(_Parent(_X))) = _Red;
|
|
_Lrotate(_Parent(_Parent(_X))); }}
|
|
_Color(_Root()) = _Black;
|
|
return (iterator(_Z)); }
|
|
_Nodeptr _Lbound(const _K& _Kv) const
|
|
{_Nodeptr _X = _Root();
|
|
_Nodeptr _Y = _Head;
|
|
while (_X != _Nil)
|
|
if (key_compare(_Key(_X), _Kv))
|
|
_X = _Right(_X);
|
|
else
|
|
_Y = _X, _X = _Left(_X);
|
|
return (_Y); }
|
|
_Nodeptr& _Lmost()
|
|
{return (_Left(_Head)); }
|
|
_Nodeptr& _Lmost() const
|
|
{return (_Left(_Head)); }
|
|
void _Lrotate(_Nodeptr _X)
|
|
{_Nodeptr _Y = _Right(_X);
|
|
_Right(_X) = _Left(_Y);
|
|
if (_Left(_Y) != _Nil)
|
|
_Parent(_Left(_Y)) = _X;
|
|
_Parent(_Y) = _Parent(_X);
|
|
if (_X == _Root())
|
|
_Root() = _Y;
|
|
else if (_X == _Left(_Parent(_X)))
|
|
_Left(_Parent(_X)) = _Y;
|
|
else
|
|
_Right(_Parent(_X)) = _Y;
|
|
_Left(_Y) = _X;
|
|
_Parent(_X) = _Y; }
|
|
static _Nodeptr _Max(_Nodeptr _P)
|
|
{while (_Right(_P) != _Nil)
|
|
_P = _Right(_P);
|
|
return (_P); }
|
|
static _Nodeptr _Min(_Nodeptr _P)
|
|
{while (_Left(_P) != _Nil)
|
|
_P = _Left(_P);
|
|
return (_P); }
|
|
_Nodeptr& _Rmost()
|
|
{return (_Right(_Head)); }
|
|
_Nodeptr& _Rmost() const
|
|
{return (_Right(_Head)); }
|
|
_Nodeptr& _Root()
|
|
{return (_Parent(_Head)); }
|
|
_Nodeptr& _Root() const
|
|
{return (_Parent(_Head)); }
|
|
void _Rrotate(_Nodeptr _X)
|
|
{_Nodeptr _Y = _Left(_X);
|
|
_Left(_X) = _Right(_Y);
|
|
if (_Right(_Y) != _Nil)
|
|
_Parent(_Right(_Y)) = _X;
|
|
_Parent(_Y) = _Parent(_X);
|
|
if (_X == _Root())
|
|
_Root() = _Y;
|
|
else if (_X == _Right(_Parent(_X)))
|
|
_Right(_Parent(_X)) = _Y;
|
|
else
|
|
_Left(_Parent(_X)) = _Y;
|
|
_Right(_Y) = _X;
|
|
_Parent(_X) = _Y; }
|
|
_Nodeptr _Ubound(const _K& _Kv) const
|
|
{_Nodeptr _X = _Root();
|
|
_Nodeptr _Y = _Head;
|
|
while (_X != _Nil)
|
|
if (key_compare(_Kv, _Key(_X)))
|
|
_Y = _X, _X = _Left(_X);
|
|
else
|
|
_X = _Right(_X);
|
|
return (_Y); }
|
|
_Nodeptr _Buynode(_Nodeptr _Parg, _Redbl _Carg)
|
|
{_Nodeptr _S = (_Nodeptr)allocator._Charalloc(
|
|
1 * sizeof (_Node));
|
|
_Parent(_S) = _Parg;
|
|
_Color(_S) = _Carg;
|
|
return (_S); }
|
|
void _Consval(_Tptr _P, const _Ty& _V)
|
|
{_Construct(&*_P, _V); }
|
|
void _Destval(_Tptr _P)
|
|
{_Destroy(&*_P); }
|
|
void _Freenode(_Nodeptr _S)
|
|
{allocator.deallocate(_S, 1); }
|
|
_A allocator;
|
|
_Pr key_compare;
|
|
_Nodeptr _Head;
|
|
bool _Multi;
|
|
size_type _Size;
|
|
};
|
|
template<class _K, class _Ty, class _Kfn, class _Pr, class _A>
|
|
typename _Tree<_K, _Ty, _Kfn, _Pr, _A>::_Nodeptr
|
|
_Tree<_K, _Ty, _Kfn, _Pr, _A>::_Nil = 0;
|
|
template<class _K, class _Ty, class _Kfn, class _Pr, class _A>
|
|
size_t _Tree<_K, _Ty, _Kfn, _Pr, _A>::_Nilrefs = 0;
|
|
// tree TEMPLATE OPERATORS
|
|
template<class _K, class _Ty, class _Kfn,
|
|
class _Pr, class _A> inline
|
|
bool operator==(const _Tree<_K, _Ty, _Kfn, _Pr, _A>& _X,
|
|
const _Tree<_K, _Ty, _Kfn, _Pr, _A>& _Y)
|
|
{return (_X.size() == _Y.size()
|
|
&& equal(_X.begin(), _X.end(), _Y.begin())); }
|
|
template<class _K, class _Ty, class _Kfn,
|
|
class _Pr, class _A> inline
|
|
bool operator!=(const _Tree<_K, _Ty, _Kfn, _Pr, _A>& _X,
|
|
const _Tree<_K, _Ty, _Kfn, _Pr, _A>& _Y)
|
|
{return (!(_X == _Y)); }
|
|
template<class _K, class _Ty, class _Kfn,
|
|
class _Pr, class _A> inline
|
|
bool operator<(const _Tree<_K, _Ty, _Kfn, _Pr, _A>& _X,
|
|
const _Tree<_K, _Ty, _Kfn, _Pr, _A>& _Y)
|
|
{return (lexicographical_compare(_X.begin(), _X.end(),
|
|
_Y.begin(), _Y.end())); }
|
|
template<class _K, class _Ty, class _Kfn,
|
|
class _Pr, class _A> inline
|
|
bool operator>(const _Tree<_K, _Ty, _Kfn, _Pr, _A>& _X,
|
|
const _Tree<_K, _Ty, _Kfn, _Pr, _A>& _Y)
|
|
{return (_Y < _X); }
|
|
template<class _K, class _Ty, class _Kfn,
|
|
class _Pr, class _A> inline
|
|
bool operator<=(const _Tree<_K, _Ty, _Kfn, _Pr, _A>& _X,
|
|
const _Tree<_K, _Ty, _Kfn, _Pr, _A>& _Y)
|
|
{return (!(_Y < _X)); }
|
|
template<class _K, class _Ty, class _Kfn,
|
|
class _Pr, class _A> inline
|
|
bool operator>=(const _Tree<_K, _Ty, _Kfn, _Pr, _A>& _X,
|
|
const _Tree<_K, _Ty, _Kfn, _Pr, _A>& _Y)
|
|
{return (!(_X < _Y)); }
|
|
_STD_END
|
|
#ifdef _MSC_VER
|
|
#pragma pack(pop)
|
|
#endif /* _MSC_VER */
|
|
|
|
#endif /* _TREE_ */
|
|
|
|
/*
|
|
* Copyright (c) 1995 by P.J. Plauger. ALL RIGHTS RESERVED.
|
|
* Consult your license regarding permissions and restrictions.
|
|
*/
|
|
|
|
/*
|
|
* This file is derived from software bearing the following
|
|
* restrictions:
|
|
*
|
|
* 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.
|
|
*/
|