泛型的RedBlack Tree的实现,并和STL map 做了简单的性能比较
来源:互联网 发布:模仿周杰伦的网络 编辑:程序博客网 时间:2024/06/10 04:55
问题提出:
1.RedBlack Tree是一种简单的自平衡树。它通过属性约束来实现树的平衡,保证在树上没有一条路是别的路的2倍长。
2. 它有以下五条属性约束:
1) 每个node是红色或者黑色;
2) 每个叶子node是黑色;
3)根node是黑色;
4)若一个node是黑色,则它的两个孩子node是红色;
5) 对每个node,若有从这个node到它的子孙叶子(node)的路上包含有相同数目的黑色节点;
3. 本文的实现是参考introduction to algorithm 书中的讲述;
4. 本文和STL map做了简单的性能比较,结果基本上不相上下;
代码如下:
#ifndef _RED_BLACK_TREE_H_#define _RED_BLACK_TREE_H_#include <functional>#include <algorithm>#include <map>/** encapsulate red black tree only for challenge self**/template<class T, class V, class Cmp = std::less<T> > class RedBlackTree{public:enum COLOR{RED,BLACK};typedef struct tagRedBlackNode{T key;V value;tagRedBlackNode* parent;tagRedBlackNode* leftChild;tagRedBlackNode* rightChild;COLOR color;tagRedBlackNode():key(), value(), parent(0), leftChild(0), rightChild(0), color(){}tagRedBlackNode( const T& _key, const T& _value ): key(_key), value(_value),leftChild(0),rightChild(0), color(RED){}}RedBlackNode, *pRedBlackNode;/****/RedBlackTree():m_root(0), m_size(0){}/** Copy constructor**/RedBlackTree( const RedBlackTree& rhs ){m_root = Clone( rhs.m_root );m_size = rhs.m_size;}/****/~RedBlackTree(){Clear();}/** assignment operator overload**/RedBlackTree& operator = ( const RedBlackTree& rhs ){if( this != &rhs ){Clear();m_root = Clone( rhs.m_root );m_size = rhs.m_size;}return *this;}/****/bool IsEmpty() const {return Size == 0;}/** Remove all node **/void Clear(){Clear( m_root );m_size = 0;}/** Retrieve the number of node**/size_t Size() const {return m_size;}/****/void Insert( const T& key, const V& value ){InsertUtil( key, value );}/** Find value from tree for given key**/V* Find( const T& key ){return Find( m_root, key );}/** delete node from tree for given key**/void Delete( const T& key ){Delete( m_root, key );}/** Retrieve the element of min**/V* FindMin( T& key ){pRedBlackNode node = FindMin( m_root );if( node ){key = node->key;return &node->value;}return 0;}/** Retrieve the element of max**/V* FindMax( T& key ){pRedBlackNode node = FindMax( m_root );if( node ){key = node->key;return &node->value;}return 0;}size_t GetSize() const {return Size( m_root );}protected:/** get the number of node by recursive method**/size_t Size( pRedBlackNode root ) const {if( 0 == root )return 0;return 1 + Size( root->leftChild ) + Size( root->rightChild );}/** Clone tree**/pRedBlackNode Clone( pRedBlackNode root ){if( 0 == root )return root;pRedBlackNode newNode = new RedBlackNode( root->key, root->value );newNode->leftChild = Clone( root->leftChild );newNode->rightChild = Clone( root->rightChild );if( newNode->leftChild )newNode->leftChild->parent = newNode;if( newNode->rightChild )newNode->rightChild->parent = newNode;return newNode;}/** Clear all elements**/void Clear( pRedBlackNode& root ){if( 0 == root )return;Clear( root->leftChild );Clear( root->rightChild );delete root;root = 0;}/** Reabalance when complete delete operation**/void DeleteReablance( pRedBlackNode root ){if( 0 == root->parent )return;while( root != m_root && BLACK == root->color ){if( root == root->parent->leftChild ){pRedBlackNode y = root->parent->rightChild;if( RED == y->color ){y->color = BLACK;root->parent->color = RED;LeftRotate( root->parent );y = root->parent->rightChild;}if( y->leftChild && BLACK == y->leftChild->color && y->rightChild && BLACK == y->rightChild->color ){y->color = RED;root = root->parent;}else{if( y->rightChild && BLACK == y->rightChild->color ){y->leftChild->color = BLACK;y->color = RED;RightRotate( y );y = root->parent;}y->color = root->parent->color;root->color = BLACK;if( y->rightChild )y->rightChild->color = BLACK;LeftRotate( root->parent );root = m_root;}}else if( root == root->parent->rightChild ){pRedBlackNode y = root->parent->leftChild;if( RED == y->color ){y->color = BLACK;root->parent->color = RED;RightRotate( root->parent );y = root->parent->leftChild;}if( y->leftChild && BLACK == y->leftChild->color && y->rightChild && BLACK == y->rightChild->color ){y->color = RED;root = root->parent;}else {if( y->leftChild && BLACK == y->leftChild->color ){y->rightChild->color = BLACK;y->color = RED;LeftRotate( y );y = root->parent;}y->color = root->parent->color;root->color = BLACK;if( y->leftChild )y->leftChild->color = BLACK;RightRotate( root->parent );root = m_root;}}}// terminal while looproot->color = BLACK;}/** reabalance tree when complete insert operation**/void InsertReablance( pRedBlackNode root ){if( 0 == root->parent ){root->color = BLACK;return;}while( root->parent && RED == root->parent->color ){if( root->parent->parent ){if( root->parent == root->parent->parent->leftChild ) // uncle right{pRedBlackNode y = root->parent->parent->rightChild;if( y && RED == y->color ) // case 1{root->parent->color = BLACK;y->color = BLACK;root->parent->parent->color = RED;root = root->parent->parent;}else{if( root == root->parent->rightChild ){root = root->parent;LeftRotate( root );}root->parent->color = BLACK;root->parent->parent->color = RED;RightRotate( root->parent->parent );}}else if( root->parent == root->parent->parent->rightChild ) // uncle left{pRedBlackNode y = root->parent->parent->leftChild;if( y && RED == y->color ) // case 1{root->parent->color = BLACK;y->color = BLACK;root->parent->parent->color = RED;root = root->parent->parent;}else {if( root == root->parent->leftChild ){root = root->parent;RightRotate( root );}root->parent->color = BLACK;root->parent->parent->color = RED;LeftRotate( root->parent->parent );}}}}m_root->color = BLACK;}/**Insert element to redblack tree**/void InsertUtil( const T& key, const V& value ){pRedBlackNode root = m_root;pRedBlackNode cur = root;while( root ){cur = root;if( key < root->key ){root = root->leftChild;}else if( key > root->key ){root = root->rightChild;}}pRedBlackNode newNode = new RedBlackNode( key, value );newNode->parent = cur;if( 0 == cur ){m_root = newNode;}else if( cur->key > newNode->key ){cur->leftChild = newNode;}else if( cur->key < newNode->key ){cur->rightChild = newNode;}InsertReablance( newNode );m_size++;}/** Delete element from redblack tree**/pRedBlackNode DeleteUtil( pRedBlackNode root, const T& key ){if( 0 == root )return 0;pRedBlackNode y = 0;if( 0 == root->leftChild ||0 == root->rightChild ){y = root;}else{y = Successor( root );}pRedBlackNode x = 0;if( y->leftChild != 0 ){x = y->leftChild;}else { x = y->rightChild;}if( 0 == y->parent ){m_root = x;}else if( y == y->parent->leftChild ){x = y->parent->leftChild;}else{x = y->parent->rightChild;}x->parent = y->parent;if( y != root ){root->key = y->key;root->value = y->value;}if( BLACK == y->color ){DeleteReablance( x );}return y;}/****/pRedBlackNode Insert( pRedBlackNode root, const T& key, const V& value ){if( 0 == root ){root = new RedBlackNode( key, value );return root;}if( root->key < key ){root->rightChild = Insert( root->rightChild, key, value );}else if( root->key > key ){root->leftChild = Insert( root->leftChild, key, value );}}/****/V* Find( pRedBlackNode root, const T& key ){if( 0 == root )return 0;pRedBlackNode cur = root;while( root ){cur = root;if( root->key < key ){root = root->rightChild;}else if( root->key > key ){root = root->leftChild;}else{break;}}if( cur->key == key ){return &cur->value;}return 0;}/****/void Delete( pRedBlackNode root, const T& key ){if( 0 == root )return;if( root->key < key ){Delete( root->rightChild, key );}else if( root->key > key ){Delete( root->leftChild, key );}else {pRedBlackNode delNode = DeleteUtil( root, key );if( delNode->parent->leftChild == delNode ){delNode->parent->leftChild = 0;}else{delNode->parent->rightChild = 0;}delete delNode;delNode = 0;m_size--;}}/****/pRedBlackNode FindMin( pRedBlackNode root ){if( 0 == root )return root;while( root->leftChild ){root = root->leftChild;}return root;}/****/pRedBlackNode FindMax( pRedBlackNode root ){if( 0 == root )return root;while( root->rightChild ){root = root->rightChild;}return root;}/****/void LeftRotate( pRedBlackNode root ){pRedBlackNode y = root->rightChild;root->rightChild = y->leftChild;if( y->leftChild )y->leftChild->parent = root;y->parent = root->parent;if( root == m_root ){m_root = y;}else if( root->parent->leftChild == root ){root->parent->leftChild = y;}else{root->parent->rightChild = y;}y->leftChild = root;root->parent = y;}/****/void RightRotate( pRedBlackNode root ){pRedBlackNode y = root->leftChild;root->leftChild = y->rightChild;if( y->rightChild )y->rightChild->parent = root;y->parent = root->parent;if( root == m_root ){m_root = y;}else if( root->parent->leftChild == root ){root->parent->leftChild = y;}else {root->parent->rightChild = y;}y->rightChild = root;root->parent = y;}/****/pRedBlackNode Successor( pRedBlackNode root ){if( 0 == root )return root;if( root->rightChild ){root = FindMin( root->rightChild );}else{pRedBlackNode y = root->parent;if( 0 == y )return root;while( root == y->rightChild ){root = y;y = y->parent;}if( root->rightChild != y ){root = y;}}return root;}/****/pRedBlackNode Predecessor( pRedBlackNode root ){if( 0 == root )return root;if( root->leftChild ){root = FindMax( root->leftChild );}else{pRedBlackNode y = root->parent;if( 0 == y )return root;while( root == y->leftChild ){root = y;y = y->parent;}root = y;}return root;}protected:pRedBlackNode m_root;size_t m_size;};/** Test STL map**/void TestSTLMapRbTree(){const int Len = 10000;int key[Len];int value[Len];for( int i = 0; i < Len; i++ ){key[i] = i;value[i] = i;}std::random_shuffle( key, key + Len );std::random_shuffle( value, value + Len );unsigned long start = GetTickCount();std::map<int, int> treeObj;for( int i = 0; i < Len; i++ ){treeObj.insert( std::make_pair( key[i], value[i] ) );}size_t count = treeObj.size();for( int i = 0; i < Len; i++ ){std::map<int, int>::iterator iter = treeObj.find( key[i] );assert( iter != treeObj.end() );assert( iter->second == value[i] );}for( int i = 0; i < Len; i++ ){if( !(i % 15) ){treeObj.erase( key[i] );std::map<int, int>::iterator iter = treeObj.find( key[i] );assert( iter == treeObj.end() );}}unsigned long interval = GetTickCount() - start;printf( " STL map consume time is %d \n", interval );}/** Unit test for redblack tree**/void TestRedBlackTree(){const int Len = 10000;int key[Len];int value[Len];for( int i = 0; i < Len; i++ ){key[i] = i;value[i] = i;}std::random_shuffle( key, key + Len );std::random_shuffle( value, value + Len );unsigned long start = GetTickCount();RedBlackTree<int, int> treeObj;for( int i = 0; i < Len; i++ ){treeObj.Insert( key[i], value[i] );}size_t count = treeObj.GetSize();for( int i = 0; i < Len; i++ ){int* val = treeObj.Find( key[i] );assert( *val == value[i] );}int minKey = -1;int* minValue = treeObj.FindMin( minKey );assert( minKey == 0 );assert( minValue != 0 );int maxKey = -1;int* maxValue = treeObj.FindMax( maxKey );assert( maxKey == Len - 1 );assert( maxValue != 0 );size_t size = treeObj.Size();assert( size == Len );for( int i = 0; i < Len; i++ ){if( !(i % 15) ){treeObj.Delete( i );int* val = treeObj.Find( i );assert( !val );}}RedBlackTree<int, int> newTreeObj;newTreeObj = treeObj;assert(newTreeObj.Size() == treeObj.Size());newTreeObj.Clear();treeObj.Clear();unsigned long interval = GetTickCount() - start;printf( " redblack tree consume time is %d \n", interval );}void TestSuiteRBTree(){TestSTLMapRbTree();TestRedBlackTree();}#endifcompile and run in visual studio 2005
2 0
- 泛型的RedBlack Tree的实现,并和STL map 做了简单的性能比较
- 支持泛型AVL Tree的简单实现,并和STL map比较了插入,删除,查找的性能
- 支持泛型AVL Tree的简单实现,并和STL map比较了插入,删除,查找的性能
- 泛型的Binary Search Tree的实现,并与STL map进行操作性能上的比较
- 比较并对比散列表和STL map。散列表是如何实现的?
- JdbcTemplate返回Map和做ORM的性能比较
- 用c++封装一个Hash Table,并与STL map 进行操作性能上的比较
- 比较Map的性能
- 扩展封装暴雪哈希算法(blizard hash algorithm),并与STL map进行操作性能上的比较
- STL map 和 set的实现
- STL map和set的实现
- STL map 和 set的实现
- STL map 和 set的实现
- STL:map和BOOST:unordered_map 实现简单比较
- stl map的简单用法
- STL Map 的简单操作
- STL map的简单使用
- C++ STL map的使用和性能分析
- SQLite C语言接口
- 如何在火狐中获取浏览器的高度
- automake 详解
- cocos2d-x:读取指定目录下的文件名+解决中文乱码(win32下有效)
- long long 和 __int64的区别
- 泛型的RedBlack Tree的实现,并和STL map 做了简单的性能比较
- [projecteuler]Counting Sundays
- Android中滑屏实现----手把手教你如何实现触摸滑屏以及Scroller类详解
- C# 为WebBrowser设置代理,打开网页
- Apache ActiveMQ消息中间件的基本使用
- Java 项目字符集修改
- Oracle集群件组件
- Cocos2d-x设计模式发掘之四:外观模式
- 根据值设置spinner的选中项