Implement the avl tree, rbtree without the two fields: parent pointer and balance/color

来源:互联网 发布:阿里云ecs 80端口 编辑:程序博客网 时间:2024/05/16 05:14
#ifndef GYM_BINARY_SEARCH_TREE_COMMON_H_6D4EBDB0_5B18_4FC1_A34A_CBBF36FE95E4#define GYM_BINARY_SEARCH_TREE_COMMON_H_6D4EBDB0_5B18_4FC1_A34A_CBBF36FE95E4#include <stdint.h>#include <assert.h>#include <boost/call_traits.hpp>#include <vector>#include <stack>#include <queue>namespace pratique{    namespace details    {        enum child_position        {            left_child = 0,            right_child = 1,            child_position_limit = 2        };        enum search_result        {            empty_tree = 1,            found_node = 2,            should_insert_as_left = 4,            should_insert_as_right = 8        };        template <typename TreeNodeIndicator>        size_t height( TreeNodeIndicator root )        {            size_t h = 0;            if ( root.is_non_null( ) ) {                size_t lh = height<TreeNodeIndicator>( root.get_pointer( )->m_left ), rh = height<TreeNodeIndicator>( root.get_pointer( )->m_right );                h = ( lh < rh ? rh : lh ) + 1;            }            return h;        }        template <typename TreeNodeIndicator>        bool has_filiation(            TreeNodeIndicator parent,            TreeNodeIndicator child        )        {            return parent.get_pointer( )->m_left == child || parent.get_pointer( )->m_right == child;        }        template <typename TreeNodeIndicator>        TreeNodeIndicator * get_minimum_child(            TreeNodeIndicator * parent,            std::vector<TreeNodeIndicator *> & ancestors        )        {            assert( parent != NULL && parent->is_non_null( ) && parent->get_pointer( )->m_right.is_non_null( ) );            ancestors.push_back( parent );            TreeNodeIndicator * minimum_child = &parent->get_pointer( )->m_right;            while ( minimum_child->get_pointer( )->m_left.is_non_null( ) ) {                ancestors.push_back( minimum_child );                minimum_child = &minimum_child->get_pointer( )->m_left;            }            return minimum_child;        }        template <typename TreeNodeIndicator>        TreeNodeIndicator * get_other_child(            TreeNodeIndicator parent,            TreeNodeIndicator child        )        {            TreeNodeIndicator * another_child = &parent.get_pointer( )->m_left;            if ( *another_child == child ) {                another_child = &parent.get_pointer( )->m_right;            }            return another_child;        }        template <typename TreeNodeIndicator>        TreeNodeIndicator * get_other_child(            TreeNodeIndicator parent,            child_position this_child_position        )        {            return this_child_position == left_child ? &parent.get_pointer( )->m_right : &parent.get_pointer( )->m_left;        }        template <typename TreeNodeIndicator>        child_position get_child_position(            TreeNodeIndicator parent,            TreeNodeIndicator child        )        {            child_position cp = left_child;            if ( parent.get_pointer( )->m_right == child ) {                cp = right_child;            }            return cp;        }        template <typename TreeNodeIndicator>        bool in_the_same_branch(            TreeNodeIndicator grandparent,            TreeNodeIndicator parent,            TreeNodeIndicator child        )        {            return (                ( grandparent.get_pointer( )->m_left == parent && parent.get_pointer( )->m_left == child ) ||                ( grandparent.get_pointer( )->m_right == parent && parent.get_pointer( )->m_right == child )            );        }        template <typename TreeNodeIndicator>        TreeNodeIndicator * pop_without_doubt(            std::stack<TreeNodeIndicator *> & ancestors        )        {            assert( !ancestors.empty( ) );            TreeNodeIndicator * parent = ancestors.top( );            ancestors.pop( );            return parent;        }        template <typename TreeNodeIndicator>        TreeNodeIndicator * pop(            std::stack<TreeNodeIndicator *> & ancestors        )        {            TreeNodeIndicator * parent = NULL;            if ( !ancestors.empty( ) ) {                parent = pop_without_doubt( ancestors );            }            return parent;        }        template <typename T, typename TreeNodeIndicator>        search_result find(            TreeNodeIndicator const * const root,            typename boost::call_traits<T>::param_type t,            std::stack<TreeNodeIndicator *> * ancestors,            TreeNodeIndicator ** n        )        {            search_result sr = empty_tree;            if ( n != NULL && *n != NULL ) {                ( *n )->pointer = NULL;            }            TreeNodeIndicator * node = const_cast<TreeNodeIndicator *>( root );            if ( node->is_non_null( ) ) {                if ( !node->value_equals( t ) ) {                    for (                        TreeNodeIndicator * p = node, *c = p;                        c->is_non_null( );                        ancestors != NULL ? ( ancestors->push( p ), 0 ) : 0                    ) {                        p = c;                        if ( c->value( ) > t ) {                            c = &p->get_pointer( )->m_left;                            sr = should_insert_as_left;                        } else if ( c->value( ) < t ) {                            c = &p->get_pointer( )->m_right;                            sr = should_insert_as_right;                        } else {                            if ( n != NULL ) {                                *n = c;                            }                            sr = found_node;                            break;                        }                    }                } else {                    if ( n != NULL ) {                        *n = node;                    }                    sr = found_node;                }            }            return sr;        }        template <typename TreeNodeIndicator, typename Visitor>        void levelorder_visit( TreeNodeIndicator const root, Visitor visitor )        {            TreeNodeIndicator dummy;            if ( root.is_non_null( ) ) {                std::queue<TreeNodeIndicator const> q1, q2, *pq1 = &q1, *pq2 = &q2;                q1.push( root );                visitor( dummy );                while ( !pq1->empty( ) ) {                    while ( !pq1->empty( ) ) {                        TreeNodeIndicator n = pq1->front( );                        visitor( n );                        pq1->pop( );                        if ( n.get_pointer( )->m_left.is_non_null( ) ) {                            pq2->push( n.get_pointer( )->m_left );                        }                        if ( n.get_pointer( )->m_right.is_non_null( ) ) {                            pq2->push( n.get_pointer( )->m_right );                        }                    }                    visitor( dummy );                    std::swap( pq1, pq2 );                }            }        }    }}#endif //GYM_BINARY_SEARCH_TREE_COMMON_H_6D4EBDB0_5B18_4FC1_A34A_CBBF36FE95E4



