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

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

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

时间: 2024-08-06 11:54:49

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

泛型的RedBlack Tree的实现,并和STL map 做了简单的性能比较

问题提出: 1.RedBlack Tree是一种简单的自平衡树.它通过属性约束来实现树的平衡,保证在树上没有一条路是别的路的2倍长. 2. 它有以下五条属性约束: 1) 每个node是红色或者黑色: 2) 每个叶子node是黑色: 3)根node是黑色: 4)若一个node是黑色,则它的两个孩子node是红色: 5)   对每个node,若有从这个node到它的子孙叶子(node)的路上包含有相同数目的黑色节点: 3. 本文的实现是参考introduction to algorithm 书中的讲

泛型的Binary Search Tree的实现,并与STL map进行操作性能上的比较

问题描述: 1.binary search tree是一种排序二叉树.对于key值,当前节点的小于左孩子的大于右孩子的: 2.binary search tree不是自平衡树.所以,当插入数据不是很随机时候,性能会接近O(N),N是树中节点数目; 3.理想状态下,时间复杂度是O(lgN), N是树中节点的数目: 4.下面给出一个简单的实现,并比较其和STL map的性能,一样的操作,大约耗时为STL map 的2/3: 代码如下: #ifndef _BINARY_SEARCH_TREE_H_ #

PAT Root of AVL Tree

Root of AVL Tree An AVL tree is a self-balancing binary search tree. In an AVL tree, the heights of the two child subtrees of any node differ by at most one; if at any time they differ by more than one, rebalancing is done to restore this property. F

.net中数据集合导出为Excel(支持泛型及显示字段顺序,可自定义显示列名)

摘要:咳咳~入园快两年,工作也快将近两年了,这才打算写自己在园中的第一篇文章,主要因为之前只是小白一个,肚子里没有什么墨水,现如今,也喝了些许墨水~当然墨水来源也是受益于广大程序猿们的技术分享,感谢,共同进步! 好了,废话不多说,直接切入今天要分享的主题. 主题:.net中数据集合导出为Excel 背景:如今越来越多的公司开始注重了大数据,公司开始通过数据来分析用户的行为习惯或者某些产品给公司带来的利害,总之这些数据都可以很好的帮助公司做的更好,了解自身的优缺点从而更好的为用户服务获取更大的利益

asp.net泛型结合反射的简单Base封装

泛型(generic)是C#语言2.0和通用语言运行时(CLR)的一个新特性.泛型为.NET框架引入了类型参数(type parameters)的概念.类型参数使得设计类和方法时,不必确定一个或多个具体参数,其的具体参数可延迟到客户代码中声明.实现.这意味着使用泛型的类型参数T,写一个类MyList<T>,客户代码可以这样调用:MyList<int>, MyList<string>或 MyList<MyClass>.这避免了运行时类型转换或装箱操作的代价和风

平衡二叉树(AVL Tree)

在学习算法的过程中,二叉平衡树是一定会碰到的,这篇博文尽可能简明易懂的介绍下二叉树的相关概念,然后着重讲下什么事平衡二叉树. (由于作图的时候忽略了箭头的问题,正常的树一般没有箭头,虽然不影响描述的过程,但是还是需要注意,所以还请读者忽略一下部分图的箭头) 一.二叉(查找)树 二叉查找树(Binary Search Tree)是二叉树的一种,其树节点(internal nodes of the tree)储存着键值并且满足以下特性并如图A所示: 假设u, v, r分别为树的三个结点(nodes)

04-树4. Root of AVL Tree (25)

04-树4. Root of AVL Tree (25) 时间限制 100 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue An AVL tree is a self-balancing binary search tree. In an AVL tree, the heights of the two child subtrees of any node differ by at most one; if at any tim

04-树5 Root of AVL Tree + AVL树操作集

An AVL tree is a self-balancing binary search tree. In an AVL tree, the heights of the two child subtrees of any node differ by at most one; if at any time they differ by more than one, rebalancing is done to restore this property. Figures 1-4 illust

1066. Root of AVL Tree (25)【AVL树】——PAT (Advanced Level) Practise

题目信息 1066. Root of AVL Tree (25) 时间限制100 ms 内存限制65536 kB 代码长度限制16000 B An AVL tree is a self-balancing binary search tree. In an AVL tree, the heights of the two child subtrees of any node differ by at most one; if at any time they differ by more tha