#pragma once #ifndef _STLTREE_H_ #define _STLTREE_H_ //#include //#include //#include //#include #include #include #include #include #ifdef _MSC_VER #pragma pack(push,8) #endif /* _MSC_VER */ _STD_BEGIN // TEMPLATE CLASS _Tree template 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 _A::size_type size_type; typedef _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() { //_Lockit _Lk; 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() { //_Lockit _Lk; 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 reverse_iterator; typedef reverse_bidirectional_iterator const_reverse_iterator; typedef pair _Pairib; typedef pair _Pairii; typedef pair _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; { //_Lockit _Lk; if (--_Nilrefs == 0) { _Freenode(_Nil); _Nil = 0; } } } _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; { //_Lockit Lk; 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()) { //_Lockit Lk; 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()))) { //_Lockit _Lk; 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; //_Lockit _Lk; if (_Left(_Y) == _Nil) _X = _Right(_Y); else if (_Right(_Y) == _Nil) _X = _Left(_Y); else _Y = _Min(_Right(_Y)), _X = _Right(_Y); 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 { //_Lockit Lk; _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) { //_Lockit _Lk; _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) { //_Lockit _Lk; _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) { //_Lockit _Lk; for (_Nodeptr _Y = _X; _Y != _Nil; _X = _Y) { _Erase(_Right(_Y)); _Y = _Left(_Y); _Destval(&_Value(_X)); _Freenode(_X); } } void _Init() { //_Lockit _Lk; if (_Nil == 0) { _Nil = _Buynode(0, _Black); _Left(_Nil) = 0, _Right(_Nil) = 0; } ++_Nilrefs; _Head = _Buynode(_Nil, _Red), _Size = 0; _Lmost() = _Head, _Rmost() = _Head; } iterator _Insert(_Nodeptr _X, _Nodeptr _Y, const _Ty& _V) { //_Lockit _Lk; _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 { //_Lockit _Lk; _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) { //_Lockit _Lk; _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) { //_Lockit _Lk; while (_Right(_P) != _Nil) _P = _Right(_P); return (_P); } static _Nodeptr _Min(_Nodeptr _P) { //_Lockit _Lk; 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) { //_Lockit _Lk; _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 { //_Lockit _Lk; _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 _Tree<_K, _Ty, _Kfn, _Pr, _A>::_Nodeptr _Tree<_K, _Ty, _Kfn, _Pr, _A>::_Nil = 0; template size_t _Tree<_K, _Ty, _Kfn, _Pr, _A>::_Nilrefs = 0; // tree TEMPLATE OPERATORS template 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 inline bool operator!=(const _Tree<_K, _Ty, _Kfn, _Pr, _A>& _X, const _Tree<_K, _Ty, _Kfn, _Pr, _A>& _Y) { return (!(_X == _Y)); } template 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 inline bool operator>(const _Tree<_K, _Ty, _Kfn, _Pr, _A>& _X, const _Tree<_K, _Ty, _Kfn, _Pr, _A>& _Y) { return (_Y < _X); } template inline bool operator<=(const _Tree<_K, _Ty, _Kfn, _Pr, _A>& _X, const _Tree<_K, _Ty, _Kfn, _Pr, _A>& _Y) { return (!(_Y < _X)); } template 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 /* _STLTREE_H_ */ /* * 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. */