#ifndef GYM_AVL_TREE_H_6D4EBDB0_5B18_4FC1_A34A_CBBF36FE95E4#define GYM_AVL_TREE_H_6D4EBDB0_5B18_4FC1_A34A_CBBF36FE95E4#include "bst_common.h"#include <algorithm>namespace pratique{    namespace details    {        template <typename T>        struct avl_tree_node        {            typedef union child {                avl_tree_node<T> * pointer;                intptr_t           int_value;                child( avl_tree_node<T> * p = NULL, int balance = 0 ) : pointer( p )                {                    set_balance( balance );                }                bool is_null() const { return pointer == NULL; }                bool is_non_null() const { return int_value > 1; }                int get_balance() const                {                    int balance = int_value & 3;                    assert( balance <= 2 );                    if ( balance == 2 ) {                        balance = -1;                    }                    return balance;                }                void set_balance( int balance )                {                    assert( balance >= -1 && balance <= 1 );                    if ( balance == -1 ) {                        balance = 2;                    }                    int_value &= (~3);                    int_value |= balance;                #if ( defined( DEBUG ) || defined( _DEBUG ) || defined( DBG ) )                    if ( is_null() ) {                        assert(balance == 0);                    }                #endif                }                avl_tree_node<T> const * get_pointer() const                {                    return const_cast<avl_tree_node<T> const *>(                        reinterpret_cast<avl_tree_node<T> *>( int_value & (~3) )                    );                }                avl_tree_node<T> * get_pointer()                {                    return reinterpret_cast<avl_tree_node<T> *>( int_value & (~3) );                }                bool value_equals( typename boost::call_traits<T>::param_type t ) const                {                    return is_non_null() && ( get_pointer()->m_data == t );                }                T const & value() const { assert( is_non_null() ); return get_pointer()->m_data; }                T & value() { assert( is_non_null() ); return get_pointer()->m_data; }                bool operator==( typename boost::call_traits<child>::param_type c ) const                {                    return int_value == c.int_value;                }                bool operator!=( typename boost::call_traits<child>::param_type c ) const                {                    return int_value != c.int_value;                }            } child_t;            struct hash            {                size_t operator()( child_t const c ) const                {                    return std::hash<intptr_t>()( c.int_value );                }            };            T m_data;            child_t m_left, m_right;            avl_tree_node() : m_left{ NULL, false }, m_right{ NULL, false } {}            avl_tree_node( typename boost::call_traits<T>::param_type t ) : m_data{ t }, m_left{ NULL, false }, m_right{ NULL, false } {}        };        template <typename T>        bool check_balance_attributes( typename avl_tree_node<T>::child_t const root )        {            bool passed = true;            if ( root.is_non_null( ) ) {                auto left = root.get_pointer( )->m_left, right = root.get_pointer( )->m_right;                int diff = static_cast<int>( height( left ) ) - static_cast<int>( height( right ) );                passed = ( diff >= -1 && diff <= 1 ) && ( root.get_balance( ) == diff );                if ( passed ) {                    passed = check_balance_attributes<T>( left ) && check_balance_attributes<T>( right );                }            }            return passed;        }        template <typename T>        bool is_avl_tree( typename avl_tree_node<T>::child_t const root )        {            return check_balance_attributes<T>( root );        }    }    template <typename T>    class avl_tree    {        typename details::avl_tree_node<T>::child_t m_root;        inline typename details::avl_tree_node<T>::child_t * reset_parent(            typename details::avl_tree_node<T>::child_t * grandparent,            typename details::avl_tree_node<T>::child_t new_parent,            details::child_position pcp        ) {            typename details::avl_tree_node<T>::child_t * pointer_to_new_parent = NULL;            if ( grandparent != NULL ) {                if ( pcp == details::left_child ) {                    grandparent->get_pointer()->m_left = new_parent;                    pointer_to_new_parent = &grandparent->get_pointer()->m_left;                } else {                    grandparent->get_pointer()->m_right = new_parent;                    pointer_to_new_parent = &grandparent->get_pointer()->m_right;                }            } else {                m_root = new_parent;                pointer_to_new_parent = &m_root;            }            return pointer_to_new_parent;        }        inline typename details::avl_tree_node<T>::child_t * left_rotate(            typename details::avl_tree_node<T>::child_t * grandparent,            typename details::avl_tree_node<T>::child_t parent,            typename details::avl_tree_node<T>::child_t child,            int parent_balance = 0,            int child_balance = 0        )        {            assert( grandparent == NULL || details::has_filiation( *grandparent, parent ) );            assert( details::has_filiation( parent, child ) );            details::child_position pcp = details::left_child;            if ( grandparent != NULL ) {                pcp = details::get_child_position( *grandparent, parent );            }            parent.set_balance( parent_balance );            child.set_balance( child_balance );            parent.get_pointer()->m_left = child.get_pointer()->m_right;            child.get_pointer()->m_right = parent;            return reset_parent( grandparent, child, pcp );        }        inline typename details::avl_tree_node<T>::child_t * right_rotate(            typename details::avl_tree_node<T>::child_t * grandparent,            typename details::avl_tree_node<T>::child_t parent,            typename details::avl_tree_node<T>::child_t child,            int parent_balance = 0,            int child_balance = 0        )        {            assert( grandparent == NULL || details::has_filiation( *grandparent, parent ) );            assert( details::has_filiation( parent, child ) );            details::child_position pcp = details::left_child;            if ( grandparent != NULL ) {                pcp = details::get_child_position( *grandparent, parent );            }            parent.set_balance( parent_balance );            child.set_balance( child_balance );            parent.get_pointer()->m_right = child.get_pointer()->m_left;            child.get_pointer()->m_left = parent;            return reset_parent( grandparent, child, pcp );        }        inline typename details::avl_tree_node<T>::child_t * left_rotate(            typename details::avl_tree_node<T>::child_t * new_grandparent,            typename details::avl_tree_node<T>::child_t grandparent,            typename details::avl_tree_node<T>::child_t parent,            typename details::avl_tree_node<T>::child_t child        )        {            int child_balance = child.get_balance();            assert( new_grandparent == NULL || details::has_filiation( *new_grandparent, grandparent ) );            assert( details::has_filiation( grandparent, parent ) );            assert( details::has_filiation( parent, child ) );            details::child_position gcp = details::left_child;            if ( new_grandparent != NULL ) {                gcp = details::get_child_position( *new_grandparent, grandparent );            }            if ( child_balance == -1 ) {                grandparent.set_balance( 0 );                parent.set_balance( 1 );            }            else if ( child_balance == 1 ) {                grandparent.set_balance( -1 );                parent.set_balance( 0 );            }            else {                grandparent.set_balance( 0 );                parent.set_balance( 0 );            }            child.set_balance( 0 );            parent.get_pointer()->m_right = child.get_pointer()->m_left;            child.get_pointer()->m_left = parent;            grandparent.get_pointer()->m_left = child.get_pointer()->m_right;            child.get_pointer()->m_right = grandparent;            return reset_parent( new_grandparent, child, gcp );        }        inline typename details::avl_tree_node<T>::child_t * right_rotate(            typename details::avl_tree_node<T>::child_t * new_grandparent,            typename details::avl_tree_node<T>::child_t grandparent,            typename details::avl_tree_node<T>::child_t parent,            typename details::avl_tree_node<T>::child_t child        )        {            int child_balance = child.get_balance();            assert( new_grandparent == NULL || details::has_filiation( *new_grandparent, grandparent ) );            assert( details::has_filiation( grandparent, parent ) );            assert( details::has_filiation( parent, child ) );            details::child_position gcp = details::left_child;            if ( new_grandparent != NULL ) {                gcp = details::get_child_position( *new_grandparent, grandparent );            }            if ( child_balance == -1 ) {                grandparent.set_balance( 1 );                parent.set_balance( 0 );            }            else if ( child_balance == 1 ) {                grandparent.set_balance( 0 );                parent.set_balance( -1 );            }            else {                grandparent.set_balance( 0 );                parent.set_balance( 0 );            }            child.set_balance( 0 );            parent.get_pointer()->m_left = child.get_pointer()->m_right;            child.get_pointer()->m_right = parent;            grandparent.get_pointer()->m_right = child.get_pointer()->m_left;            child.get_pointer()->m_left = grandparent;            return reset_parent( new_grandparent, child, gcp );        }        void insertion_rebalance(            typename details::avl_tree_node<T>::child_t * child,            std::stack<typename details::avl_tree_node<T>::child_t *> & ancestors        )        {            assert( child != NULL && child->is_non_null() && !ancestors.empty() );            for (                typename details::avl_tree_node<T>::child_t * parent = details::pop_without_doubt( ancestors );                parent != NULL;                parent = details::pop( ancestors )            ) {                assert( details::has_filiation( *parent, *child ) );                details::child_position ccp = details::get_child_position( *parent, *child );                int parent_balance = parent->get_balance();                assert( parent_balance >= -1 && parent_balance <= 1 );                if ( ccp == details::left_child ) {                    if ( parent_balance == -1 ) {                        parent->set_balance( 0 );                        break;                    }                    else if ( parent_balance == 0 ) {                        parent->set_balance( 1 );                        child = parent;                    }                    else {                        assert( parent_balance == 1 );                        typename details::avl_tree_node<T>::child_t * grandparent = NULL;                        if ( !ancestors.empty() ) {                            grandparent = ancestors.top();                            assert( details::has_filiation( *grandparent, *parent ) );                        }                        int child_balance = child->get_balance();                        if ( child_balance == -1 ) {                            left_rotate( grandparent, *parent, *child, child->get_pointer()->m_right );                            break;                        }                        else if ( child_balance == 0 ) {                            child = left_rotate( grandparent, *parent, *child, 1, -1 );                        }                        else {                            assert( child_balance == 1 );                            left_rotate( grandparent, *parent, *child );                            break;                        }                    }                }                else {                    if ( parent_balance == -1 ) {                        typename details::avl_tree_node<T>::child_t * grandparent = NULL;                        if ( !ancestors.empty() ) {                            grandparent = ancestors.top();                            assert( details::has_filiation( *grandparent, *parent ) );                        }                        int child_balance = child->get_balance();                        if ( child_balance == -1 ) {                            right_rotate( grandparent, *parent, *child );                            break;                        }                        else if ( child_balance == 0 ) {                            child = right_rotate( grandparent, *parent, *child, -1, 1 );                        }                        else {                            assert( child_balance == 1 );                            right_rotate( grandparent, *parent, *child, child->get_pointer()->m_left );                            break;                        }                    }                    else if ( parent_balance == 0 ) {                        parent->set_balance( -1 );                        child = parent;                    }                    else {                        parent->set_balance( 0 );                        break;                    }                }            }        }        typename details::avl_tree_node<T>::child_t * transplant(            typename details::avl_tree_node<T>::child_t expellee_parent,            typename details::avl_tree_node<T>::child_t expellee,            typename details::avl_tree_node<T>::child_t replacer        )        {            assert( details::has_filiation( expellee_parent, expellee ) );            assert( !expellee.is_null() );            if ( !replacer.is_null() ) {                if ( !details::has_filiation( expellee, replacer ) ) {                    replacer.get_pointer()->m_left  = expellee.get_pointer()->m_left;                    replacer.get_pointer()->m_right = expellee.get_pointer()->m_right;                    replacer.set_balance( expellee.get_balance() );                }                else {                    if ( expellee.get_pointer()->m_left == replacer ) {                        replacer.get_pointer()->m_right = expellee.get_pointer()->m_right;                        assert( replacer.get_pointer()->m_left.is_null() );                        replacer.set_balance( expellee.get_balance() - 1 );                    }                    else {                        replacer.get_pointer()->m_left = expellee.get_pointer()->m_left;                        assert( replacer.get_pointer()->m_right.is_null() );                        replacer.set_balance( expellee.get_balance() + 1 );                    }                }            }            typename details::avl_tree_node<T>::child_t * new_child;            auto ecp = details::get_child_position( expellee_parent, expellee );            if ( ecp == details::left_child ) {                expellee_parent.get_pointer()->m_left = replacer;                new_child = &expellee_parent.get_pointer()->m_left;            }            else {                expellee_parent.get_pointer()->m_right = replacer;                new_child = &expellee_parent.get_pointer()->m_right;            }            if ( m_root == expellee ) {                m_root = *new_child;            }            return new_child;        }        void erasing_rebalance(            typename details::avl_tree_node<T>::child_t * replacement,            details::child_position rcp,            std::stack<typename details::avl_tree_node<T>::child_t *> & ancestors        )        {            while ( !ancestors.empty() ) {                typename details::avl_tree_node<T>::child_t * parent = details::pop_without_doubt( ancestors ), * grandparent = NULL;                assert( details::has_filiation( *parent, *replacement ) );                details::child_position pcp = details::left_child;                if ( !ancestors.empty() ) {                    grandparent = ancestors.top();                    pcp = details::get_child_position( *grandparent, *parent );                    parent = &grandparent->get_pointer()->m_left;                    if ( pcp == details::right_child ) {                        parent = &grandparent->get_pointer()->m_right;                    }                }                else {                    parent = &m_root;                }                int parent_balance = parent->get_balance();                assert( parent_balance >= -1 && parent_balance <= 1 );                if ( rcp == details::left_child ) {                    if ( parent_balance == -1 ) {                        typename details::avl_tree_node<T>::child_t * sibling = details::get_other_child( *parent, rcp );                        int sibling_balance = sibling->get_balance();                        if ( sibling_balance == -1 ) {                            right_rotate( grandparent, *parent, *sibling );                        }                        else if ( sibling_balance == 0 ) {                            right_rotate( grandparent, *parent, *sibling, -1, 1 );                            break;                        }                        else {                            assert( sibling_balance == 1 );                            right_rotate( grandparent, *parent, *sibling, sibling->get_pointer()->m_left );                        }                        if ( grandparent != NULL ) {                            rcp = details::left_child;                            replacement = &grandparent->get_pointer()->m_left;                            if ( pcp == details::right_child ) {                                rcp = details::right_child;                                replacement = &grandparent->get_pointer()->m_right;                            }                        }                    }                    else if ( parent_balance == 0 ) {                        parent->set_balance( -1 );                        break;                    }                    else {                        assert( parent_balance == 1 );                        parent->set_balance( 0 );                        replacement = parent;                        if ( !ancestors.empty() ) {                            rcp = details::get_child_position( *ancestors.top(), *replacement );                        }                    }                }                else {                    if ( parent_balance == -1 ) {                        parent->set_balance( 0 );                        replacement = parent;                        if ( !ancestors.empty() ) {                            rcp = details::get_child_position( *ancestors.top(), *replacement );                        }                    }                    else if ( parent_balance == 0 ) {                        parent->set_balance( 1 );                        break;                    }                    else {                        assert( parent_balance == 1 );                        typename details::avl_tree_node<T>::child_t * sibling = details::get_other_child( *parent, rcp );                        int sibling_balance = sibling->get_balance();                        if ( sibling_balance == -1 ) {                            left_rotate( grandparent, *parent, *sibling, sibling->get_pointer()->m_right );                        }                        else if ( sibling_balance == 0 ) {                            left_rotate( grandparent, *parent, *sibling, 1, -1 );                            break;                        }                        else {                            assert( sibling_balance == 1 );                            left_rotate( grandparent, *parent, *sibling );                        }                        if ( grandparent != NULL ) {                            rcp = details::left_child;                            replacement = &grandparent->get_pointer()->m_left;                            if ( pcp == details::right_child ) {                                rcp = details::right_child;                                replacement = &grandparent->get_pointer()->m_right;                            }                        }                    }                }            }        }    public:        avl_tree() {}        avl_tree( avl_tree<T> const & );        avl_tree<T> & operator=( avl_tree<T> const & );        void insert( typename boost::call_traits<T>::param_type t )        {            assert( details::is_avl_tree<T>( m_root ) );            std::stack<typename details::avl_tree_node<T>::child_t *> ancestors;            typename details::avl_tree_node<T>::child_t * child = NULL;            details::search_result sr = details::find<T>( &m_root, t, &ancestors, &child );            if ( ( sr & ( details::empty_tree | details::should_insert_as_left | details::should_insert_as_right ) ) != 0 ) {                details::avl_tree_node<T> * new_node = new details::avl_tree_node<T>( t );                switch ( sr ) {                case details::empty_tree:                    assert( m_root.is_null() );                    m_root.pointer = new_node;                    return;                case details::should_insert_as_left:                    ancestors.top()->get_pointer()->m_left.pointer = new_node;                    child = &ancestors.top()->get_pointer()->m_left;                    break;                case details::should_insert_as_right:                    ancestors.top()->get_pointer()->m_right.pointer = new_node;                    child = &ancestors.top()->get_pointer()->m_right;                    break;                default:                    assert( false && "bug" );                }                insertion_rebalance( child, ancestors );                assert( details::is_avl_tree<T>( m_root ) );            }        }        void erase( typename boost::call_traits<T>::param_type t )        {            assert( details::is_avl_tree<T>( m_root ) );            std::stack<typename details::avl_tree_node<T>::child_t *> ancestors;            details::avl_tree_node<T> dummy_node;            typename details::avl_tree_node<T>::child_t * expellee = NULL, dummy;            auto result = details::find<T>( &m_root, t, &ancestors, &expellee );            if ( result == details::found_node ) {                details::child_position rcp;                typename details::avl_tree_node<T>::child_t expellee_ref;                typename details::avl_tree_node<T>::child_t * expellee_parent = NULL;                if ( !ancestors.empty() ) {                    expellee_parent = ancestors.top();                }                if ( expellee_parent == NULL ) {                    assert( m_root == *expellee );                    dummy_node.m_left = m_root;                    dummy.pointer = &dummy_node;                    expellee_parent = &dummy;                }                expellee_ref = *expellee;                assert( expellee != NULL && expellee->is_non_null() );                typename details::avl_tree_node<T>::child_t * replacement;                if ( expellee->get_pointer()->m_right.is_non_null() ) {                    std::vector<typename details::avl_tree_node<T>::child_t *> new_ancestors;                    replacement = details::get_minimum_child( expellee, new_ancestors );                    assert( replacement != NULL && replacement->is_non_null() );                    assert( !new_ancestors.empty() );                    assert( details::height( *replacement ) <= 2 );                    auto replacement_ref = *replacement;                    auto expellee_ref = *expellee;                    rcp = details::get_child_position( *new_ancestors.back(), replacement_ref );                    replacement = transplant( *new_ancestors.back(), replacement_ref, replacement_ref.get_pointer()->m_right );                    expellee = transplant( *expellee_parent, expellee_ref, replacement_ref );                    ancestors.push( expellee );                    std::for_each(                        new_ancestors.begin() + 1, new_ancestors.end(),                        [ &ancestors ]( typename details::avl_tree_node<T>::child_t * node ) { ancestors.push( node ); }                    );                } else {                    assert( details::height( *expellee ) <= 2 );                    rcp = details::get_child_position( *expellee_parent, *expellee );                    replacement = transplant( *expellee_parent, *expellee, expellee->get_pointer()->m_left );                }                erasing_rebalance( replacement, rcp, ancestors );                delete expellee_ref.get_pointer();                assert( details::is_avl_tree<T>( m_root ) );            }        }        template <typename Visitor>        void levelorder_visit( Visitor visitor ) const        {            details::levelorder_visit( m_root, visitor );        }        bool is_valid( ) const { return details::is_avl_tree<T>( m_root ); }    };}#endif //GYM_AVL_TREE_H_6D4EBDB0_5B18_4FC1_A34A_CBBF36FE95E4


