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
- Implement the avl tree, rbtree without the two fields: parent pointer and balance/color
- ZOJ1486 Color the Tree
- Using Spring Boot without the parent POM
- hdu 4603 Color the Tree
- hdu 4603 Color the Tree
- The two-dimensional pointer operation in C++
- Color Transformations and the Color Matrix
- The Balance
- The Balance
- The Balance
- ntfs mft record head(without the NTFS 3.1+ specific fields)
- the database tables and fields of ecshop
- Two birds in the tree
- The implement of Binary Search Tree (JAVA)
- Delete a node WITHOUT using the HEAD pointer.
- Ilya And The Tree
- Synchronize the height of iframe and parent
- the difference between the version and build fields
- Android网络数据抓包:利用Fiddler进行网络数据抓包
- c#中的一些类!
- 宏定义的黑魔法 - 宏菜鸟起飞手册
- Ubuntu下Beamer制作PPT范例
- QT学习
- Implement the avl tree, rbtree without the two fields: parent pointer and balance/color
- PHP位操作符
- MONO上的ios、Android开发框架(官方出品)
- VS2010快捷键
- 统计信息动态采集级别的解释
- nodejs开发环境安装
- Eclipse安装插件的时候出现CheckTrust错误的解决办法
- 给自己一个改变的机会
- android4.x Notification使用