|
|
// 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. */
|