#ifndef GYM_RED_BLACK_TREE_H_6D4EBDB0_5B18_4FC1_A34A_CBBF36FE95E4#define GYM_RED_BLACK_TREE_H_6D4EBDB0_5B18_4FC1_A34A_CBBF36FE95E4#include "bst_common.h"#include <algorithm>#include <unordered_map>namespace pratique{    namespace details    {        template <typename T>        struct rbtree_node        {            typedef union child {                rbtree_node<T> * pointer;                intptr_t         int_value;                child( rbtree_node<T> * p = NULL, bool red = false ) : pointer( p )                {                    if ( red ) {                        set_red();                    }                }                bool is_null() const { return pointer == NULL; }                bool is_non_null() const { return int_value > 1; }                bool is_red() const { assert( is_non_null() ); return ( int_value & 1 ) != 0; }                bool is_black() const { return ( int_value & 1 ) == 0; }                void set_red() { assert( is_non_null() ); int_value |= 1; }                void set_black() { int_value &= ~1; }                void set_color( bool red )                {                    if ( red ) { set_red(); } else { set_black(); }                }                rbtree_node<T> const * get_pointer() const                {                    rbtree_node<T> const * p = pointer;                    if ( is_red() ) {                        p = reinterpret_cast<rbtree_node<T> const *>( int_value & ~1 );                    }                    return p;                }                rbtree_node<T> * get_pointer()                {                    rbtree_node<T> * p = pointer;                    if ( is_red() ) {                        p = reinterpret_cast<rbtree_node<T> *>( int_value & ~1 );                    }                    return p;                }                bool value_equals( typename boost::call_traits<T>::param_type t ) const                {                    return is_non_null() && ( get_pointer()->m_data == t );                }                T const & value() const { assert( is_non_null() ); return get_pointer()->m_data; }                T & value() { assert( is_non_null() ); return get_pointer()->m_data; }                bool operator==( typename boost::call_traits<child>::param_type c ) const                {                    return int_value == c.int_value;                }                bool operator!=( typename boost::call_traits<child>::param_type c ) const                {                    return int_value != c.int_value;                }            } child_t;            struct hash            {                size_t operator()( child_t const c ) const                {                    return std::hash<intptr_t>()( c.int_value );                }            };            T m_data;            child_t m_left, m_right;            rbtree_node() : m_left{ NULL, false }, m_right{ NULL, false } {}            rbtree_node( typename boost::call_traits<T>::param_type t ) : m_data{ t }, m_left{ NULL, false }, m_right{ NULL, false } {}        };        template <typename T>        bool check_red_black_attributes( typename rbtree_node<T>::child_t const root )        {            bool passed = true;            if ( root.is_non_null() ) {                auto left = root.get_pointer()->m_left, right = root.get_pointer()->m_right;                if ( root.is_red() ) {                    passed = left.is_black() && right.is_black();                }                if ( passed ) {                    passed = check_red_black_attributes<T>( left ) && check_red_black_attributes<T>( right );                }            }            return passed;        }        template <typename T>        bool compute_black_height(            int starting_height,            typename rbtree_node<T>::child_t const node,            int & ending_height        )        {            bool successful = true;            ending_height = starting_height;            if ( node.is_non_null() ) {                if ( node.is_black() ) {                    ++starting_height;                }                if ( node.get_pointer()->m_left.is_non_null() || node.get_pointer()->m_right.is_non_null() ) {                    int left_height, right_height;                    successful = (                        compute_black_height<T>( starting_height, node.get_pointer()->m_left, left_height ) &&                        compute_black_height<T>( starting_height, node.get_pointer()->m_right, right_height ) &&                        left_height == right_height                    );                    if ( successful ) {                        ending_height = left_height;                    }                }                else {                    ending_height = starting_height;                }            }            return successful;        }        template <typename T>        bool is_rb_tree( typename rbtree_node<T>::child_t const root )        {            int height = 0;            return compute_black_height<T>( 0, root, height ) && root.is_black() && check_red_black_attributes<T>( root );        }    }    // In fact what I implement is the 2-3-4-tree    template <typename T>    class rbtree    {        typename details::rbtree_node<T>::child_t m_root;        void rebalance_nodes_in_the_different_branch(            std::stack<typename details::rbtree_node<T>::child_t *> & ancestors,            typename details::rbtree_node<T>::child_t ** parent,            typename details::rbtree_node<T>::child_t ** child,            details::child_position * ccp        )        {            assert( details::has_filiation( **parent, **child ) );            typename details::rbtree_node<T>::child_t * grandparent = ancestors.top();            details::child_position pcp = details::get_child_position( *grandparent, **parent );            *ccp = details::get_child_position( **parent, **child );            if ( pcp != *ccp ) {                typename details::rbtree_node<T>::child_t parent_ref = **parent;                typename details::rbtree_node<T>::child_t child_ref = **child;                if ( *ccp == details::left_child ) {                    parent_ref.get_pointer()->m_left = child_ref.get_pointer()->m_right;                    child_ref.get_pointer()->m_right = parent_ref;                    grandparent->get_pointer()->m_right = child_ref;                    *parent = &grandparent->get_pointer()->m_right;                    *child = &( *parent )->get_pointer()->m_right;                    *ccp = details::right_child;                }                else {                    parent_ref.get_pointer()->m_right = child_ref.get_pointer()->m_left;                    child_ref.get_pointer()->m_left = parent_ref;                    grandparent->get_pointer()->m_left = child_ref;                    *parent = &grandparent->get_pointer()->m_left;                    *child = &( *parent )->get_pointer()->m_left;                    *ccp = details::left_child;                }            }        }        void rebalance_nodes_in_the_same_branch(            std::stack<typename details::rbtree_node<T>::child_t *> & ancestors,            typename details::rbtree_node<T>::child_t * parent,            typename details::rbtree_node<T>::child_t ** child,            details::child_position ccp        )        {            assert( !ancestors.empty() && details::has_filiation( *parent, **child ) );            typename details::rbtree_node<T>::child_t * grandparent = details::pop_without_doubt( ancestors );            typename details::rbtree_node<T>::child_t * new_grandparent = NULL;            details::child_position gcp = details::left_child;            if ( !ancestors.empty() ) {                new_grandparent = ancestors.top();                gcp = details::get_child_position( *new_grandparent, *grandparent );            }            auto parent_ref = *parent;            if ( ccp == details::left_child ) {                grandparent->get_pointer()->m_left = parent_ref.get_pointer()->m_right;                parent_ref.get_pointer()->m_right = *grandparent;            }            else {                grandparent->get_pointer()->m_right = parent_ref.get_pointer()->m_left;                parent_ref.get_pointer()->m_left = *grandparent;            }            (*child)->set_black();            if ( new_grandparent != NULL && new_grandparent->is_non_null() ) {                if ( gcp == details::left_child ) {                    new_grandparent->get_pointer()->m_left = parent_ref;                    parent = &new_grandparent->get_pointer()->m_left;                }                else {                    new_grandparent->get_pointer()->m_right = parent_ref;                    parent = &new_grandparent->get_pointer()->m_right;                }            }            else {                m_root = parent_ref;            }            *child = parent;        }        void insertion_rebalance(            typename details::rbtree_node<T>::child_t * child,            std::stack<typename details::rbtree_node<T>::child_t *> & ancestors        )        {            assert( child != NULL && child->is_non_null() && !ancestors.empty() );            for ( typename details::rbtree_node<T>::child_t * parent = details::pop_without_doubt( ancestors ); parent != NULL; parent = details::pop( ancestors ) ) {                assert( details::has_filiation( *parent, *child ) );                typename details::rbtree_node<T>::child_t * sibling = details::get_other_child( *parent, *child );                if ( !sibling->is_black() ) { // cannot call is_red()                    child->set_black();                    sibling->set_black();                    child = parent;                    child->set_red();                }                else {                    if ( parent->is_red() && !ancestors.empty() ) {                        details::child_position ccp;                        rebalance_nodes_in_the_different_branch( ancestors, &parent, &child, &ccp );                        rebalance_nodes_in_the_same_branch( ancestors, parent, &child, ccp );                    }                    else {                        if ( ancestors.empty() ) {                            m_root = *parent;                        }                        break;                    }                }            }        }        typename details::rbtree_node<T>::child_t * transplant(            typename details::rbtree_node<T>::child_t expellee_parent,            typename details::rbtree_node<T>::child_t expellee,            typename details::rbtree_node<T>::child_t replacer        )        {            assert( details::has_filiation( expellee_parent, expellee ) );            assert( !expellee.is_null() );            if ( !replacer.is_null() ) {                if ( !details::has_filiation( expellee, replacer ) ) {                    replacer.get_pointer()->m_left  = expellee.get_pointer()->m_left;                    replacer.get_pointer()->m_right = expellee.get_pointer()->m_right;                }                else {                    if ( expellee.get_pointer()->m_left == replacer ) {                        replacer.get_pointer()->m_right = expellee.get_pointer()->m_right;                        assert( replacer.get_pointer()->m_left.is_null() );                    }                    else {                        replacer.get_pointer()->m_left = expellee.get_pointer()->m_left;                        assert( replacer.get_pointer()->m_right.is_null() );                    }                }                replacer.set_color( expellee.is_red() );            }            typename details::rbtree_node<T>::child_t * new_child;            auto ecp = details::get_child_position( expellee_parent, expellee );            if ( ecp == details::left_child ) {                expellee_parent.get_pointer()->m_left = replacer;                new_child = &expellee_parent.get_pointer()->m_left;            }            else {                expellee_parent.get_pointer()->m_right = replacer;                new_child = &expellee_parent.get_pointer()->m_right;            }            if ( m_root == expellee ) {                m_root = *new_child;            }            return new_child;        }        // After rotating, the child and the parent change their position        void rotate(            typename details::rbtree_node<T>::child_t * grandparent,            typename details::rbtree_node<T>::child_t parent,            typename details::rbtree_node<T>::child_t child,            typename details::rbtree_node<T>::child_t ** new_parent = NULL,            typename details::rbtree_node<T>::child_t ** new_child = NULL        )        {            assert( grandparent == NULL || details::has_filiation( *grandparent, parent ) );            assert( details::has_filiation( parent, child ) );            details::child_position ccp = details::get_child_position( parent, child );            details::child_position pcp = details::left_child;            if ( grandparent != NULL ) {                pcp = details::get_child_position( *grandparent, parent );            }            if ( ccp == details::left_child ) {                parent.get_pointer()->m_left = child.get_pointer()->m_right;                child.get_pointer()->m_right = parent;                if ( new_child != NULL ) {                    *new_child = &child.get_pointer()->m_right;                }            } else {                parent.get_pointer()->m_right = child.get_pointer()->m_left;                child.get_pointer()->m_left = parent;                if ( new_child != NULL ) {                    *new_child = &child.get_pointer()->m_left;                }            }            if ( grandparent != NULL ) {                if ( pcp == details::left_child ) {                    grandparent->get_pointer()->m_left = child;                    if ( new_parent != NULL ) {                        *new_parent = &grandparent->get_pointer()->m_left;                    }                } else {                    grandparent->get_pointer()->m_right = child;                    if ( new_parent != NULL ) {                        *new_parent = &grandparent->get_pointer()->m_right;                    }                }            } else {                m_root = child;                if ( new_parent != NULL ) {                    *new_parent = &m_root;                }            }        }        void erasing_rebalance(            typename details::rbtree_node<T>::child_t * replacement,            details::child_position rcp,            std::stack<typename details::rbtree_node<T>::child_t *> & ancestors        )        {            assert( !ancestors.empty() );            for (                typename details::rbtree_node<T>::child_t * parent = details::pop_without_doubt( ancestors );                parent != NULL;                parent = details::pop( ancestors )            ) {                assert( details::has_filiation( *parent, *replacement ) );                typename details::rbtree_node<T>::child_t * grandparent = NULL;                if ( !ancestors.empty() ) {                    grandparent = ancestors.top();                    assert(details::has_filiation(*grandparent, *parent));                    if ( details::get_child_position(*grandparent, *parent) == details::left_child ) {                        parent = &grandparent->get_pointer()->m_left;                    }                    else {                        parent = &grandparent->get_pointer()->m_right;                    }                }                else {                    parent = &m_root;                }                typename details::rbtree_node<T>::child_t * sibling = details::get_other_child( *parent, rcp );                if ( sibling->is_non_null() && sibling->is_black() && sibling->get_pointer()->m_left.is_black() && sibling->get_pointer()->m_right.is_black() ) {                    sibling->set_red();                    if ( parent->is_black() ) {                        replacement = parent;                        if ( !ancestors.empty() ) {                            rcp = details::get_child_position( *ancestors.top(), *replacement );                        }                    }                    else {                        parent->set_black();                        break;                    }                }                else {                    if ( !sibling->is_black() ) {                        // we cannot use the logical listed in CLRS, because our implementation is based on 2-3-4-tree                        assert( details::has_filiation( *parent, *replacement ) );                        assert( parent->is_black() );                        if ( !ancestors.empty() ) {                            grandparent = ancestors.top();                        }                        sibling->set_black();                        if ( rcp == details::left_child ) {                            if ( sibling->get_pointer()->m_left.is_non_null() ) {                                sibling->get_pointer()->m_left.set_red();                            }                        }                        else {                            if ( sibling->get_pointer()->m_right.is_non_null() ) {                                sibling->get_pointer()->m_right.set_red();                            }                        }                        rotate( grandparent, *parent, *sibling, &grandparent, &parent );                        if ( rcp == details::left_child ) {                            sibling = &parent->get_pointer()->m_right;                        } else {                            sibling = &parent->get_pointer()->m_left;                        }                        assert( details::has_filiation( *grandparent, *parent ) );                        assert( details::has_filiation( *parent, *replacement ) );                        assert( details::has_filiation( *parent, *sibling ) );                        if ( sibling->is_non_null() ) {                            bool left_is_red = !sibling->get_pointer()->m_left.is_black(), right_is_red = !sibling->get_pointer()->m_right.is_black();                            if ( left_is_red || right_is_red ) {                                typename details::rbtree_node<T>::child_t * child = &sibling->get_pointer()->m_left;                                if ( right_is_red ) {                                    child = &sibling->get_pointer()->m_right;                                }                                std::stack<typename details::rbtree_node<T>::child_t *> new_ancestors;                                new_ancestors.push( grandparent );                                new_ancestors.push( parent );                                parent = sibling;                                details::child_position ccp;                                rebalance_nodes_in_the_different_branch(new_ancestors, &parent, &child, &ccp);                                rebalance_nodes_in_the_same_branch(new_ancestors, parent, &child, ccp);                            }                        }                    }                    else {                        if ( rcp == details::left_child ) {                            if ( !sibling->get_pointer()->m_left.is_black() ) {                                sibling->set_red();                                sibling->get_pointer()->m_left.set_black();                                rotate( parent, *sibling, sibling->get_pointer()->m_left );                                sibling = &parent->get_pointer()->m_right;                            }                            sibling->set_color( parent->is_red() );                            parent->set_black();                            sibling->get_pointer()->m_right.set_black();                            rotate( grandparent, *parent, *sibling );                        } else {                            if ( !sibling->get_pointer()->m_right.is_black() ) {                                sibling->set_red();                                sibling->get_pointer()->m_right.set_black();                                rotate( parent, *sibling, sibling->get_pointer()->m_right );                                sibling = &parent->get_pointer()->m_left;                            }                            sibling->set_color( parent->is_red() );                            parent->set_black();                            sibling->get_pointer()->m_left.set_black();                            rotate( grandparent, *parent, *sibling );                        }                    }                    break;                }            }        }        struct height_record        {            size_t height;            size_t width;        };        static void calculate_height(            typename details::rbtree_node<T>::child_t const node,            std::unordered_map<typename details::rbtree_node<T>::child_t const, height_record, typename details::rbtree_node<T>::hash> & cache        )        {            if ( cache.find( node ) == cache.end() && node.is_non_null() ) {                calculate_height( node.get_pointer()->m_left, cache );                height_record & left = cache[ node.get_pointer()->m_left ];                calculate_height( node.get_pointer()->m_right, cache );                height_record & right = cache[ node.get_pointer()->m_right ];                size_t width = left.height + right.height;                if ( width < left.width ) {                    width = left.width;                }                if ( width < right.width ) {                    width = right.width;                }                height_record self = { ( left.height < right.height ? right.height : left.height ) + 1, width };                cache[ node ] = std::move( self );            }        }    public:        rbtree() {}        rbtree( rbtree<T> const & );        rbtree<T> & operator=( rbtree<T> const & );        void insert( typename boost::call_traits<T>::param_type t )        {            assert( details::is_rb_tree<T>( m_root ) );            std::stack<typename details::rbtree_node<T>::child_t *> stack;            typename details::rbtree_node<T>::child_t * child = NULL;            details::search_result sr = details::find<T>( &m_root, t, &stack, &child );            if ( ( sr & ( details::empty_tree | details::should_insert_as_left | details::should_insert_as_right ) ) != 0 ) {                details::rbtree_node<T> * new_node = new details::rbtree_node<T>( t );                switch ( sr ) {                case details::empty_tree:                    assert( m_root.is_null() );                    m_root.pointer = new_node;                    return;                case details::should_insert_as_left:                    stack.top()->get_pointer()->m_left.pointer = new_node;                    child = &stack.top()->get_pointer()->m_left;                    break;                case details::should_insert_as_right:                    stack.top()->get_pointer()->m_right.pointer = new_node;                    child = &stack.top()->get_pointer()->m_right;                    break;                default:                    assert( false && "bug" );                }                child->set_red();                insertion_rebalance( child, stack );                m_root.set_black();            }            assert( details::is_rb_tree<T>( m_root ) );        }        size_t width() const        {            std::unordered_map<typename details::rbtree_node<T>::child_t const, height_record, typename details::rbtree_node<T>::hash> cache;            height_record hr = { 0, 0 };            cache[ typename details::rbtree_node<T>::child_t() ] = std::move( hr );            calculate_height( m_root, cache );            return cache[ m_root ].width;        }        void erase( typename boost::call_traits<T>::param_type t )        {            assert( details::is_rb_tree<T>( m_root ) );            bool need_to_reblance = false;            std::stack<typename details::rbtree_node<T>::child_t *> ancestors;            details::rbtree_node<T> dummy_node;            details::child_position rcp;            typename details::rbtree_node<T>::child_t * expellee = NULL, dummy;            auto result = details::find<T>( &m_root, t, &ancestors, &expellee );            if ( result == details::found_node ) {                typename details::rbtree_node<T>::child_t expellee_ref;                need_to_reblance = true;                typename details::rbtree_node<T>::child_t * expellee_parent = NULL;                if ( !ancestors.empty() ) {                    expellee_parent = ancestors.top();                }                if ( expellee_parent == NULL ) {                    assert( m_root == *expellee );                    dummy_node.m_left = m_root;                    dummy.pointer = &dummy_node;                    expellee_parent = &dummy;                }                expellee_ref = *expellee;                assert( expellee != NULL && expellee->is_non_null() );                typename details::rbtree_node<T>::child_t * replacement;                if ( expellee->get_pointer()->m_right.is_non_null() ) {                    std::vector<typename details::rbtree_node<T>::child_t *> new_ancestors;                    replacement = details::get_minimum_child( expellee, new_ancestors );                    assert( replacement != NULL && replacement->is_non_null() );                    assert( !new_ancestors.empty() );                    assert( details::height( *replacement ) <= 2 );                    if ( replacement->get_pointer()->m_right.is_non_null() || replacement->is_red() ) {                        //the replacement is a 3-node, we only need to change the 3-node to a 2-node                        if ( replacement->get_pointer()->m_right.is_non_null() ) {                            assert( replacement->get_pointer()->m_right.is_red() && replacement->is_black() );                            replacement->get_pointer()->m_right.set_black();                        }                        need_to_reblance = false;                    }                    auto replacement_ref = *replacement;                    auto expellee_ref = *expellee;                    rcp = details::get_child_position( *new_ancestors.back(), replacement_ref );                    replacement = transplant( *new_ancestors.back(), replacement_ref, replacement_ref.get_pointer()->m_right );                    expellee = transplant( *expellee_parent, expellee_ref, replacement_ref );                    if ( need_to_reblance ) {                        ancestors.push( expellee );                        std::for_each(                            new_ancestors.begin() + 1, new_ancestors.end(),                            [&ancestors]( typename details::rbtree_node<T>::child_t * node ) { ancestors.push( node ); }                        );                    }                }                else {                    assert( details::height( *expellee ) <= 2 );                    need_to_reblance = *expellee != m_root;                    if ( expellee->get_pointer()->m_left.is_non_null() ) {                        //it is a 3-node                        assert( expellee->get_pointer()->m_left.is_red() );                        need_to_reblance = false;                    }                    else if ( expellee->is_red() ) {                        //it is a 3-node                        assert( expellee->get_pointer()->m_left.is_null() && expellee->get_pointer()->m_right.is_null() );                        need_to_reblance = false;                    }                    rcp = details::get_child_position( *expellee_parent, *expellee );                    replacement = transplant( *expellee_parent, *expellee, expellee->get_pointer()->m_left );                }                if ( need_to_reblance ) {                    assert( replacement->is_null() );                    erasing_rebalance( replacement, rcp, ancestors );                }                delete expellee_ref.get_pointer();                assert( details::is_rb_tree<T>( m_root ) );            }        }        template <typename Visitor>        void levelorder_visit( Visitor visitor ) const        {            details::levelorder_visit( m_root, visitor );        }        bool is_valid( ) const { return details::is_rb_tree<T>( m_root ); }    };}#endif //GYM_RED_BLACK_TREE_H_6D4EBDB0_5B18_4FC1_A34A_CBBF36FE95E4


0 0