123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709 |
- #ifndef __GBLIBCPP_BITS_RBTREE__
- #define __GBLIBCPP_BITS_RBTREE__
- #include "compressed_pair"
- #include <cstddef>
- #include <functional>
- #include <utility>
- #include <memory>
- namespace std::impl {
- template <typename T, typename Compare, typename Allocator>
- struct rbtree {
- struct node {
- node* parent;
- node* left;
- node* right;
- T value;
- enum class node_color : unsigned char { RED, BLACK, } color;
- constexpr node(const T& val)
- : parent {}, left {}, right {}
- , value { val } , color {node_color::RED} {}
- constexpr node(T&& val)
- : parent {}, left {}, right {}
- , value { std::move(val) } , color {node_color::RED} {}
- template <typename... Args, std::enable_if_t<
- (sizeof...(Args) > 1)
- || !(... && std::is_same_v<T, std::remove_cvref_t<Args>>)
- , bool> = true>
- constexpr node(Args&&... args)
- : parent {}, left {}, right {}
- , value { std::forward<Args>(args)... }, color { node_color::RED } {}
- constexpr node* grandparent(void) const
- { return this->parent->parent; }
- constexpr node* uncle(void) const
- {
- node* pp = this->grandparent();
- if (this->parent == pp->left)
- return pp->right;
- return pp->left;
- }
- constexpr node* leftmost(void)
- {
- node* nd = this;
- while (nd->left)
- nd = nd->left;
- return nd;
- }
- constexpr node* rightmost(void)
- {
- node* nd = this;
- while (nd->right)
- nd = nd->right;
- return nd;
- }
- constexpr node* next(void)
- {
- if (this->right)
- return this->right->leftmost();
- if (this->is_root())
- return nullptr;
- if (this->is_left_child())
- return this->parent;
- node* ret = this;
- do {
- ret = ret->parent;
- } while (!ret->is_root() && !ret->is_left_child());
- return ret->parent;
- }
- constexpr node* prev(void)
- {
- if (this->left)
- return this->left->rightmost();
- if (this->is_root())
- return nullptr;
- if (this->is_right_child())
- return this->parent;
- node* ret = this;
- do {
- ret = ret->parent;
- } while (!ret->is_root() && !ret->is_right_child());
- return ret->parent;
- }
- static constexpr bool is_red(node* nd)
- { return nd && nd->color == node_color::RED; }
- static constexpr bool is_black(node* nd)
- { return !node::is_red(nd); }
- constexpr bool is_root(void) const
- { return this->parent == nullptr; }
- constexpr bool is_full(void) const
- { return this->left && this->right; }
- constexpr bool has_child(void) const
- { return this->left || this->right; }
- constexpr bool is_leaf(void) const
- { return !this->has_child(); }
- constexpr bool is_left_child(void) const
- { return this == this->parent->left; }
- constexpr bool is_right_child(void) const
- { return this == this->parent->right; }
- constexpr void tored(void)
- { this->color = node_color::RED; }
- constexpr void toblack(void)
- { this->color = node_color::BLACK; }
- static constexpr void swap(node* first, node* second)
- {
- if (node::is_red(first)) {
- first->color = second->color;
- second->color = node_color::RED;
- } else {
- first->color = second->color;
- second->color = node_color::BLACK;
- }
- if (first->parent == second) {
- node* tmp = first;
- first = second;
- second = tmp;
- }
- bool f_is_left_child = first->parent ? first->is_left_child() : false;
- bool s_is_left_child = second->parent ? second->is_left_child() : false;
- node* fp = first->parent;
- node* fl = first->left;
- node* fr = first->right;
- node* sp = second->parent;
- node* sl = second->left;
- node* sr = second->right;
- if (second->parent != first) {
- first->parent = sp;
- if (sp) {
- if (s_is_left_child)
- sp->left = first;
- else
- sp->right = first;
- }
- first->left = sl;
- if (sl)
- sl->parent = first;
- first->right = sr;
- if (sr)
- sr->parent = first;
- second->parent = fp;
- if (fp) {
- if (f_is_left_child)
- fp->left = second;
- else
- fp->right = second;
- }
- second->left = fl;
- if (fl)
- fl->parent = second;
- second->right = fr;
- if (fr)
- fr->parent = second;
- } else {
- first->left = sl;
- if (sl)
- sl->parent = first;
- first->right = sr;
- if (sr)
- sr->parent = first;
- second->parent = fp;
- if (fp) {
- if (f_is_left_child)
- fp->left = second;
- else
- fp->right = second;
- }
- first->parent = second;
- if (s_is_left_child) {
- second->left = first;
- second->right = fr;
- if (fr)
- fr->parent = second;
- } else {
- second->right = first;
- second->left = fl;
- if (fl)
- fl->parent = second;
- }
- }
- }
- };
- template <bool Const>
- class _iterator {
- public:
- using node_pointer = node*;
- using value_type = std::conditional_t<Const, const T, T>;
- using pointer = std::add_pointer_t<value_type>;
- using reference = std::add_lvalue_reference_t<value_type>;
- friend rbtree;
- private:
- node_pointer p;
- public:
- constexpr _iterator() = default;
- explicit constexpr _iterator(node_pointer ptr)
- : p { ptr } {}
- constexpr _iterator(const _iterator& iter) = default;
- constexpr _iterator(_iterator&& iter) = default;
- constexpr ~_iterator() = default;
- constexpr _iterator& operator=(const _iterator& iter) = default;
- constexpr _iterator& operator=(_iterator&& iter) = default;
- constexpr bool operator==(const _iterator& iter) const = default;
- constexpr reference operator*(void) const { return p->value; }
- constexpr pointer operator&(void) const { return std::addressof(p->value); }
- constexpr pointer operator->(void) const { return this->operator&(); }
- constexpr _iterator& operator++(void)
- { p = p->next(); return *this; }
- constexpr _iterator operator++(int)
- { _iterator ret(p); (void)this->operator++(); return ret; }
- constexpr _iterator& operator--(void)
- { p = p->prev(); return *this; }
- constexpr _iterator operator--(int)
- { _iterator ret(p); (void)this->operator--(); return ret; }
- constexpr operator bool() const
- { return p; }
- constexpr operator _iterator<true>() const
- { return _iterator<true> { p }; }
- };
- using iterator = _iterator<false>;
- using const_iterator = _iterator<true>;
- using node_allocator = typename
- std::allocator_traits<Allocator>::template rebind_alloc<node>;
- using node_alloc_traits = std::allocator_traits<node_allocator>;
- compressed_pair<node*, node_allocator> root_data;
- compressed_pair<std::size_t, Compare> size_data;
- private:
- constexpr node*& _root() noexcept { return root_data.first(); }
- constexpr node* const& _root() const noexcept { return root_data.first(); }
- constexpr std::size_t& _size() noexcept { return size_data.first(); }
- constexpr const std::size_t& _size() const noexcept { return size_data.first(); }
- constexpr node_allocator& _alloc() noexcept { return root_data.second(); }
- constexpr const node_allocator& _alloc() const noexcept { return root_data.second(); }
- constexpr Compare& _comp() noexcept { return size_data.second(); }
- constexpr const Compare& _comp() const noexcept { return size_data.second(); }
- template <typename... Args>
- constexpr node* newnode(Args&&... key)
- {
- node* ptr = node_alloc_traits::allocate(_alloc(), 1);
- node_alloc_traits::construct(_alloc(), ptr, std::forward<Args>(key)...);
- return ptr;
- }
- constexpr void delnode(node* nd)
- {
- node_alloc_traits::destroy(_alloc(), nd);
- node_alloc_traits::deallocate(_alloc(), nd, 1);
- }
- constexpr void do_insertion(node* parent,
- node*& child_inserted, node* nd)
- {
- nd->parent = parent;
- child_inserted = nd;
- this->balance(nd);
- ++_size();
- }
- public:
- constexpr iterator end(void) noexcept
- { return iterator(nullptr); }
- constexpr const_iterator end(void) const noexcept
- { return const_iterator(nullptr); }
- constexpr const_iterator cend(void) const noexcept
- { return const_iterator(nullptr); }
- constexpr iterator begin(void) noexcept
- { return _root() ? iterator(_root()->leftmost()) : end(); }
- constexpr const_iterator begin(void) const noexcept
- { return _root() ? const_iterator(_root()->leftmost()) : end(); }
- constexpr const_iterator cbegin(void) const noexcept
- { return _root() ? const_iterator(_root()->leftmost()) : end(); }
- constexpr void destroy(node* nd)
- {
- if (!nd)
- return;
- destroy(nd->left);
- destroy(nd->right);
- delnode(nd);
- }
- constexpr void destroy() { destroy(_root()); _root() = nullptr; _size() = 0; }
- constexpr node* copy(node* nd)
- {
- if (!nd)
- return nullptr;
- node* newnd = newnode(nd->value);
- newnd->color = nd->color;
- ++_size();
- newnd->left = copy(nd->left);
- if (newnd->left)
- newnd->left->parent = newnd;
- newnd->right = copy(nd->right);
- if (newnd->right)
- newnd->right->parent = newnd;
- return newnd;
- }
- explicit constexpr rbtree(const Compare& comp, const node_allocator& alloc)
- : root_data{nullptr, alloc}, size_data{0, comp} { }
- constexpr rbtree(const rbtree& other)
- : rbtree(other._comp(), other._alloc())
- {
- _root() = copy(other._root());
- if (_root())
- _root()->parent = nullptr;
- }
- constexpr rbtree(const rbtree& other, const node_allocator& alloc)
- : rbtree(other._comp(), alloc)
- {
- _root() = copy(other._root());
- if (_root())
- _root()->parent = nullptr;
- }
- constexpr rbtree(rbtree&& other) noexcept
- : root_data{std::exchange(other._root(), nullptr), std::move(other._alloc())}
- , size_data{std::exchange(other._size(), 0), std::move(other._comp())} { }
- constexpr rbtree(rbtree&& other, const node_allocator& alloc) noexcept
- : root_data{std::exchange(other._root(), nullptr), alloc}
- , size_data{std::exchange(other._size(), 0), std::move(other._comp())} { }
- constexpr ~rbtree() { destroy(); }
- constexpr rbtree& operator=(const rbtree& other)
- {
- destroy(_root());
- _comp() = other._comp();
- if constexpr (node_alloc_traits::
- propagate_on_container_copy_assignment::value)
- _alloc() = other._alloc();
- _root() = copy(other._root());
- if (_root())
- _root()->parent = nullptr;
- return *this;
- }
- constexpr rbtree& operator=(rbtree&& other) noexcept
- {
- destroy(_root());
- _root() = std::exchange(other._root(), nullptr);
- _size() = std::exchange(other._size(), 0);
- _comp() = std::move(other._comp());
- if constexpr (node_alloc_traits::
- propagate_on_container_move_assignment::value)
- _alloc() = std::move(other._alloc());
- return *this;
- }
- constexpr void rotateleft(node* rt)
- {
- node* nrt = rt->right;
- if (!rt->is_root()) {
- if (rt->is_left_child())
- rt->parent->left = nrt;
- else
- rt->parent->right = nrt;
- } else {
- _root() = nrt;
- }
- nrt->parent = rt->parent;
- rt->parent = nrt;
- rt->right = nrt->left;
- if (rt->right)
- rt->right->parent = rt;
- nrt->left = rt;
- }
- constexpr void rotateright(node* rt)
- {
- node* nrt = rt->left;
- if (!rt->is_root()) {
- if (rt->is_left_child())
- rt->parent->left = nrt;
- else
- rt->parent->right = nrt;
- } else {
- _root() = nrt;
- }
- nrt->parent = rt->parent;
- rt->parent = nrt;
- rt->left = nrt->right;
- if (rt->left)
- rt->left->parent = rt;
- nrt->right = rt;
- }
- constexpr void balance(node* nd)
- {
- if (nd->is_root()) {
- nd->toblack();
- return;
- }
- if (node::is_black(nd->parent))
- return;
- node* p = nd->parent;
- node* pp = nd->grandparent();
- node* uncle = nd->uncle();
- if (node::is_red(uncle)) {
- p->toblack();
- uncle->toblack();
- pp->tored();
- this->balance(pp);
- return;
- }
- if (p->is_left_child()) {
- if (nd->is_left_child()) {
- p->toblack();
- pp->tored();
- this->rotateright(pp);
- } else {
- this->rotateleft(p);
- this->balance(p);
- }
- } else {
- if (nd->is_right_child()) {
- p->toblack();
- pp->tored();
- this->rotateleft(pp);
- } else {
- this->rotateright(p);
- this->balance(p);
- }
- }
- }
- template <typename U>
- constexpr node* _find(const U& key) const
- {
- for (node* cur = _root(); cur; ) {
- if (_comp()(key, cur->value))
- cur = cur->left;
- else if (_comp()(cur->value, key))
- cur = cur->right;
- else
- return cur;
- }
- return nullptr;
- }
- template <typename U>
- constexpr iterator find(const U& key) const
- { return iterator { _find(key) }; }
- // RBTREE RECURSIVE DELETE
- // THIS FUNCTION DOES NOT DELLOCATE THE NODE
- // CALLER IS RESPONSIBLE FOR FREEING THE MEMORY
- // @param: nd is guaranteed to be a leaf node
- constexpr void _erase(node* nd)
- {
- if (nd->is_root())
- return;
- if (node::is_black(nd)) {
- node* p = nd->parent;
- node* s = nullptr;
- if (nd->is_left_child())
- s = p->right;
- else
- s = p->left;
- if (node::is_red(s)) {
- p->tored();
- s->toblack();
- if (nd->is_right_child()) {
- this->rotateright(p);
- s = p->left;
- } else {
- this->rotateleft(p);
- s = p->right;
- }
- }
- node* r = nullptr;
- if (node::is_red(s->left)) {
- r = s->left;
- if (s->is_left_child()) {
- r->toblack();
- s->color = p->color;
- this->rotateright(p);
- p->toblack();
- } else {
- r->color = p->color;
- this->rotateright(s);
- this->rotateleft(p);
- p->toblack();
- }
- } else if (node::is_red(s->right)) {
- r = s->right;
- if (s->is_left_child()) {
- r->color = p->color;
- this->rotateleft(s);
- this->rotateright(p);
- p->toblack();
- } else {
- r->toblack();
- s->color = p->color;
- this->rotateleft(p);
- p->toblack();
- }
- } else {
- s->tored();
- if (node::is_black(p))
- this->_erase(p);
- else
- p->toblack();
- }
- }
- }
- // delete nd from the tree. make nd safe to deallocate
- // THIS FUNCTION DOES NOT DELLOCATE THE NODE
- // CALLER IS RESPONSIBLE FOR FREEING THE MEMORY
- constexpr node* erase(node* nd)
- {
- if (nd->is_root() && nd->is_leaf()) {
- _root() = nullptr;
- return nullptr;
- }
- node* next = nd->next();
- while (!nd->is_leaf()) {
- node* alt = nd->right ? nd->right->leftmost() : nd->left;
- if (nd->is_root())
- _root() = alt;
- node::swap(nd, alt);
- }
- this->_erase(nd);
- if (nd->is_left_child())
- nd->parent->left = nullptr;
- else
- nd->parent->right = nullptr;
- return next;
- }
- constexpr iterator erase(iterator pos) noexcept
- {
- node* nextpos = erase(pos.p);
- delnode(pos.p);
- --_size();
- return iterator { nextpos };
- }
- constexpr iterator erase(const_iterator pos) noexcept
- {
- node* nextpos = erase(pos.p);
- delnode(pos.p);
- --_size();
- return iterator { nextpos };
- }
- template <typename U>
- constexpr iterator lower_bound(U&& val) const
- {
- node* cur = _root();
- node* result = nullptr;
- while (cur) {
- if (!_comp()(cur->value, val)) {
- result = cur;
- cur = cur->left;
- }
- else {
- cur = cur->right;
- }
- }
- return iterator { result };
- }
- template <typename U>
- constexpr iterator upper_bound(U&& val) const
- {
- iterator iter = lower_bound(std::forward<U>(val));
- if (iter && !_comp()(*iter, val) && !_comp()(val, *iter))
- return ++iter;
- return iter;
- }
- // value in nd MUST NOT exist in the rbtree,
- // that is, if a < b, then a > b
- constexpr void insert(node* nd)
- {
- node* cur = _root();
- while (cur) {
- if (_comp()(nd->value, cur->value)) {
- if (!cur->left) {
- do_insertion(cur, cur->left, nd);
- return;
- }
- cur = cur->left;
- } else {
- if (!cur->right) {
- do_insertion(cur, cur->right, nd);
- return;
- }
- cur = cur->right;
- }
- }
- do_insertion(cur, _root(), nd);
- }
- template <typename U>
- constexpr std::pair<iterator, bool> insert(U&& value)
- {
- auto iter = find(value);
- if (iter)
- return { iter, false };
- node* ptr = newnode(std::forward<U>(value));
- insert(ptr);
- return { iterator { ptr }, true };
- }
- template <typename... Args>
- constexpr std::pair<iterator, bool> emplace(Args&&... args)
- {
- node* nd = newnode(std::forward<Args>(args)...);
- node* exist_nd = _find(nd->value);
- if (exist_nd) {
- delnode(nd);
- return { iterator { exist_nd }, false };
- }
- insert(nd);
- return { iterator { nd }, true };
- }
- constexpr bool empty() const noexcept { return !_root(); }
- constexpr std::size_t size() const noexcept { return _size(); }
- constexpr void swap(rbtree& other)
- {
- std::swap(_root(), other._root());
- std::swap(_size(), other._size());
- std::swap(_comp(), other._comp());
- if constexpr (node_alloc_traits::propagate_on_container_swap::value)
- std::swap(_alloc(), other._alloc());
- }
- };
- } // namespace std::impl
- #endif
|