您的位置:首页 > 理论基础 > 数据结构算法

支持泛型AVL Tree的简单实现,并和STL map比较了插入,删除,查找的性能

2014-04-27 12:37 591 查看

1.问题描述:

   1)AVL tree是一种自平衡树。它通过左右子树的高度差来控制树的平衡,当高度差是不大于1的时候,认为树是平衡的。树的平衡保证了树在极端情况下
         (输入序列不够随机)的性能。很显然当左右子树高度平衡,保证了任何插入,删除,查找操作平均性能呢个,当不平衡时(有的子树很高),当
          要操作的元素在这个子树时,性能会很差;

  2)AVL tree 和Red black tree 都是一种平衡树,它的操作的时间复杂度是:O(lgN) ,N是树的节点的数目;
  3)本文实现了AVL Tree, 并和STL map做了操作性能上的比较,结果发现:AVL tree 的消耗时间稍微多一些大约比Red Black tree多出8%;
  4)本文没有封装迭代器(iterator),随后可以完成这个工作;
  5)由于表达力有限,关于AVL tree的算法详述请参见维基百科;


2:程序代码

#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


compile and run in visual studio 2005
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