标签:c++ 数据结构 performance
#ifndef _AVL_TREE_H_ #define _AVL_TREE_H_ #include <algorithm> #include <functional> #include <map> #include "windows.h" #define Max( a, b ) ( (a > b )? (a):(b)) template<class T, class V, class Cmp = std::less<T> > class AVLTree { public: typedef struct tagAVLNode { T key; V data; int height; tagAVLNode* leftChild; tagAVLNode* rightChild; tagAVLNode():key(), data(), height(0), leftChild(0), rightChild(0) { } tagAVLNode( const T& _key, const V& _data ):key( _key ), data(_data), height(1), leftChild(0), rightChild(0) { } ~tagAVLNode() { key.~T(); data.~V(); } }AVLNode, *pAVLNode; AVLTree():m_root(0), m_size(0) { } /* * Copy constructor * */ AVLTree( const AVLTree& rhs ) { Clear(); m_root = Clone( rhs.m_root ); } /* * Destructor * */ ~AVLTree() { Clear(); } /* * overload assignment operator * */ AVLTree& operator = ( const AVLTree& rhs ) { if( this != &rhs ) { Clear(); m_root = Clone( rhs.m_root ); } return m_root; } /* * Retrieve the number of node for the given avl tree * */ size_t Size() const { return m_size; } /* * Clear all node * */ void Clear() { Clear( m_root ); } /* * Insert key value pair to avl tree * */ void Insert( const T& _key, const V& _value ) { m_root = Insert( m_root, _key, _value ); } /* * Delete node for given key * */ void Delete( const T& _key ) { m_root = Delete( m_root, _key ); } /* * Find the pointer of value for given key * */ V* Find( const T& _key ) { return Find( m_root, _key ); } /* * Find the min value * */ V& FindMin( T& key ) { pAVLNode node = FindMin( m_root ); if( node ) { key = node->key; return node->data; } } /* * Find the max value * */ V& FindMax( T& key ) { pAVLNode node = FindMax( m_root ); if( node ) { key = node->key; return node->data; } } protected: /* * Clone avl tree * */ pAVLNode Clone( pAVLNode root ) { if( 0 == root ) return 0; pAVLNode newNode = new AVLNode( root->key, root->data ); newNode->leftChild = Clone( root->leftChild ); newNode->rightChild = Clone( root->rightChild ); return newNode; } /* * * */ size_t Size( pAVLNode root ) const { if( 0 == root ) return 0; return 1 + Size( root->leftChild ) + Size( root->rightChild ); } /* * * */ int GetBalance( pAVLNode root ) { if( 0 == root ) return 0; return GetHeight( root->leftChild ) - GetHeight( root->rightChild ); } /* * * */ int GetHeight( pAVLNode root ) { if( 0 == root ) return 0; return root->height; } /* * Left Rotate * */ pAVLNode LeftRotate( pAVLNode node ) { pAVLNode y = node->rightChild; node->rightChild = y->leftChild; y->leftChild = node; node->height = Max( GetHeight( node->leftChild ), GetHeight( node->rightChild ) ) + 1; // important y->height = Max( GetHeight( y->leftChild ), GetHeight( y->rightChild ) ) + 1; return y; } /* * Right rotate * */ pAVLNode RightRotate( pAVLNode node ) { pAVLNode y = node->leftChild; node->leftChild = y->rightChild; y->rightChild = node; node->height = Max( GetHeight( node->leftChild ), GetHeight( node->rightChild ) ) + 1; // important y->height = Max( GetHeight( y->leftChild ), GetHeight( y->rightChild )) + 1; return y; } /* * Clear all node * */ void Clear( pAVLNode root ) { if( 0 == root ) return; Clear( root->leftChild ); Clear( root->rightChild ); delete root; root = 0; } /* * Insert key value pair to avl tree * */ pAVLNode Insert( pAVLNode root, const T& _key, const V& _value ) { if( 0 == root ) { root = new AVLNode( _key, _value ); m_size++; return root; } else if( root->key > _key ) { root->leftChild = Insert( root->leftChild, _key, _value ); } else if( root->key < _key ) { root->rightChild = Insert( root->rightChild, _key, _value ); } // update height root->height = Max( GetHeight( root->leftChild ), GetHeight( root->rightChild ) ); // rebalance tree int balance = GetBalance( root ); if( balance > 1 ) //left child tree more high { if( _key < root->leftChild->key ) //left left case { return RightRotate( root ); } else if( _key > root->leftChild->key ) // left right case { root->leftChild = LeftRotate( root->leftChild ); return RightRotate( root ); } } else if( balance <- 1 ) // right child tree more high { if( _key > root->rightChild->key ) // right right case { return LeftRotate( root ); } else if( _key < root->rightChild->key ) // right left case { root->rightChild = RightRotate( root->rightChild ); LeftRotate( root ); } } return root; } /* * Delete node for given key * */ pAVLNode Delete( pAVLNode root, const T& _key ) { if( 0 == root ) return 0; if( root->key < _key ) { root->rightChild = Delete( root->rightChild, _key ); } else if( root->key > _key ) { root->leftChild = Delete( root->leftChild, _key ); } else { if( root->leftChild ) { if( root->rightChild ) // left right child exist case 1 { pAVLNode minNode = FindMin( root->rightChild ); root->key = minNode->key; root->data = minNode->data; root->rightChild = Delete( root->rightChild, minNode->key ); } else // only left child exist { pAVLNode cur = root; root = root->leftChild; delete cur; cur = 0; } } else { if( root->rightChild ) // only right child exist { pAVLNode minNode = FindMin( root->rightChild ); root->key = minNode->key; root->data = minNode->data; root->rightChild = Delete( root->rightChild, minNode->key ); } else // no child exist { delete root; root = 0; } } m_size--; } if( 0 == root ) return 0; // update height root->height = Max( GetHeight( root->leftChild ), GetHeight( root->leftChild ) ) + 1; //rebalance tree int balance = GetBalance( root ); if( balance > 1 && GetBalance( root->leftChild ) >= 0 ) { return RightRotate( root ); } if( balance > 1 && GetBalance( root->leftChild ) < 0 ) { root->leftChild = LeftRotate( root->leftChild ); return RightRotate( root ); } if( balance < -1 && GetBalance( root->rightChild ) <= 0 ) { return LeftRotate( root ); } if( balance < -1 && GetBalance( root->rightChild ) > 0 ) { root->rightChild = RightRotate( root->rightChild ); return LeftRotate( root ); } return root; } /* * Find node for given key * */ V* Find( pAVLNode root, const T& _key ) { if( 0 == root ) { return 0; } if( root->key > _key ) { return Find( root->leftChild, _key ); } else if( root->key < _key ) { return Find( root->rightChild, _key ); } else { return &root->data; } } /* * Find the node of min key value * */ pAVLNode FindMin( pAVLNode root ) { if( 0 == root ) return 0; pAVLNode cur = root; while( root->leftChild ) { cur = root->leftChild; root = cur; } return cur; } /* * Find the node of max key value * */ pAVLNode FindMax( pAVLNode root ) { if( 0 == root ) return 0; pAVLNode cur = root; while( root->rightChild ) { cur = root->rightChild; root = cur; } return cur; } protected: pAVLNode m_root; size_t m_size; }; /* * Test map * */ void TestSTLMap() { const int Len = 100000; 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> mapObj; for( int i = 0; i < Len; i++ ) { mapObj.insert( std::make_pair( key[i], value[i] ) ); } for( int i = 0; i < Len; i++ ) { std::map<int, int>::iterator iter = mapObj.find( key[i] ); assert( iter != mapObj.end() ); assert( iter->second == value[i] ); } for( int i = 0; i < Len; i++ ) { if( !(i % 15) ) { mapObj.erase( key[i] ); std::map<int, int>::iterator iter = mapObj.find( key[i] ); assert( iter == mapObj.end() ); } } unsigned long interval = GetTickCount() - start; printf( " map consume time is %d \n", interval ); } /* * Test avl tree * */ void TestAVLTree() { const int Len = 100000; 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(); AVLTree<int, int> treeObj; for( int i = 0; i < Len; i++ ) { treeObj.Insert( key[i], value[i] ); } 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 ); int maxKey = -1; int maxValue = treeObj.FindMax( maxKey ); assert( maxKey == Len - 1 ); 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 ); } } size = treeObj.Size(); unsigned long interval = GetTickCount() - start; printf( " avl tree consume time is %d \n", interval ); } /* * Test interface * */ void TestSuit() { TestSTLMap(); TestAVLTree(); } #endif
支持泛型AVL Tree的简单实现,并和STL map比较了插入,删除,查找的性能,码迷,mamicode.com
支持泛型AVL Tree的简单实现,并和STL map比较了插入,删除,查找的性能
标签:c++ 数据结构 performance
原文地址:http://blog.csdn.net/manthink2005/article/details/24582027