|
/** |
|
* @class rbtree |
|
* |
|
* @details Red Black Tree Implementation |
|
* |
|
* @author Jaeyong Sung |
|
* |
|
* @date April 29, 2018 |
|
*/ |
|
|
|
#ifndef COLLECTIONS_RBTREE_H |
|
#define COLLECTIONS_RBTREE_H |
|
|
|
#include <vector> |
|
#include <functional> |
|
#include <initializer_list> |
|
#include <iterator> |
|
#include <utility> |
|
|
|
// node structure of rbtree |
|
template<class _Tp> |
|
struct __rbtree_node_ { |
|
typedef _Tp value_type; |
|
typedef __rbtree_node_* node_pointer; |
|
|
|
value_type __value; |
|
node_pointer __parent, __left, __right; |
|
bool __is_black; |
|
unsigned long __count; |
|
}; |
|
|
|
// const iterator class of rbtree |
|
template<class _Tp> |
|
class __rbtree_const_iterator_ { |
|
public: |
|
typedef _Tp value_type; |
|
typedef value_type* pointer; |
|
typedef value_type& reference; |
|
typedef __rbtree_node_<_Tp>* node_pointer; |
|
typedef std::bidirectional_iterator_tag iterator_category; |
|
typedef ptrdiff_t difference_type; |
|
|
|
template<class, class> friend class rbtree; |
|
template<class, class> friend class multi_rbtree; |
|
|
|
|
|
private: |
|
node_pointer __ptr; |
|
|
|
inline bool __is_nil(const node_pointer &__p) { return __p->__right == __p; } |
|
|
|
// returns the pointer |
|
// not for use in the outer code |
|
// only use for rbtree class |
|
inline node_pointer __get_np() { return __ptr; } |
|
|
|
// returns the pointer |
|
// not for use in the outer code |
|
// only use for rbtree class |
|
inline node_pointer __get_np() const { return __ptr; } |
|
|
|
public: |
|
explicit __rbtree_const_iterator_(node_pointer __p) : __ptr(__p) {} |
|
|
|
// returns the value of the pointer |
|
reference operator*() const; |
|
|
|
// returns the pointer of the value of the pointer |
|
const pointer operator->() const; |
|
|
|
// postfix operator ++ |
|
// returns the next const iterator of the rbtree when sorted |
|
// or returns the const iterator pointing __nil if the iterator is pointing last node |
|
// or returns the const iterator pointing the first node if the iterator is pointing __nil |
|
__rbtree_const_iterator_ &operator++(); |
|
|
|
// prefix operator ++ |
|
// returns this const iterator but it would be pointing to next node when sorted |
|
// or pointing __nil if the iterator is pointing last node |
|
// or pointing the first node if the iterator is pointing __nil |
|
const __rbtree_const_iterator_ operator++(int); |
|
|
|
// postfix operator -- |
|
// returns the previous const iterator of the rbtree when sorted |
|
// or returns the const iterator pointing __nil if the iterator is pointing first node |
|
// or returns the const iterator pointing the last node if the iterator is pointing __nil |
|
__rbtree_const_iterator_ &operator--(); |
|
|
|
// prefix operator -- |
|
// returns this const iterator but it would be pointing to previous node when sorted |
|
// or pointing __nil if the iterator is pointing first node |
|
// or pointing the last node if the iterator is pointing __nil |
|
const __rbtree_const_iterator_ operator--(int); |
|
|
|
// returns if two iterators are pointing the same node |
|
bool operator==(const __rbtree_const_iterator_ &__x); |
|
|
|
// returns if two iterators are not pointing the same node |
|
bool operator!=(const __rbtree_const_iterator_ &__x); |
|
}; |
|
|
|
template<class _Tp> |
|
typename __rbtree_const_iterator_<_Tp>::reference |
|
__rbtree_const_iterator_<_Tp>::operator*() const { return __ptr->__value; } |
|
|
|
template<class _Tp> |
|
typename __rbtree_const_iterator_<_Tp>::pointer const |
|
__rbtree_const_iterator_<_Tp>::operator->() const { return &__ptr->__value; } |
|
|
|
template<class _Tp> |
|
__rbtree_const_iterator_<_Tp>& |
|
__rbtree_const_iterator_<_Tp>::operator++() { |
|
if (__is_nil(__ptr)) { |
|
__ptr = __ptr->__parent; |
|
while (!__is_nil(__ptr->__left)) |
|
__ptr = __ptr->__left; |
|
} else if (!__is_nil(__ptr->__right)) { |
|
__ptr = __ptr->__right; |
|
while (!__is_nil(__ptr->__left)) |
|
__ptr = __ptr->__left; |
|
} else if (!__is_nil(__ptr)) { |
|
while (!__is_nil(__ptr) && __ptr->__parent->__left != __ptr) |
|
__ptr = __ptr->__parent; |
|
if (!__is_nil(__ptr)) __ptr = __ptr->__parent; |
|
} |
|
return *this; |
|
} |
|
|
|
template<class _Tp> |
|
__rbtree_const_iterator_<_Tp> const |
|
__rbtree_const_iterator_<_Tp>::operator++(int) { |
|
__rbtree_const_iterator_ __t(*this); |
|
++(*this); |
|
return __t; |
|
} |
|
|
|
template<class _Tp> |
|
__rbtree_const_iterator_<_Tp>& |
|
__rbtree_const_iterator_<_Tp>::operator--() { |
|
if (__is_nil(__ptr)) { |
|
__ptr = __ptr->__parent; |
|
while (!__is_nil(__ptr->__right)) |
|
__ptr = __ptr->__right; |
|
} else if (!__is_nil(__ptr->__left)) { |
|
__ptr = __ptr->__left; |
|
while (!__is_nil(__ptr->__right)) |
|
__ptr = __ptr->__right; |
|
} else if (!__is_nil(__ptr)) { |
|
while (!__is_nil(__ptr) && __ptr->__parent->__right != __ptr) |
|
__ptr = __ptr->__parent; |
|
if (!__is_nil(__ptr)) __ptr = __ptr->__parent; |
|
} |
|
return *this; |
|
} |
|
|
|
template<class _Tp> |
|
__rbtree_const_iterator_<_Tp> const |
|
__rbtree_const_iterator_<_Tp>::operator--(int) { |
|
__rbtree_const_iterator_ __t(*this); |
|
--(*this); |
|
return __t; |
|
} |
|
|
|
template<class _Tp> |
|
bool __rbtree_const_iterator_<_Tp>::operator==(const __rbtree_const_iterator_ &__x) { return this->__ptr == __x.__ptr; } |
|
|
|
template<class _Tp> |
|
bool __rbtree_const_iterator_<_Tp>::operator!=(const __rbtree_const_iterator_ &__x) { return this->__ptr != __x.__ptr; } |
|
|
|
// the red-black rbtree class |
|
template<class _Tp, class _Comp = std::less<_Tp>> |
|
class rbtree { |
|
public: |
|
typedef _Tp value_type; |
|
typedef _Comp comp_type; |
|
|
|
private: |
|
typedef __rbtree_node_<value_type> __node; |
|
typedef __node* __node_pointer; |
|
|
|
public: |
|
typedef __rbtree_const_iterator_<value_type> iterator; |
|
typedef __rbtree_const_iterator_<value_type> const_iterator; |
|
typedef std::reverse_iterator<iterator> reverse_iterator; |
|
typedef std::reverse_iterator<const_iterator> reverse_const_iterator; |
|
|
|
private: |
|
// the pointer to __root and __nil |
|
// __nil's parent would be always __root |
|
__node_pointer __root, __nil; |
|
|
|
unsigned long __size; |
|
|
|
// init method - is called by constructors in the beginning for initialization |
|
inline void __init(); |
|
|
|
// finds the value __x |
|
// returns the pointer of node of __x if rbtree has the value |
|
// or returns the pointer to the leaf node that was last node when searching |
|
template<class _Compare> |
|
inline __node_pointer __find(const value_type &__x, _Compare compare); |
|
|
|
// finds the value __x |
|
// returns the pointer of node of __x if rbtree has the value |
|
// or returns the pointer to the leaf node that was last node when searching |
|
template<class _Compare> |
|
inline __node_pointer __find(value_type &&__x, _Compare compare); |
|
|
|
// finds the min node from node pointer |
|
// returns itself when it is leaf node |
|
// precondition : __p is not __nil |
|
inline __node_pointer __find_min(__node_pointer __p); |
|
|
|
// finds the min node from node pointer |
|
// returns itself when it is leaf node |
|
// precondition : __p is not __nil |
|
inline __node_pointer __find_min(__node_pointer __p) const; |
|
|
|
// finds the __xth element when the values are sorted (0 based) |
|
// returns pointer of __xth node if __x is in range |
|
// or returns pointer to __nil |
|
inline __node_pointer __nth_element(unsigned long __x); |
|
|
|
// finds the index of node pointer __p when the values are sorted (0 based) |
|
// returns the index of node pointer __p node |
|
inline unsigned long __index_of(__node_pointer __p); |
|
|
|
// simple lower_bound function |
|
// returns the pointer to the first not small value of __x |
|
template<class _Compare> |
|
inline __node_pointer __lower_bound(const value_type &__x, _Compare compare); |
|
|
|
// simple lower_bound function |
|
// returns the pointer to the first not small value of __x |
|
template<class _Compare> |
|
inline __node_pointer __lower_bound(value_type &&__x, _Compare compare); |
|
|
|
// simple upper_bound function |
|
// returns the pointer to the first big value of __x |
|
template<class _Compare> |
|
inline __node_pointer __upper_bound(const value_type &__x, _Compare compare); |
|
|
|
// simple upper_bound function |
|
// returns the pointer to the first big value of __x |
|
template<class _Compare> |
|
inline __node_pointer __upper_bound(value_type &&__x, _Compare compare); |
|
|
|
// returns the sibling node of the pointer of __p if __p is not root |
|
// or returns __nil; |
|
// preconditions : __p is not __nil |
|
inline __node_pointer __sibling_node(__node_pointer __p); |
|
|
|
// rotates the rbtree left from __b's parent |
|
// when the function is finished, __b would be parent of __b's parent |
|
// changes the root when __b's parent was root |
|
// preconditions : __b is not __root. |
|
void __left_rotate(__node_pointer __b); |
|
|
|
// rotates the rbtree right from __b's parent |
|
// when the function is finished, __b would be parent of __b's parent |
|
// changes the root when __b's parent was root |
|
// preconditions : __b is not __root |
|
void __right_rotate(__node_pointer __b); |
|
|
|
// the balance function after insert |
|
// __p is the pointer to node that was inserted |
|
// preconditions : __p is red and __p's parent is red |
|
void __insert_balance(__node_pointer __p); |
|
|
|
// inserts the value __x |
|
// do nothing when __x is already in the rbtree |
|
// allocates a new node that the value is __x |
|
template<class _Compare> |
|
__node_pointer __insert(const value_type &__x, _Compare compare); |
|
|
|
// inserts the value __x |
|
// do nothing when __x is already in the rbtree |
|
// allocates a new node that the value is __x |
|
template<class _Compare> |
|
__node_pointer __insert(value_type &&__x, _Compare compare); |
|
|
|
// the balance function after erase |
|
// __x is the pointer to node of a child that was erased |
|
// preconditions : __x's black nodes count is 1 smaller than sibling of __x's |
|
void __erase_balance(__node_pointer __x); |
|
|
|
// erases the pointer __x |
|
// deallocates the one-child node and changes the value |
|
// do nothing when __x is __nil |
|
void __erase(__node_pointer __x); |
|
|
|
public: |
|
|
|
// simple constructor |
|
rbtree(); |
|
|
|
// constructor that inserts all the value in vector __v |
|
rbtree(const std::vector<value_type> &__v); |
|
|
|
// constructor that inserts all the value in initialize_list __il |
|
rbtree(const std::initializer_list<value_type> &__il); |
|
|
|
// constructor that inserts all the value from input iterator __first to intput iterator __last |
|
template<class _InputIterator> |
|
rbtree(_InputIterator __first, _InputIterator __last); |
|
|
|
rbtree(const rbtree &other); |
|
|
|
rbtree &operator=(const rbtree &other); |
|
|
|
// deallocates all the node |
|
void clear(); |
|
|
|
// inserts the value __x |
|
iterator insert(const value_type &__x); |
|
|
|
// inserts the value __x |
|
iterator insert(value_type &&__x); |
|
|
|
// inserts the value all from vector __v |
|
void insert(const std::vector<value_type> &__v); |
|
|
|
// inserts the value all from initializer list __il |
|
void insert(const std::initializer_list<value_type> &__il); |
|
|
|
// inserts the value all from input iterator __first to input iterator __last |
|
template<class _InputIterator> |
|
void insert(_InputIterator __first, _InputIterator __last); |
|
|
|
// erases the node that iterator is pointing at |
|
void erase(iterator __it); |
|
|
|
// erases the value if the rbtree has the value |
|
void erase(const value_type &__x); |
|
|
|
// erases the value if the rbtree has the value |
|
void erase(value_type &&__x); |
|
|
|
// returns the size of the rbtree |
|
unsigned long size(); |
|
|
|
// returns if rbtree is empty |
|
bool empty(); |
|
|
|
// returns if rbtree is empty |
|
bool empty() const; |
|
|
|
// returns if the rbtree has the value __x |
|
bool has(const value_type &__x); |
|
|
|
// returns if the rbtree has the value __x |
|
bool has(value_type &&__x); |
|
|
|
// returns the count of the value __x in the rbtree |
|
unsigned long count(const value_type &__x); |
|
|
|
// returns the count of the value __x in the rbtree |
|
unsigned long count(value_type &&__x); |
|
|
|
// returns the any iterator of value __x if the value is in the rbtree |
|
// or returns end iterator |
|
iterator find(const value_type &__x); |
|
|
|
// returns the any iterator of value __x if the value is in the rbtree |
|
// or returns end iterator |
|
iterator find(value_type &&__x); |
|
|
|
// returns the pair of find function and index_of function (0 based) |
|
// index_of gets iterator, but this function gets the value __x |
|
std::pair<iterator, unsigned long> find_with(const value_type &__x); |
|
|
|
// returns the pair of find function and index_of function (0 based) |
|
// index_of gets iterator, but this function gets the value __x |
|
std::pair<iterator, unsigned long> find_with(value_type &&__x); |
|
|
|
// returns the iterator pointing the nth element of the values when sorted if __x is in range (0 based) |
|
// of returns the end iterator |
|
iterator nth_element(const unsigned long &__x); |
|
|
|
// returns the iterator pointing the nth element of the values when sorted if __x is in range (0 based) |
|
// of returns the end iterator |
|
iterator nth_element(unsigned long &&__x); |
|
|
|
// returns the index of iterator __x in the rbtree when sorted (0 based) |
|
// or returns the size of the rbtree when the iterator is pointing __nil |
|
unsigned long index_of(const iterator &__x); |
|
|
|
// returns the iterator pointing to the first not small value of __x |
|
iterator lower_bound(const value_type &__x); |
|
|
|
// returns the iterator pointing to the first not small value of __x |
|
iterator lower_bound(value_type &&__x); |
|
|
|
// returns the iterator pointing to the first bigger value of __x |
|
iterator upper_bound(const value_type &__x); |
|
|
|
// returns the iterator pointing to the first bigger value of __x |
|
iterator upper_bound(value_type &&__x); |
|
|
|
// returns the pair of lower_bound and upper_bound |
|
std::pair<iterator, iterator> equal_range(const value_type &__x); |
|
|
|
// returns the pair of lower_bound and upper_bound |
|
std::pair<iterator, iterator> equal_range(value_type &&__x); |
|
|
|
void merge(const rbtree &t); |
|
|
|
// returns the begin iterator pointing min value |
|
iterator begin(); |
|
|
|
// returns the const begin iterator pointing min value |
|
const_iterator begin() const; |
|
|
|
// returns the reverse iterator of end |
|
// the value of the rbegin would be max value of the rbtree |
|
reverse_iterator rbegin(); |
|
|
|
// returns the reverse iterator of end |
|
// the value of the rbegin would be max value of the rbtree |
|
reverse_const_iterator rbegin() const; |
|
|
|
// returns the end iterator pointing __nil |
|
iterator end(); |
|
|
|
// returns the end iterator pointing __nil |
|
const_iterator end() const; |
|
|
|
// returns the reverse iterator of begin |
|
// the value of the rend would be __nil |
|
reverse_iterator rend(); |
|
|
|
// returns the reverse iterator of begin |
|
// the value of the rend would be __nil |
|
reverse_const_iterator rend() const; |
|
|
|
// returns the begin const iterator pointing min value |
|
const_iterator cbegin() const; |
|
|
|
// returns the reverse const iterator of end |
|
// the value of the crbegin would be max value of the rbtree |
|
reverse_const_iterator crbegin() const; |
|
|
|
// returns the end const iterator pointing __nil |
|
const_iterator cend() const; |
|
|
|
// returns the reverse const iterator of begin |
|
// the value of the crend would be __nil |
|
reverse_const_iterator crend() const; |
|
|
|
// destructor of the rbtree class |
|
// deallocates all the nodes |
|
~rbtree(); |
|
}; |
|
|
|
template<class _Tp, class _Comp> |
|
void rbtree<_Tp, _Comp>::__init() { |
|
__root = new __node; |
|
__nil = new __node; |
|
__root->__parent = __nil; |
|
__root->__left = __nil; |
|
__root->__right = __nil; |
|
__root->__is_black = true; |
|
__root->__count = 0; |
|
__nil->__parent = __root; |
|
__nil->__left = __nil; |
|
__nil->__right = __nil; |
|
__nil->__is_black = true; |
|
__nil->__count = 0; |
|
__size = 0; |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
template<class _Compare> |
|
typename rbtree<_Tp, _Comp>::__node_pointer |
|
rbtree<_Tp, _Comp>::__find(const value_type &__x, _Compare compare) { |
|
__node_pointer __p = __root, __q = __p; |
|
while (__p != __nil) { |
|
__q = __p; |
|
if (__x == __p->__value) return __p; |
|
if (compare(__x, __p->__value)) __p = __p->__left; |
|
else __p = __p->__right; |
|
} |
|
return __q; |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
template<class _Compare> |
|
typename rbtree<_Tp, _Comp>::__node_pointer |
|
rbtree<_Tp, _Comp>::__find(value_type &&__x, _Compare compare) { |
|
__node_pointer __p = __root, __q = __p; |
|
while (__p != __nil) { |
|
__q = __p; |
|
if (std::move(__x) == __p->__value) return __p; |
|
if (compare(std::move(__x), __p->__value)) __p = __p->__left; |
|
else __p = __p->__right; |
|
} |
|
return __q; |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
typename rbtree<_Tp, _Comp>::__node_pointer |
|
rbtree<_Tp, _Comp>::__find_min(rbtree::__node_pointer __p) { |
|
while (__p->__left != __nil) |
|
__p = __p->__left; |
|
return __p; |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
typename rbtree<_Tp, _Comp>::__node_pointer |
|
rbtree<_Tp, _Comp>::__find_min(rbtree::__node_pointer __p) const { |
|
while (__p->__left != __nil) |
|
__p = __p->__left; |
|
return __p; |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
typename rbtree<_Tp, _Comp>::__node_pointer |
|
rbtree<_Tp, _Comp>::__nth_element(unsigned long __x) { |
|
__node_pointer __p = __root; |
|
while (__p != __nil) { |
|
if (__x == __p->__left->__count) return __p; |
|
if (__x < __p->__left->__count) __p = __p->__left; |
|
else { |
|
__x -= __p->__left->__count + 1; |
|
__p = __p->__right; |
|
} |
|
} |
|
return __nil; |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
unsigned long rbtree<_Tp, _Comp>::__index_of(rbtree::__node_pointer __p) { |
|
unsigned long ans = __p->__left->__count; |
|
while (__p != __root) { |
|
if (__p == __p->__parent->__right) ans += __p->__parent->__left->__count + 1; |
|
__p = __p->__parent; |
|
} |
|
return ans; |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
template<class _Compare> |
|
typename rbtree<_Tp, _Comp>::__node_pointer |
|
rbtree<_Tp, _Comp>::__lower_bound(const value_type &__x, _Compare compare) { |
|
__node_pointer __p = __root, __ans = __nil; |
|
while (__p->__left != __nil && __p->__right != __nil) { |
|
if (__x == __p->__value) { |
|
while (__p->__left->__value == __x) __p = __p->__left; |
|
return __p; |
|
} |
|
if (compare(__x, __p->__value)) |
|
__p = __p->__left; |
|
else { |
|
__p = __p->__right; |
|
if (__ans == __nil || compare(__p->__value, __ans->__value)) __ans = __p; |
|
} |
|
} |
|
return __ans; |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
template<class _Compare> |
|
typename rbtree<_Tp, _Comp>::__node_pointer |
|
rbtree<_Tp, _Comp>::__lower_bound(value_type &&__x, _Compare compare) { |
|
__node_pointer __p = __root, __ans = __nil; |
|
while (__p->__left != __nil && __p->__right != __nil) { |
|
if (std::move(__x) == __p->__value) { |
|
while (__p->__left->__value == std::move(__x)) __p = __p->__left; |
|
return __p; |
|
} |
|
if (compare(std::move(__x), __p->__value)) |
|
__p = __p->__left; |
|
else { |
|
__p = __p->__right; |
|
if (__ans == __nil || compare(__p->__value, __ans->__value)) __ans = __p; |
|
} |
|
} |
|
return __ans; |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
template<class _Compare> |
|
typename rbtree<_Tp, _Comp>::__node_pointer |
|
rbtree<_Tp, _Comp>::__upper_bound(const value_type &__x, _Compare compare) { |
|
__node_pointer __p = __root, __ans = __nil; |
|
while (__p->__left != __nil && __p->__right != __nil) { |
|
if (__x == __p->__value) { |
|
while (__p->__right->__value == __x) __p = __p->__right; |
|
return __p; |
|
} |
|
if (compare(__x, __p->__value)) |
|
__p = __p->__left; |
|
else { |
|
__p = __p->__right; |
|
if (__ans == __nil || compare(__p->__value, __ans->__value)) __ans = __p; |
|
} |
|
} |
|
return __ans; |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
template<class _Compare> |
|
typename rbtree<_Tp, _Comp>::__node_pointer |
|
rbtree<_Tp, _Comp>::__upper_bound(value_type &&__x, _Compare compare) { |
|
__node_pointer __p = __root, __ans = __nil; |
|
while (__p->__left != __nil && __p->__right != __nil) { |
|
if (std::move(__x) == __p->__value) { |
|
while (__p->__right->__value == std::move(__x)) __p = __p->__right; |
|
return __p; |
|
} |
|
if (compare(std::move(__x), __p->__value)) |
|
__p = __p->__left; |
|
else { |
|
__p = __p->__right; |
|
if (__ans == __nil || compare(__p->__value, __ans->__value)) __ans = __p; |
|
} |
|
} |
|
return __ans; |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
typename rbtree<_Tp, _Comp>::__node_pointer |
|
rbtree<_Tp, _Comp>::__sibling_node(rbtree::__node_pointer __p) { |
|
if (__p == __root) return __nil; |
|
if (__p == __p->__parent->__left) return __p->__parent->__right; |
|
return __p->__parent->__left; |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
void rbtree<_Tp, _Comp>::__left_rotate(rbtree::__node_pointer __b) { |
|
__node_pointer __a = __b->__parent, __p = __b->__left, __q = __a->__parent; |
|
if (__a == __root) |
|
__root = __b; |
|
else { |
|
if (__a == __q->__left) __q->__left = __b; |
|
else __q->__right = __b; |
|
} |
|
if (__b == __root) __b->__parent = __nil; |
|
else __b->__parent = __q; |
|
__b->__left = __a; |
|
__a->__parent = __b; |
|
__a->__right = __p; |
|
if (__p != __nil) __p->__parent = __a; |
|
__b->__count = __a->__count; |
|
__a->__count = __a->__left->__count + __a->__right->__count + 1; |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
void rbtree<_Tp, _Comp>::__right_rotate(rbtree::__node_pointer __b) { |
|
__node_pointer __a = __b->__parent, __p = __b->__right, __q = __a->__parent; |
|
if (__a == __root) |
|
__root = __b; |
|
else { |
|
if (__a == __q->__left) __q->__left = __b; |
|
else __q->__right = __b; |
|
} |
|
if (__b == __root) __b->__parent = __nil; |
|
else __b->__parent = __q; |
|
__b->__right = __a; |
|
__a->__parent = __b; |
|
__a->__left = __p; |
|
if (__p != __nil) __p->__parent = __a; |
|
__a->__count = __b->__count; |
|
__b->__count = __b->__left->__count + __b->__right->__count + 1; |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
void rbtree<_Tp, _Comp>::__insert_balance(rbtree::__node_pointer __p) { |
|
if (__p->__parent == __root) { |
|
__root->__is_black = true; |
|
return; |
|
} |
|
__node_pointer __s = __sibling_node(__p->__parent); |
|
__node_pointer __a = __p->__parent->__parent; |
|
if (!__s->__is_black) { |
|
__s->__is_black = true; |
|
__p->__parent->__is_black = true; |
|
if (__a != __root) { |
|
__a->__is_black = false; |
|
if (!__a->__parent->__is_black) |
|
__insert_balance(__a); |
|
} |
|
} else { |
|
if (__p->__parent == __a->__left) { |
|
if (__p == __p->__parent->__right) { |
|
__left_rotate(__p); |
|
__right_rotate(__p); |
|
__p->__is_black = true; |
|
} else { |
|
__right_rotate(__p->__parent); |
|
__p->__parent->__is_black = true; |
|
} |
|
__a->__is_black = false; |
|
} else { |
|
if (__p == __p->__parent->__left) { |
|
__right_rotate(__p); |
|
__left_rotate(__p); |
|
__p->__is_black = true; |
|
} else { |
|
__left_rotate(__p->__parent); |
|
__p->__parent->__is_black = true; |
|
} |
|
__a->__is_black = false; |
|
} |
|
} |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
template<class _Compare> |
|
typename rbtree<_Tp, _Comp>::__node_pointer |
|
rbtree<_Tp, _Comp>::__insert(const value_type &__x, _Compare compare) { |
|
__size++; |
|
if (__size == 1) { |
|
__root->__value = __x; |
|
__root->__count++; |
|
__nil->__parent = __root; |
|
return __root; |
|
} |
|
__node_pointer __p = __root, __q = __p; |
|
while (__p != __nil) { |
|
__q = __p; |
|
if (__p->__value == __x) return __p; |
|
if (compare(__x, __p->__value)) __p = __p->__left; |
|
else __p = __p->__right; |
|
} |
|
__p = __q; |
|
__node_pointer __n = new __node; |
|
__n->__parent = __p; |
|
if (compare(__x, __p->__value)) __p->__left = __n; |
|
else __p->__right = __n; |
|
__n->__is_black = false; |
|
__n->__left = __nil; |
|
__n->__right = __nil; |
|
__n->__value = __x; |
|
__n->__count = 0; |
|
for (__node_pointer __i = __n; __i != __nil; __i = __i->__parent) __i->__count++; |
|
if (!__p->__is_black) __insert_balance(__n); |
|
__nil->__parent = __root; |
|
return __n; |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
template<class _Compare> |
|
typename rbtree<_Tp, _Comp>::__node_pointer |
|
rbtree<_Tp, _Comp>::__insert(value_type &&__x, _Compare compare) { |
|
__size++; |
|
if (__size == 1) { |
|
__root->__value = std::move(__x); |
|
__root->__count++; |
|
__nil->__parent = __root; |
|
return __root; |
|
} |
|
__node_pointer __p = __root, __q = __p; |
|
while (__p != __nil) { |
|
__q = __p; |
|
if (__p->__value == std::move(__x)) return __p; |
|
if (compare(std::move(__x), __p->__value)) __p = __p->__left; |
|
else __p = __p->__right; |
|
} |
|
__p = __q; |
|
__node_pointer __n = new __node; |
|
__n->__parent = __p; |
|
if (compare(std::move(__x), __p->__value)) __p->__left = __n; |
|
else __p->__right = __n; |
|
__n->__is_black = false; |
|
__n->__left = __nil; |
|
__n->__right = __nil; |
|
__n->__value = std::move(__x); |
|
__n->__count = 0; |
|
for (__node_pointer __i = __n; __i != __nil; __i = __i->__parent) __i->__count++; |
|
if (!__p->__is_black) __insert_balance(__n); |
|
__nil->__parent = __root; |
|
return __n; |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
void rbtree<_Tp, _Comp>::__erase_balance(rbtree::__node_pointer __x) { |
|
if (__x == __root) { |
|
__x->__is_black = true; |
|
return; |
|
} |
|
__node_pointer __p = __x->__parent; |
|
if (__x == __p->__left) { |
|
__node_pointer __s = __p->__right, __l = __s->__left, __r = __s->__right; |
|
if (!__r->__is_black) { |
|
__left_rotate(__s); |
|
std::swap(__p->__is_black, __s->__is_black); |
|
__r->__is_black = true; |
|
} else if (!__l->__is_black) { |
|
__right_rotate(__l); |
|
__left_rotate(__l); |
|
__l->__is_black = __p->__is_black; |
|
__p->__is_black = true; |
|
} else if (!__s->__is_black) { |
|
__left_rotate(__s); |
|
__p->__is_black = false; |
|
__s->__is_black = true; |
|
__erase_balance(__x); |
|
} else if (!__p->__is_black) { |
|
__p->__is_black = true; |
|
__s->__is_black = false; |
|
} else { |
|
__s->__is_black = false; |
|
__erase_balance(__p); |
|
} |
|
} else { |
|
__node_pointer __s = __p->__left, __l = __s->__left, __r = __s->__right; |
|
if (!__l->__is_black) { |
|
__right_rotate(__s); |
|
std::swap(__p->__is_black, __s->__is_black); |
|
__l->__is_black = true; |
|
} else if (!__r->__is_black) { |
|
__left_rotate(__r); |
|
__right_rotate(__r); |
|
__r->__is_black = __p->__is_black; |
|
__p->__is_black = true; |
|
} else if (!__s->__is_black) { |
|
__right_rotate(__s); |
|
__p->__is_black = false; |
|
__s->__is_black = true; |
|
__erase_balance(__x); |
|
} else if (!__p->__is_black) { |
|
__p->__is_black = true; |
|
__s->__is_black = false; |
|
} else { |
|
__s->__is_black = false; |
|
__erase_balance(__p); |
|
} |
|
} |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
void rbtree<_Tp, _Comp>::__erase(rbtree::__node_pointer __x) { |
|
if (__x == __nil) return; |
|
if (__size != 1) { |
|
__node_pointer __a = __find_min(__x->__right); |
|
if (__a == __nil) __a = __x; |
|
else __x->__value = __a->__value; |
|
if (__a->__left != __nil || __a->__right != __nil) { |
|
__node_pointer __b; |
|
if (__a->__right != __nil) __b = __a->__right; |
|
else __b = __a->__left; |
|
if (__a == __root) { |
|
__root = __b; |
|
__b->__is_black = true; |
|
__b->__parent = __nil; |
|
} else { |
|
if (__a->__parent->__left == __a) __a->__parent->__left = __b; |
|
else __a->__parent->__right = __b; |
|
__b->__parent = __a->__parent; |
|
for (__node_pointer __i = __b->__parent; __i != __nil; __i = __i->__parent) __i->__count--; |
|
if (!__a->__is_black || !__b->__is_black) __b->__is_black = true; |
|
else __erase_balance(__b); |
|
} |
|
} else { |
|
if (__a->__is_black) __erase_balance(__a); |
|
if (__a->__parent->__left == __a) __a->__parent->__left = __nil; |
|
else __a->__parent->__right = __nil; |
|
for (__node_pointer __i = __a->__parent; __i != __nil; __i = __i->__parent) __i->__count--; |
|
} |
|
delete __a; |
|
} |
|
__size--; |
|
__nil->__parent = __root; |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
rbtree<_Tp, _Comp>::rbtree() { __init(); } |
|
|
|
template<class _Tp, class _Comp> |
|
rbtree<_Tp, _Comp>::rbtree(const std::vector<value_type> &__v) { |
|
__init(); |
|
insert(__v); |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
rbtree<_Tp, _Comp>::rbtree(const std::initializer_list<value_type> &__il) { |
|
__init(); |
|
insert(__il); |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
template<class _InputIterator> |
|
rbtree<_Tp, _Comp>::rbtree(_InputIterator __first, _InputIterator __last) { |
|
__init(); |
|
insert(__first, __last); |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
rbtree<_Tp, _Comp>::rbtree(const rbtree &other) { |
|
this->__init(); |
|
for (auto &i: other) this->insert(i); |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
rbtree<_Tp, _Comp>& |
|
rbtree<_Tp, _Comp>::operator=(const rbtree &other) { |
|
this->clear(); |
|
for (auto &i: other) this->insert(i); |
|
return *this; |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
void rbtree<_Tp, _Comp>::clear() { while (!empty()) __erase(__root); } |
|
|
|
template<class _Tp, class _Comp> |
|
typename rbtree<_Tp, _Comp>::iterator |
|
rbtree<_Tp, _Comp>::insert(const value_type &__x) { return iterator(__insert(__x, comp_type())); } |
|
|
|
template<class _Tp, class _Comp> |
|
typename rbtree<_Tp, _Comp>::iterator |
|
rbtree<_Tp, _Comp>::insert(value_type &&__x) { return iterator(__insert(std::move(__x), comp_type())); } |
|
|
|
template<class _Tp, class _Comp> |
|
void rbtree<_Tp, _Comp>::insert(const std::vector<value_type> &__v) { insert(__v.begin(), __v.end()); } |
|
|
|
template<class _Tp, class _Comp> |
|
void rbtree<_Tp, _Comp>::insert(const std::initializer_list<value_type> &__il) { insert(__il.begin(), __il.end()); } |
|
|
|
template<class _Tp, class _Comp> |
|
template<class _InputIterator> |
|
void rbtree<_Tp, _Comp>::insert(_InputIterator __first, _InputIterator __last) { |
|
for (; __first != __last; ++__first) |
|
insert(*__first); |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
void rbtree<_Tp, _Comp>::erase(rbtree::iterator __it) { __erase(__it.__get_np()); } |
|
|
|
template<class _Tp, class _Comp> |
|
void rbtree<_Tp, _Comp>::erase(const value_type &__x) { |
|
__node_pointer __p = __find(__x, comp_type()); |
|
if (__p->__value != __x) return; |
|
__erase(__p); |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
void rbtree<_Tp, _Comp>::erase(value_type &&__x) { |
|
__node_pointer __p = __find(std::move(__x), comp_type()); |
|
if (__p->__value != std::move(__x)) return; |
|
__erase(__p); |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
unsigned long rbtree<_Tp, _Comp>::size() { return __size; } |
|
|
|
template<class _Tp, class _Comp> |
|
bool rbtree<_Tp, _Comp>::empty() { return !__size; } |
|
|
|
template<class _Tp, class _Comp> |
|
bool rbtree<_Tp, _Comp>::empty() const { return !__size; } |
|
|
|
template<class _Tp, class _Comp> |
|
bool rbtree<_Tp, _Comp>::has(const value_type &__x) { |
|
__node_pointer __p = __find(__x, comp_type()); |
|
return __p->__value == __x; |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
bool rbtree<_Tp, _Comp>::has(value_type &&__x) { |
|
__node_pointer __p = __find(std::move(__x), comp_type()); |
|
return __p->__value == std::move(__x); |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
unsigned long rbtree<_Tp, _Comp>::count(const value_type &__x) { return index_of(upper_bound(__x)) - index_of(lower_bound(__x)); } |
|
|
|
template<class _Tp, class _Comp> |
|
unsigned long rbtree<_Tp, _Comp>::count(value_type &&__x) { return index_of(upper_bound(std::move(__x))) - index_of(lower_bound(std::move(__x))); } |
|
|
|
template<class _Tp, class _Comp> |
|
typename rbtree<_Tp, _Comp>::iterator |
|
rbtree<_Tp, _Comp>::find(const value_type &__x) { |
|
__node_pointer __p = __find(__x, comp_type()); |
|
if (__p->__value == __x) return iterator(__p); |
|
return end(); |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
typename rbtree<_Tp, _Comp>::iterator |
|
rbtree<_Tp, _Comp>::find(value_type &&__x) { |
|
__node_pointer __p = __find(std::move(__x), comp_type()); |
|
if (__p->__value == std::move(__x)) return iterator(__p); |
|
return end(); |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
std::pair<typename rbtree<_Tp, _Comp>::iterator, unsigned long> |
|
rbtree<_Tp, _Comp>::find_with(const value_type &__x) { |
|
__node_pointer __ret = __find(__x, comp_type()); |
|
if (__ret->__value == __x) return std::make_pair(iterator(__ret), __index_of(__ret)); |
|
return std::make_pair(end(), size()); |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
std::pair<typename rbtree<_Tp, _Comp>::iterator, unsigned long> |
|
rbtree<_Tp, _Comp>::find_with(value_type &&__x) { |
|
__node_pointer __ret = __find(std::move(__x), comp_type()); |
|
if (__ret->__value == std::move(__x)) return std::make_pair(iterator(__ret), __index_of(__ret)); |
|
return std::make_pair(end(), size()); |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
typename rbtree<_Tp, _Comp>::iterator |
|
rbtree<_Tp, _Comp>::nth_element(const unsigned long &__x) { return iterator(__nth_element(__x)); } |
|
|
|
template<class _Tp, class _Comp> |
|
typename rbtree<_Tp, _Comp>::iterator |
|
rbtree<_Tp, _Comp>::nth_element(unsigned long &&__x) { return iterator(__nth_element(__x)); } |
|
|
|
template<class _Tp, class _Comp> |
|
unsigned long rbtree<_Tp, _Comp>::index_of(const rbtree::iterator &__x) { |
|
if (__x.__get_np() == __nil) return size(); |
|
return __index_of(__x.__get_np()); |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
typename rbtree<_Tp, _Comp>::iterator |
|
rbtree<_Tp, _Comp>::lower_bound(const value_type &__x) { return iterator(__lower_bound(__x, comp_type())); } |
|
|
|
template<class _Tp, class _Comp> |
|
typename rbtree<_Tp, _Comp>::iterator |
|
rbtree<_Tp, _Comp>::lower_bound(value_type &&__x) { return iterator(__lower_bound(std::move(__x), comp_type())); } |
|
|
|
template<class _Tp, class _Comp> |
|
typename rbtree<_Tp, _Comp>::iterator |
|
rbtree<_Tp, _Comp>::upper_bound(const value_type &__x) { |
|
iterator it(__upper_bound(__x, comp_type())); |
|
if (*it == __x) ++it; |
|
return it; |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
typename rbtree<_Tp, _Comp>::iterator |
|
rbtree<_Tp, _Comp>::upper_bound(value_type &&__x) { |
|
iterator it(__upper_bound(std::move(__x), comp_type())); |
|
if (*it == std::move(__x)) ++it; |
|
return it; |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
std::pair<typename rbtree<_Tp, _Comp>::iterator, typename rbtree<_Tp, _Comp>::iterator> |
|
rbtree<_Tp, _Comp>::equal_range(const value_type &__x) { return std::make_pair(lower_bound(__x), upper_bound(__x)); } |
|
|
|
template<class _Tp, class _Comp> |
|
std::pair<typename rbtree<_Tp, _Comp>::iterator, typename rbtree<_Tp, _Comp>::iterator> |
|
rbtree<_Tp, _Comp>::equal_range(value_type &&__x) { return std::make_pair(lower_bound(std::move(__x)), upper_bound(std::move(__x))); } |
|
|
|
template<class _Tp, class _Comp> |
|
void rbtree<_Tp, _Comp>::merge(const rbtree &t) { for (auto &i: t) insert(i); } |
|
|
|
template<class _Tp, class _Comp> |
|
typename rbtree<_Tp, _Comp>::iterator |
|
rbtree<_Tp, _Comp>::begin() { |
|
if (empty()) return iterator(__nil); |
|
return iterator(__find_min(__root)); |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
typename rbtree<_Tp, _Comp>::const_iterator |
|
rbtree<_Tp, _Comp>::begin() const { |
|
if (empty()) return const_iterator(__nil); |
|
return const_iterator(__find_min(__root)); |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
typename rbtree<_Tp, _Comp>::reverse_iterator |
|
rbtree<_Tp, _Comp>::rbegin() { return reverse_iterator(end()); } |
|
|
|
template<class _Tp, class _Comp> |
|
typename rbtree<_Tp, _Comp>::reverse_const_iterator |
|
rbtree<_Tp, _Comp>::rbegin() const { return reverse_const_iterator(cend()); } |
|
|
|
template<class _Tp, class _Comp> |
|
typename rbtree<_Tp, _Comp>::iterator |
|
rbtree<_Tp, _Comp>::end() { return iterator(__nil); } |
|
|
|
template<class _Tp, class _Comp> |
|
typename rbtree<_Tp, _Comp>::const_iterator |
|
rbtree<_Tp, _Comp>::end() const { return const_iterator(__nil); } |
|
|
|
template<class _Tp, class _Comp> |
|
typename rbtree<_Tp, _Comp>::reverse_iterator |
|
rbtree<_Tp, _Comp>::rend() { return reverse_iterator(begin()); } |
|
|
|
template<class _Tp, class _Comp> |
|
typename rbtree<_Tp, _Comp>::reverse_const_iterator |
|
rbtree<_Tp, _Comp>::rend() const { return reverse_const_iterator(cbegin()); } |
|
|
|
template<class _Tp, class _Comp> |
|
typename rbtree<_Tp, _Comp>::const_iterator |
|
rbtree<_Tp, _Comp>::cbegin() const { |
|
if (empty()) return const_iterator(__nil); |
|
return const_iterator(__find_min(__root)); |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
typename rbtree<_Tp, _Comp>::reverse_const_iterator |
|
rbtree<_Tp, _Comp>::crbegin() const { return reverse_const_iterator(cend()); } |
|
|
|
template<class _Tp, class _Comp> |
|
typename rbtree<_Tp, _Comp>::const_iterator |
|
rbtree<_Tp, _Comp>::cend() const { return const_iterator(__nil); } |
|
|
|
template<class _Tp, class _Comp> |
|
typename rbtree<_Tp, _Comp>::reverse_const_iterator |
|
rbtree<_Tp, _Comp>::crend() const { return reverse_const_iterator(cbegin()); } |
|
|
|
template<class _Tp, class _Comp> |
|
rbtree<_Tp, _Comp>::~rbtree() { clear(); } |
|
|
|
// the red-black multi rbtree class |
|
template<class _Tp, class _Comp = std::less<_Tp>> |
|
class multi_rbtree { |
|
public: |
|
typedef _Tp value_type; |
|
typedef _Comp comp_type; |
|
|
|
private: |
|
typedef __rbtree_node_<value_type> __node; |
|
typedef __node* __node_pointer; |
|
|
|
public: |
|
typedef __rbtree_const_iterator_<value_type> iterator; |
|
typedef __rbtree_const_iterator_<value_type> const_iterator; |
|
typedef std::reverse_iterator<iterator> reverse_iterator; |
|
typedef std::reverse_iterator<const_iterator> reverse_const_iterator; |
|
|
|
private: |
|
// the pointer to __root and __nil |
|
// __nil's parent would be always __root |
|
__node_pointer __root, __nil; |
|
|
|
unsigned long __size; |
|
|
|
// init method - is called by constructors in the beginning for initialization |
|
inline void __init(); |
|
|
|
// finds the value __x |
|
// returns the pointer of node of __x if rbtree has the value |
|
// or returns the pointer to the leaf node that was last node when searching |
|
template<class _Compare> |
|
inline __node_pointer __find(const value_type &__x, _Compare compare); |
|
|
|
// finds the value __x |
|
// returns the pointer of node of __x if rbtree has the value |
|
// or returns the pointer to the leaf node that was last node when searching |
|
template<class _Compare> |
|
inline __node_pointer __find(value_type &&__x, _Compare compare); |
|
|
|
// finds the min node from node pointer |
|
// returns itself when it is leaf node |
|
// precondition : __p is not __nil |
|
inline __node_pointer __find_min(__node_pointer __p); |
|
|
|
// finds the min node from node pointer |
|
// returns itself when it is leaf node |
|
// precondition : __p is not __nil |
|
inline __node_pointer __find_min(__node_pointer __p) const; |
|
|
|
// finds the __xth element when the values are sorted (0 based) |
|
// returns pointer of __xth node if __x is in range |
|
// or returns pointer to __nil |
|
inline __node_pointer __nth_element(unsigned long __x); |
|
|
|
// finds the index of node pointer __p when the values are sorted (0 based) |
|
// returns the index of node pointer __p node |
|
inline unsigned long __index_of(__node_pointer __p); |
|
|
|
// simple lower_bound function |
|
// returns the pointer to the first not small value of __x |
|
template<class _Compare> |
|
inline __node_pointer __lower_bound(const value_type &__x, _Compare compare); |
|
|
|
// simple lower_bound function |
|
// returns the pointer to the first not small value of __x |
|
template<class _Compare> |
|
inline __node_pointer __lower_bound(value_type &&__x, _Compare compare); |
|
|
|
// simple upper_bound function |
|
// returns the pointer to the first big value of __x |
|
template<class _Compare> |
|
inline __node_pointer __upper_bound(const value_type &__x, _Compare compare); |
|
|
|
// simple upper_bound function |
|
// returns the pointer to the first big value of __x |
|
template<class _Compare> |
|
inline __node_pointer __upper_bound(value_type &&__x, _Compare compare); |
|
|
|
// returns the sibling node of the pointer of __p if __p is not root |
|
// or returns __nil; |
|
// preconditions : __p is not __nil |
|
inline __node_pointer __sibling_node(__node_pointer __p); |
|
|
|
// rotates the rbtree left from __b's parent |
|
// when the function is finished, __b would be parent of __b's parent |
|
// changes the root when __b's parent was root |
|
// preconditions : __b is not __root. |
|
void __left_rotate(__node_pointer __b); |
|
|
|
// rotates the rbtree right from __b's parent |
|
// when the function is finished, __b would be parent of __b's parent |
|
// changes the root when __b's parent was root |
|
// preconditions : __b is not __root |
|
void __right_rotate(__node_pointer __b); |
|
|
|
// the balance function after insert |
|
// __p is the pointer to node that was inserted |
|
// preconditions : __p is red and __p's parent is red |
|
void __insert_balance(__node_pointer __p); |
|
|
|
// inserts the value __x |
|
// do nothing when __x is already in the rbtree |
|
// allocates a new node that the value is __x |
|
template<class _Compare> |
|
__node_pointer __insert(const value_type &__x, _Compare compare); |
|
|
|
// inserts the value __x |
|
// do nothing when __x is already in the rbtree |
|
// allocates a new node that the value is __x |
|
template<class _Compare> |
|
__node_pointer __insert(value_type &&__x, _Compare compare); |
|
|
|
// the balance function after erase |
|
// __x is the pointer to node of a child that was erased |
|
// preconditions : __x's black nodes count is 1 smaller than sibling of __x's |
|
void __erase_balance(__node_pointer __x); |
|
|
|
// erases the pointer __x |
|
// deallocates the one-child node and changes the value |
|
// do nothing when __x is __nil |
|
void __erase(__node_pointer __x); |
|
|
|
public: |
|
|
|
// simple constructor |
|
multi_rbtree(); |
|
|
|
// constructor that inserts all the value in vector __v |
|
multi_rbtree(const std::vector<value_type> &__v); |
|
|
|
// constructor that inserts all the value in initialize_list __il |
|
multi_rbtree(const std::initializer_list<value_type> &__il); |
|
|
|
// constructor that inserts all the value from input iterator __first to intput iterator __last |
|
template<class _InputIterator> |
|
multi_rbtree(_InputIterator __first, _InputIterator __last); |
|
|
|
multi_rbtree(const multi_rbtree &other); |
|
|
|
multi_rbtree &operator=(const multi_rbtree &other); |
|
|
|
// deallocates all the node |
|
void clear(); |
|
|
|
// inserts the value __x |
|
iterator insert(const value_type &__x); |
|
|
|
// inserts the value __x |
|
iterator insert(value_type &&__x); |
|
|
|
// inserts the value all from vector __v |
|
void insert(const std::vector<value_type> &__v); |
|
|
|
// inserts the value all from initializer list __il |
|
void insert(const std::initializer_list<value_type> &__il); |
|
|
|
// inserts the value all from input iterator __first to input iterator __last |
|
template<class _InputIterator> |
|
void insert(_InputIterator __first, _InputIterator __last); |
|
|
|
// erases the node that iterator is pointing at |
|
void erase(iterator __it); |
|
|
|
// erases the value if the rbtree has the value |
|
void erase(const value_type &__x); |
|
|
|
// erases the value if the rbtree has the value |
|
void erase(value_type &&__x); |
|
|
|
// returns the size of the rbtree |
|
unsigned long size(); |
|
|
|
// returns if rbtree is empty |
|
bool empty(); |
|
|
|
// returns if rbtree is empty |
|
bool empty() const; |
|
|
|
// returns if the rbtree has the value __x |
|
bool has(const value_type &__x); |
|
|
|
// returns if the rbtree has the value __x |
|
bool has(value_type &&__x); |
|
|
|
// returns the count of the value __x in the rbtree |
|
unsigned long count(const value_type &__x); |
|
|
|
// returns the count of the value __x in the rbtree |
|
unsigned long count(value_type &&__x); |
|
|
|
// returns the any iterator of value __x if the value is in the rbtree |
|
// or returns end iterator |
|
iterator find(const value_type &__x); |
|
|
|
// returns the any iterator of value __x if the value is in the rbtree |
|
// or returns end iterator |
|
iterator find(value_type &&__x); |
|
|
|
// returns the pair of find function and index_of function (0 based) |
|
// index_of gets iterator, but this function gets the value __x |
|
std::pair<iterator, unsigned long> find_with(const value_type &__x); |
|
|
|
// returns the pair of find function and index_of function (0 based) |
|
// index_of gets iterator, but this function gets the value __x |
|
std::pair<iterator, unsigned long> find_with(value_type &&__x); |
|
|
|
// returns the iterator pointing the nth element of the values when sorted if __x is in range (0 based) |
|
// of returns the end iterator |
|
iterator nth_element(const unsigned long &__x); |
|
|
|
// returns the iterator pointing the nth element of the values when sorted if __x is in range (0 based) |
|
// of returns the end iterator |
|
iterator nth_element(unsigned long &&__x); |
|
|
|
// returns the index of iterator __x in the rbtree when sorted (0 based) |
|
// or returns the size of the rbtree when the iterator is pointing __nil |
|
unsigned long index_of(const iterator &__x); |
|
|
|
// returns the iterator pointing to the first not small value of __x |
|
iterator lower_bound(const value_type &__x); |
|
|
|
// returns the iterator pointing to the first not small value of __x |
|
iterator lower_bound(value_type &&__x); |
|
|
|
// returns the iterator pointing to the first bigger value of __x |
|
iterator upper_bound(const value_type &__x); |
|
|
|
// returns the iterator pointing to the first bigger value of __x |
|
iterator upper_bound(value_type &&__x); |
|
|
|
// returns the pair of lower_bound and upper_bound |
|
std::pair<iterator, iterator> equal_range(const value_type &__x); |
|
|
|
// returns the pair of lower_bound and upper_bound |
|
std::pair<iterator, iterator> equal_range(value_type &&__x); |
|
|
|
void merge(const multi_rbtree &t); |
|
|
|
// returns the begin iterator pointing min value |
|
iterator begin(); |
|
|
|
// returns the const begin iterator pointing min value |
|
const_iterator begin() const; |
|
|
|
// returns the reverse iterator of end |
|
// the value of the rbegin would be max value of the rbtree |
|
reverse_iterator rbegin(); |
|
|
|
// returns the reverse iterator of end |
|
// the value of the rbegin would be max value of the rbtree |
|
reverse_const_iterator rbegin() const; |
|
|
|
// returns the end iterator pointing __nil |
|
iterator end(); |
|
|
|
// returns the end iterator pointing __nil |
|
const_iterator end() const; |
|
|
|
// returns the reverse iterator of begin |
|
// the value of the rend would be __nil |
|
reverse_iterator rend(); |
|
|
|
// returns the reverse iterator of begin |
|
// the value of the rend would be __nil |
|
reverse_const_iterator rend() const; |
|
|
|
// returns the begin const iterator pointing min value |
|
const_iterator cbegin() const; |
|
|
|
// returns the reverse const iterator of end |
|
// the value of the crbegin would be max value of the rbtree |
|
reverse_const_iterator crbegin() const; |
|
|
|
// returns the end const iterator pointing __nil |
|
const_iterator cend() const; |
|
|
|
// returns the reverse const iterator of begin |
|
// the value of the crend would be __nil |
|
reverse_const_iterator crend() const; |
|
|
|
// destructor of the rbtree class |
|
// deallocates all the nodes |
|
~multi_rbtree(); |
|
}; |
|
|
|
template<class _Tp, class _Comp> |
|
void multi_rbtree<_Tp, _Comp>::__init() { |
|
__root = new __node; |
|
__nil = new __node; |
|
__root->__parent = __nil; |
|
__root->__left = __nil; |
|
__root->__right = __nil; |
|
__root->__is_black = true; |
|
__root->__count = 0; |
|
__nil->__parent = __root; |
|
__nil->__left = __nil; |
|
__nil->__right = __nil; |
|
__nil->__is_black = true; |
|
__nil->__count = 0; |
|
__size = 0; |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
template<class _Compare> |
|
typename multi_rbtree<_Tp, _Comp>::__node_pointer |
|
multi_rbtree<_Tp, _Comp>::__find(const value_type &__x, _Compare compare) { |
|
__node_pointer __p = __root, __q = __p; |
|
while (__p != __nil) { |
|
__q = __p; |
|
if (__x == __p->__value) return __p; |
|
if (compare(__x, __p->__value)) __p = __p->__left; |
|
else __p = __p->__right; |
|
} |
|
return __q; |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
template<class _Compare> |
|
typename multi_rbtree<_Tp, _Comp>::__node_pointer |
|
multi_rbtree<_Tp, _Comp>::__find(value_type &&__x, _Compare compare) { |
|
__node_pointer __p = __root, __q = __p; |
|
while (__p != __nil) { |
|
__q = __p; |
|
if (std::move(__x) == __p->__value) return __p; |
|
if (compare(std::move(__x), __p->__value)) __p = __p->__left; |
|
else __p = __p->__right; |
|
} |
|
return __q; |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
typename multi_rbtree<_Tp, _Comp>::__node_pointer |
|
multi_rbtree<_Tp, _Comp>::__find_min(multi_rbtree::__node_pointer __p) { |
|
while (__p->__left != __nil) |
|
__p = __p->__left; |
|
return __p; |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
typename multi_rbtree<_Tp, _Comp>::__node_pointer |
|
multi_rbtree<_Tp, _Comp>::__find_min(multi_rbtree::__node_pointer __p) const { |
|
while (__p->__left != __nil) |
|
__p = __p->__left; |
|
return __p; |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
typename multi_rbtree<_Tp, _Comp>::__node_pointer |
|
multi_rbtree<_Tp, _Comp>::__nth_element(unsigned long __x) { |
|
__node_pointer __p = __root; |
|
while (__p != __nil) { |
|
if (__x == __p->__left->__count) return __p; |
|
if (__x < __p->__left->__count) __p = __p->__left; |
|
else { |
|
__x -= __p->__left->__count + 1; |
|
__p = __p->__right; |
|
} |
|
} |
|
return __nil; |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
unsigned long multi_rbtree<_Tp, _Comp>::__index_of(multi_rbtree::__node_pointer __p) { |
|
unsigned long ans = __p->__left->__count; |
|
while (__p != __root) { |
|
if (__p == __p->__parent->__right) ans += __p->__parent->__left->__count + 1; |
|
__p = __p->__parent; |
|
} |
|
return ans; |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
template<class _Compare> |
|
typename multi_rbtree<_Tp, _Comp>::__node_pointer |
|
multi_rbtree<_Tp, _Comp>::__lower_bound(const value_type &__x, _Compare compare) { |
|
__node_pointer __p = __root, __ans = __nil; |
|
while (__p->__left != __nil && __p->__right != __nil) { |
|
if (__x == __p->__value) { |
|
while (__p->__left->__value == __x) __p = __p->__left; |
|
return __p; |
|
} |
|
if (compare(__x, __p->__value)) |
|
__p = __p->__left; |
|
else { |
|
__p = __p->__right; |
|
if (compare(__p->__value, __ans->__value) || __ans == __nil) __ans = __p; |
|
} |
|
} |
|
return __ans; |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
template<class _Compare> |
|
typename multi_rbtree<_Tp, _Comp>::__node_pointer |
|
multi_rbtree<_Tp, _Comp>::__lower_bound(value_type &&__x, _Compare compare) { |
|
__node_pointer __p = __root, __ans = __nil; |
|
while (__p->__left != __nil && __p->__right != __nil) { |
|
if (std::move(__x) == __p->__value) { |
|
while (__p->__left->__value == std::move(__x)) __p = __p->__left; |
|
return __p; |
|
} |
|
if (compare(std::move(__x), __p->__value)) |
|
__p = __p->__left; |
|
else { |
|
__p = __p->__right; |
|
if (compare(__p->__value, __ans->__value) || __ans == __nil) __ans = __p; |
|
} |
|
} |
|
return __ans; |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
template<class _Compare> |
|
typename multi_rbtree<_Tp, _Comp>::__node_pointer |
|
multi_rbtree<_Tp, _Comp>::__upper_bound(const value_type &__x, _Compare compare) { |
|
__node_pointer __p = __root, __ans = __nil; |
|
while (__p->__left != __nil && __p->__right != __nil) { |
|
if (__x == __p->__value) { |
|
while (__p->__right->__value == __x) __p = __p->__right; |
|
return __p; |
|
} |
|
if (compare(__x, __p->__value)) |
|
__p = __p->__left; |
|
else { |
|
__p = __p->__right; |
|
if (compare(__p->__value, __ans->__value) || __ans == __nil) __ans = __p; |
|
} |
|
} |
|
return __ans; |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
template<class _Compare> |
|
typename multi_rbtree<_Tp, _Comp>::__node_pointer |
|
multi_rbtree<_Tp, _Comp>::__upper_bound(value_type &&__x, _Compare compare) { |
|
__node_pointer __p = __root, __ans = __nil; |
|
while (__p->__left != __nil && __p->__right != __nil) { |
|
if (std::move(__x) == __p->__value) { |
|
while (__p->__right->__value == std::move(__x)) __p = __p->__right; |
|
return __p; |
|
} |
|
if (compare(std::move(__x), __p->__value)) |
|
__p = __p->__left; |
|
else { |
|
__p = __p->__right; |
|
if (compare(__p->__value, __ans->__value) || __ans == __nil) __ans = __p; |
|
} |
|
} |
|
return __ans; |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
typename multi_rbtree<_Tp, _Comp>::__node_pointer |
|
multi_rbtree<_Tp, _Comp>::__sibling_node(multi_rbtree::__node_pointer __p) { |
|
if (__p == __root) return __nil; |
|
if (__p == __p->__parent->__left) return __p->__parent->__right; |
|
return __p->__parent->__left; |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
void multi_rbtree<_Tp, _Comp>::__left_rotate(multi_rbtree::__node_pointer __b) { |
|
__node_pointer __a = __b->__parent, __p = __b->__left, __q = __a->__parent; |
|
if (__a == __root) |
|
__root = __b; |
|
else { |
|
if (__a == __q->__left) __q->__left = __b; |
|
else __q->__right = __b; |
|
} |
|
if (__b == __root) __b->__parent = __nil; |
|
else __b->__parent = __q; |
|
__b->__left = __a; |
|
__a->__parent = __b; |
|
__a->__right = __p; |
|
if (__p != __nil) __p->__parent = __a; |
|
__b->__count = __a->__count; |
|
__a->__count = __a->__left->__count + __a->__right->__count + 1; |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
void multi_rbtree<_Tp, _Comp>::__right_rotate(multi_rbtree::__node_pointer __b) { |
|
__node_pointer __a = __b->__parent, __p = __b->__right, __q = __a->__parent; |
|
if (__a == __root) |
|
__root = __b; |
|
else { |
|
if (__a == __q->__left) __q->__left = __b; |
|
else __q->__right = __b; |
|
} |
|
if (__b == __root) __b->__parent = __nil; |
|
else __b->__parent = __q; |
|
__b->__right = __a; |
|
__a->__parent = __b; |
|
__a->__left = __p; |
|
if (__p != __nil) __p->__parent = __a; |
|
__a->__count = __b->__count; |
|
__b->__count = __b->__left->__count + __b->__right->__count + 1; |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
void multi_rbtree<_Tp, _Comp>::__insert_balance(multi_rbtree::__node_pointer __p) { |
|
if (__p->__parent == __root) { |
|
__root->__is_black = true; |
|
return; |
|
} |
|
__node_pointer __s = __sibling_node(__p->__parent); |
|
__node_pointer __a = __p->__parent->__parent; |
|
if (!__s->__is_black) { |
|
__s->__is_black = true; |
|
__p->__parent->__is_black = true; |
|
if (__a != __root) { |
|
__a->__is_black = false; |
|
if (!__a->__parent->__is_black) |
|
__insert_balance(__a); |
|
} |
|
} else { |
|
if (__p->__parent == __a->__left) { |
|
if (__p == __p->__parent->__right) { |
|
__left_rotate(__p); |
|
__right_rotate(__p); |
|
__p->__is_black = true; |
|
} else { |
|
__right_rotate(__p->__parent); |
|
__p->__parent->__is_black = true; |
|
} |
|
__a->__is_black = false; |
|
} else { |
|
if (__p == __p->__parent->__left) { |
|
__right_rotate(__p); |
|
__left_rotate(__p); |
|
__p->__is_black = true; |
|
} else { |
|
__left_rotate(__p->__parent); |
|
__p->__parent->__is_black = true; |
|
} |
|
__a->__is_black = false; |
|
} |
|
} |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
template<class _Compare> |
|
typename multi_rbtree<_Tp, _Comp>::__node_pointer |
|
multi_rbtree<_Tp, _Comp>::__insert(const value_type &__x, _Compare compare) { |
|
__size++; |
|
if (__size == 1) { |
|
__root->__value = __x; |
|
__root->__count++; |
|
__nil->__parent = __root; |
|
return __root; |
|
} |
|
__node_pointer __p = __root, __q = __p; |
|
while (__p != __nil) { |
|
__q = __p; |
|
if (compare(__x, __p->__value)) __p = __p->__left; |
|
else __p = __p->__right; |
|
} |
|
__p = __q; |
|
__node_pointer __n = new __node; |
|
__n->__parent = __p; |
|
if (compare(__x, __p->__value)) __p->__left = __n; |
|
else __p->__right = __n; |
|
__n->__is_black = false; |
|
__n->__left = __nil; |
|
__n->__right = __nil; |
|
__n->__value = __x; |
|
__n->__count = 0; |
|
for (__node_pointer __i = __n; __i != __nil; __i = __i->__parent) __i->__count++; |
|
if (!__p->__is_black) __insert_balance(__n); |
|
__nil->__parent = __root; |
|
return __n; |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
template<class _Compare> |
|
typename multi_rbtree<_Tp, _Comp>::__node_pointer |
|
multi_rbtree<_Tp, _Comp>::__insert(value_type &&__x, _Compare compare) { |
|
__size++; |
|
if (__size == 1) { |
|
__root->__value = std::move(__x); |
|
__root->__count++; |
|
__nil->__parent = __root; |
|
return __root; |
|
} |
|
__node_pointer __p = __root, __q = __p; |
|
while (__p != __nil) { |
|
__q = __p; |
|
if (compare(std::move(__x), __p->__value)) __p = __p->__left; |
|
else __p = __p->__right; |
|
} |
|
__p = __q; |
|
__node_pointer __n = new __node; |
|
__n->__parent = __p; |
|
if (compare(std::move(__x), __p->__value)) __p->__left = __n; |
|
else __p->__right = __n; |
|
__n->__is_black = false; |
|
__n->__left = __nil; |
|
__n->__right = __nil; |
|
__n->__value = std::move(__x); |
|
__n->__count = 0; |
|
for (__node_pointer __i = __n; __i != __nil; __i = __i->__parent) __i->__count++; |
|
if (!__p->__is_black) __insert_balance(__n); |
|
__nil->__parent = __root; |
|
return __n; |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
void multi_rbtree<_Tp, _Comp>::__erase_balance(multi_rbtree::__node_pointer __x) { |
|
if (__x == __root) { |
|
__x->__is_black = true; |
|
return; |
|
} |
|
__node_pointer __p = __x->__parent; |
|
if (__x == __p->__left) { |
|
__node_pointer __s = __p->__right, __l = __s->__left, __r = __s->__right; |
|
if (!__r->__is_black) { |
|
__left_rotate(__s); |
|
std::swap(__p->__is_black, __s->__is_black); |
|
__r->__is_black = true; |
|
} else if (!__l->__is_black) { |
|
__right_rotate(__l); |
|
__left_rotate(__l); |
|
__l->__is_black = __p->__is_black; |
|
__p->__is_black = true; |
|
} else if (!__s->__is_black) { |
|
__left_rotate(__s); |
|
__p->__is_black = false; |
|
__s->__is_black = true; |
|
__erase_balance(__x); |
|
} else if (!__p->__is_black) { |
|
__p->__is_black = true; |
|
__s->__is_black = false; |
|
} else { |
|
__s->__is_black = false; |
|
__erase_balance(__p); |
|
} |
|
} else { |
|
__node_pointer __s = __p->__left, __l = __s->__left, __r = __s->__right; |
|
if (!__l->__is_black) { |
|
__right_rotate(__s); |
|
std::swap(__p->__is_black, __s->__is_black); |
|
__l->__is_black = true; |
|
} else if (!__r->__is_black) { |
|
__left_rotate(__r); |
|
__right_rotate(__r); |
|
__r->__is_black = __p->__is_black; |
|
__p->__is_black = true; |
|
} else if (!__s->__is_black) { |
|
__right_rotate(__s); |
|
__p->__is_black = false; |
|
__s->__is_black = true; |
|
__erase_balance(__x); |
|
} else if (!__p->__is_black) { |
|
__p->__is_black = true; |
|
__s->__is_black = false; |
|
} else { |
|
__s->__is_black = false; |
|
__erase_balance(__p); |
|
} |
|
} |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
void multi_rbtree<_Tp, _Comp>::__erase(multi_rbtree::__node_pointer __x) { |
|
if (__x == __nil) return; |
|
if (__size != 1) { |
|
__node_pointer __a = __find_min(__x->__right); |
|
if (__a == __nil) __a = __x; |
|
else __x->__value = __a->__value; |
|
if (__a->__left != __nil || __a->__right != __nil) { |
|
__node_pointer __b; |
|
if (__a->__right != __nil) __b = __a->__right; |
|
else __b = __a->__left; |
|
if (__a == __root) { |
|
__root = __b; |
|
__b->__is_black = true; |
|
__b->__parent = __nil; |
|
} else { |
|
if (__a->__parent->__left == __a) __a->__parent->__left = __b; |
|
else __a->__parent->__right = __b; |
|
__b->__parent = __a->__parent; |
|
for (__node_pointer __i = __b->__parent; __i != __nil; __i = __i->__parent) __i->__count--; |
|
if (!__a->__is_black || !__b->__is_black) __b->__is_black = true; |
|
else __erase_balance(__b); |
|
} |
|
} else { |
|
if (__a->__is_black) __erase_balance(__a); |
|
if (__a->__parent->__left == __a) __a->__parent->__left = __nil; |
|
else __a->__parent->__right = __nil; |
|
for (__node_pointer __i = __a->__parent; __i != __nil; __i = __i->__parent) __i->__count--; |
|
} |
|
delete __a; |
|
} |
|
__size--; |
|
__nil->__parent = __root; |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
multi_rbtree<_Tp, _Comp>::multi_rbtree() { __init(); } |
|
|
|
template<class _Tp, class _Comp> |
|
multi_rbtree<_Tp, _Comp>::multi_rbtree(const std::vector<value_type> &__v) { |
|
__init(); |
|
insert(__v); |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
multi_rbtree<_Tp, _Comp>::multi_rbtree(const std::initializer_list<value_type> &__il) { |
|
__init(); |
|
insert(__il); |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
template<class _InputIterator> |
|
multi_rbtree<_Tp, _Comp>::multi_rbtree(_InputIterator __first, _InputIterator __last) { |
|
__init(); |
|
insert(__first, __last); |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
multi_rbtree<_Tp, _Comp>::multi_rbtree(const multi_rbtree &other) { |
|
this->__init(); |
|
for (auto &i: other) this->insert(i); |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
multi_rbtree<_Tp, _Comp> &multi_rbtree<_Tp, _Comp>::operator=(const multi_rbtree &other) { |
|
this->clear(); |
|
for (auto &i: other) this->insert(i); |
|
return *this; |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
void multi_rbtree<_Tp, _Comp>::clear() { while (!empty()) __erase(__root); } |
|
|
|
template<class _Tp, class _Comp> |
|
typename multi_rbtree<_Tp, _Comp>::iterator |
|
multi_rbtree<_Tp, _Comp>::insert(const value_type &__x) { return iterator(__insert(__x, comp_type())); } |
|
|
|
template<class _Tp, class _Comp> |
|
typename multi_rbtree<_Tp, _Comp>::iterator |
|
multi_rbtree<_Tp, _Comp>::insert(value_type &&__x) { return iterator(__insert(std::move(__x), comp_type())); } |
|
|
|
template<class _Tp, class _Comp> |
|
void multi_rbtree<_Tp, _Comp>::insert(const std::vector<value_type> &__v) { insert(__v.begin(), __v.end()); } |
|
|
|
template<class _Tp, class _Comp> |
|
void multi_rbtree<_Tp, _Comp>::insert(const std::initializer_list<value_type> &__il) { insert(__il.begin(), __il.end()); } |
|
|
|
template<class _Tp, class _Comp> |
|
template<class _InputIterator> |
|
void multi_rbtree<_Tp, _Comp>::insert(_InputIterator __first, _InputIterator __last) { |
|
for (; __first != __last; ++__first) |
|
insert(*__first); |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
void multi_rbtree<_Tp, _Comp>::erase(multi_rbtree::iterator __it) { __erase(__it.__get_np()); } |
|
|
|
template<class _Tp, class _Comp> |
|
void multi_rbtree<_Tp, _Comp>::erase(const value_type &__x) { |
|
__node_pointer __p = __find(__x, comp_type()); |
|
if (__p->__value != __x) return; |
|
__erase(__p); |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
void multi_rbtree<_Tp, _Comp>::erase(value_type &&__x) { |
|
__node_pointer __p = __find(std::move(__x), comp_type()); |
|
if (__p->__value != std::move(__x)) return; |
|
__erase(__p); |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
unsigned long multi_rbtree<_Tp, _Comp>::size() { return __size; } |
|
|
|
template<class _Tp, class _Comp> |
|
bool multi_rbtree<_Tp, _Comp>::empty() { return !__size; } |
|
|
|
template<class _Tp, class _Comp> |
|
bool multi_rbtree<_Tp, _Comp>::empty() const { return !__size; } |
|
|
|
template<class _Tp, class _Comp> |
|
bool multi_rbtree<_Tp, _Comp>::has(const value_type &__x) { |
|
__node_pointer __p = __find(__x, comp_type()); |
|
return __p->__value == __x; |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
bool multi_rbtree<_Tp, _Comp>::has(value_type &&__x) { |
|
__node_pointer __p = __find(std::move(__x), comp_type()); |
|
return __p->__value == std::move(__x); |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
unsigned long multi_rbtree<_Tp, _Comp>::count(const value_type &__x) { return index_of(upper_bound(__x)) - index_of(lower_bound(__x)); } |
|
|
|
template<class _Tp, class _Comp> |
|
unsigned long multi_rbtree<_Tp, _Comp>::count(value_type &&__x) { return index_of(upper_bound(std::move(__x))) - index_of(lower_bound(std::move(__x))); } |
|
|
|
template<class _Tp, class _Comp> |
|
typename multi_rbtree<_Tp, _Comp>::iterator |
|
multi_rbtree<_Tp, _Comp>::find(const value_type &__x) { |
|
__node_pointer __p = __find(__x, comp_type()); |
|
if (__p->__value == __x) return iterator(__p); |
|
return end(); |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
typename multi_rbtree<_Tp, _Comp>::iterator |
|
multi_rbtree<_Tp, _Comp>::find(value_type &&__x) { |
|
__node_pointer __p = __find(std::move(__x), comp_type()); |
|
if (__p->__value == std::move(__x)) return iterator(__p); |
|
return end(); |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
std::pair<typename multi_rbtree<_Tp, _Comp>::iterator, unsigned long> |
|
multi_rbtree<_Tp, _Comp>::find_with(const value_type &__x) { |
|
__node_pointer __ret = __find(__x, comp_type()); |
|
if (__ret->__value == __x) return std::make_pair(iterator(__ret), __index_of(__ret)); |
|
return std::make_pair(end(), size()); |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
std::pair<typename multi_rbtree<_Tp, _Comp>::iterator, unsigned long> |
|
multi_rbtree<_Tp, _Comp>::find_with(value_type &&__x) { |
|
__node_pointer __ret = __find(std::move(__x), comp_type()); |
|
if (__ret->__value == std::move(__x)) return std::make_pair(iterator(__ret), __index_of(__ret)); |
|
return std::make_pair(end(), size()); |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
typename multi_rbtree<_Tp, _Comp>::iterator |
|
multi_rbtree<_Tp, _Comp>::nth_element(const unsigned long &__x) { return iterator(__nth_element(__x)); } |
|
|
|
template<class _Tp, class _Comp> |
|
typename multi_rbtree<_Tp, _Comp>::iterator |
|
multi_rbtree<_Tp, _Comp>::nth_element(unsigned long &&__x) { return iterator(__nth_element(__x)); } |
|
|
|
template<class _Tp, class _Comp> |
|
unsigned long multi_rbtree<_Tp, _Comp>::index_of(const iterator &__x) { |
|
if (__x.__get_np() == __nil) return size(); |
|
return __index_of(__x.__get_np()); |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
typename multi_rbtree<_Tp, _Comp>::iterator |
|
multi_rbtree<_Tp, _Comp>::lower_bound(const value_type &__x) { return iterator(__lower_bound(__x, comp_type())); } |
|
|
|
template<class _Tp, class _Comp> |
|
typename multi_rbtree<_Tp, _Comp>::iterator |
|
multi_rbtree<_Tp, _Comp>::lower_bound(value_type &&__x) { return iterator(__lower_bound(std::move(__x), comp_type())); } |
|
|
|
template<class _Tp, class _Comp> |
|
typename multi_rbtree<_Tp, _Comp>::iterator |
|
multi_rbtree<_Tp, _Comp>::upper_bound(const value_type &__x) { |
|
iterator it(__upper_bound(__x, comp_type())); |
|
if (*it == __x) ++it; |
|
return it; |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
typename multi_rbtree<_Tp, _Comp>::iterator |
|
multi_rbtree<_Tp, _Comp>::upper_bound(value_type &&__x) { |
|
iterator it(__upper_bound(std::move(__x), comp_type())); |
|
if (*it == std::move(__x)) ++it; |
|
return it; |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
std::pair<typename multi_rbtree<_Tp, _Comp>::iterator, typename multi_rbtree<_Tp, _Comp>::iterator> |
|
multi_rbtree<_Tp, _Comp>::equal_range(const value_type &__x) { return std::make_pair(lower_bound(__x), upper_bound(__x)); } |
|
|
|
template<class _Tp, class _Comp> |
|
std::pair<typename multi_rbtree<_Tp, _Comp>::iterator, typename multi_rbtree<_Tp, _Comp>::iterator> |
|
multi_rbtree<_Tp, _Comp>::equal_range(value_type &&__x) { return std::make_pair(lower_bound(std::move(__x)), upper_bound(std::move(__x))); } |
|
|
|
template<class _Tp, class _Comp> |
|
void multi_rbtree<_Tp, _Comp>::merge(const multi_rbtree &t) { for (auto &i: t) insert(i); } |
|
|
|
template<class _Tp, class _Comp> |
|
typename multi_rbtree<_Tp, _Comp>::iterator |
|
multi_rbtree<_Tp, _Comp>::begin() { |
|
if (empty()) return iterator(__nil); |
|
return iterator(__find_min(__root)); |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
typename multi_rbtree<_Tp, _Comp>::const_iterator |
|
multi_rbtree<_Tp, _Comp>::begin() const { |
|
if (empty()) return const_iterator(__nil); |
|
return const_iterator(__find_min(__root)); |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
typename multi_rbtree<_Tp, _Comp>::reverse_iterator |
|
multi_rbtree<_Tp, _Comp>::rbegin() { return reverse_iterator(end()); } |
|
|
|
template<class _Tp, class _Comp> |
|
typename multi_rbtree<_Tp, _Comp>::reverse_const_iterator |
|
multi_rbtree<_Tp, _Comp>::rbegin() const { return reverse_const_iterator(cend()); } |
|
|
|
template<class _Tp, class _Comp> |
|
typename multi_rbtree<_Tp, _Comp>::iterator |
|
multi_rbtree<_Tp, _Comp>::end() { return iterator(__nil); } |
|
|
|
template<class _Tp, class _Comp> |
|
typename multi_rbtree<_Tp, _Comp>::const_iterator |
|
multi_rbtree<_Tp, _Comp>::end() const { return const_iterator(__nil); } |
|
|
|
template<class _Tp, class _Comp> |
|
typename multi_rbtree<_Tp, _Comp>::reverse_iterator |
|
multi_rbtree<_Tp, _Comp>::rend() { return reverse_iterator(begin()); } |
|
|
|
template<class _Tp, class _Comp> |
|
typename multi_rbtree<_Tp, _Comp>::reverse_const_iterator |
|
multi_rbtree<_Tp, _Comp>::rend() const { return reverse_const_iterator(cbegin()); } |
|
|
|
template<class _Tp, class _Comp> |
|
typename multi_rbtree<_Tp, _Comp>::const_iterator |
|
multi_rbtree<_Tp, _Comp>::cbegin() const { |
|
if (empty()) return const_iterator(__nil); |
|
return const_iterator(__find_min(__root)); |
|
} |
|
|
|
template<class _Tp, class _Comp> |
|
typename multi_rbtree<_Tp, _Comp>::reverse_const_iterator |
|
multi_rbtree<_Tp, _Comp>::crbegin() const { return reverse_const_iterator(cend()); } |
|
|
|
template<class _Tp, class _Comp> |
|
typename multi_rbtree<_Tp, _Comp>::const_iterator |
|
multi_rbtree<_Tp, _Comp>::cend() const { return const_iterator(__nil); } |
|
|
|
template<class _Tp, class _Comp> |
|
typename multi_rbtree<_Tp, _Comp>::reverse_const_iterator |
|
multi_rbtree<_Tp, _Comp>::crend() const { return reverse_const_iterator(cbegin()); } |
|
|
|
template<class _Tp, class _Comp> |
|
multi_rbtree<_Tp, _Comp>::~multi_rbtree() { clear(); } |
|
|
|
#endif //COLLECTIONS_RBTREE_H |