泛型Binary Search Tree实现,And和STL map比较的经营业绩

泛型Binary Search Tree实现,And和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_
#define _BINARY_SEARCH_TREE_H_

#include <functional>
#include <algorithm>
#include <iostream>
#include <map>

#include "windows.h"


template<class T, class V, class Cmp = std::less<T> > 
class BinarySearchTree
{
public:

	// node struct
	typedef struct tagBSNode
	{
		T    key;
		V    value;
		tagBSNode*  leftNode;
		tagBSNode*  rightNode;

		tagBSNode():key(), value(),
			        leftNode(0),
					rightNode(0)
		{

		}

		tagBSNode( const T& _key, const V& _value ):key(_key), 
			                                        value(_value),
													leftNode(0),
													rightNode(0)
		{

		}

	}BSTNode, *pBSTNode;


	/*
	* Constructor
	*
	*/
	BinarySearchTree():m_root(0), m_size(0)
	{

	}

	/*
	* Copy constructor
	*
	*/
	BinarySearchTree( const BinarySearchTree& rhs )
	{
		m_root = Clone( rhs.m_root );
		m_size = rhs.m_size;
	}

	/*
	* Destructor
	*
	*/
	~BinarySearchTree()
	{
		Clear();
	}

	/*
	* assignment operator overload
	*
	*/
	BinarySearchTree& operator = ( const BinarySearchTree& rhs )
	{
		if( this != &rhs )
		{
			Clear();

			m_root = Clone( rhs.m_root );
			m_size = rhs.m_size;
		}

		return *this;
	}

	/*
	* Clear all node 
	*
	*/
	void Clear()
	{
		Clear( m_root );
		m_size = 0;
	}

	/*
	* check whether or not empty
	*
	*/
	bool IsEmpty() const 
	{
		return m_size == 0;
	}

	/*
	* Retrieve the number of node in tree
	*
	*/
	size_t Size() const 
	{
		return m_size;
	}

	/*
	*
	*
	*/
	size_t GetSize() const  // only for test
	{
		return Size( m_root );
	}

	/*
	* Insert key and value pair to tree
	*
	*/
	void Insert( const T& key, const V& value )
	{
		Insert( m_root, key, value );
	}

	/*
	* Delete node from tree for given key
	*
	*/
	void Delete( const T& key )
	{
		Delete( m_root, key );
	}

	/*
	* Find element from tree for given key
	*
	*/
	V* Find( const T& key )
	{
		pBSTNode node = Find( m_root, key );
		if( node )
			return &node->value;

		return 0;
	}

	/*
	* Find the the element of max key 
	*
	*/
	V* FindMax( T& key )
	{
		pBSTNode node = FindMax( m_root );
		if( node )
		{
			key = node->key;
			return &node->value;
		}

		return 0;
	}

	/*
	* Find the the element of min key 
	*
	*/
	V* FinMin( T& key )
	{
		pBSTNode node = FindMin( m_root );
		if( node )
		{
			key = node->key;
			return &node->value;
		}

		return 0;
	}

	/*
	* inoder traversal
	*
	*/
	void InorderVisitor( void (*visitor)( const T&, const V& ) )
	{
		InorderVisitor( m_root, visitor );
	}

	/*
	* preoder traversal
	*
	*/
	void PreOrderVisitor( void (*visitor)( const T&, const V&  )  )
	{
		PreOrderVisitor( m_root, visitor );
	}

	/*
	* postoder traversal
	*
	*/
	void PostOrderVisitor( void (*visitor)( const T&, const V& ) )
	{
		PostOrderVisitor( m_root, visitor );
	}

protected:

	/*
	* Implement clone operation
	*
	*/
	pBSTNode Clone( pBSTNode root )
	{
		if( 0 == root )
			return root;

		pBSTNode node = new BSTNode( root->key, root->value );
		node->leftNode = Clone( root->leftNode );
		node->rightNode = Clone( root->rightNode );

		return node;
	}

	/*
	* Implement clear opreation
	*
	*/
	void Clear( pBSTNode& root )
	{
		if( 0 == root )
			return;

		Clear( root->leftNode );
		Clear( root->rightNode );

		delete root;
		root = 0;

	}


	/*
	* Retrieve the number of node by way of recursive
	*
	*/
	size_t Size( pBSTNode root ) const 
	{
		if( 0 == root )
			return 0;

		return 1 + Size( root->leftNode ) + Size( root->rightNode );
	}

	/*
	* Implement insert operation
	*
	*/
	void Insert( pBSTNode& root,const T& key, const V& value )
	{
		if( 0 == root )
		{
			root = new BSTNode( key, value );
			m_size++;
		}

		if( root->key < key )
		{
			Insert( root->rightNode, key, value );
		}
		else if( root->key > key )
		{
			Insert( root->leftNode, key, value );
		}
	}

	/*
	* Implement delete operation
	*
	*/
	void Delete( pBSTNode& root, const T& key )
	{
		if( 0 == root )
			return;

		if( root->key < key )
		{
			Delete( root->rightNode, key );
		}
		else if( root->key > key )
		{
			Delete( root->leftNode, key );
		}
		else
		{
			if( root->leftNode && root->rightNode )
			{
				pBSTNode minNode = FindMin( root->rightNode );
				root->key  = minNode->key;
				root->value = minNode->value;

				Delete( root->rightNode,  minNode->key );
			}
			else 
			{
				pBSTNode node = root;
				root = root->leftNode ? root->leftNode: root->rightNode;

				delete node;
				node = 0;

				m_size--;  //very important
				
			}

			
		}
	}


	/*
	* Implement find operation
	*
	*/
	pBSTNode Find( pBSTNode root, const T& key )
	{
		if( 0 == root )
			return root;

		if( root->key < key )
		{
			return Find( root->rightNode, key );
		}
		else if( root->key > key )
		{
			return Find( root->leftNode, key );
		}
		else
		{
			return root;
		}
	}

	/*
	* Find implement no recursive
	*
	*/
	pBSTNode FindUtil( pBSTNode root, const T& key )
	{
		if( 0 == root )
			return root;

		pBSTNode cur = root;
		while( root )
		{
			cur = root;
			if( root->key < key )
			{
				root = root->rightNode;
			}
			else if( root->key > key )
			{
				root = root->leftNode;
			}
			else
			{
				break;
			}	
		}

		if( cur  && cur->key == key )
			return cur;

		return 0;
	}


	/*
	* Implement find max element operation
	*
	*/
	pBSTNode FindMax( pBSTNode root )
	{
		if( 0 == root )
			return root;

		while( root->rightNode )
		{
			root = root->rightNode;
		}

		return root;
	}

	/*
	* Implement find min element operation
	*
	*/
	pBSTNode FindMin( pBSTNode root )
	{
		if( 0 == root )
			return root;

		while( root->leftNode )
		{
			root = root->leftNode;
		}

		return root;
	}


	/*
	* Implement inorder traversal
	*
	*/
	void InorderVisitor( pBSTNode root, void (*visitor)( const T&, const V& ) )
	{
		if( 0 == root )
			return;

		InorderVisitor( root->leftNode, visitor );
		visitor( root->key, root->value );
		InorderVisitor( root->rightNode, visitor );
	}

	/*
	* Implement preorder traversal
	*
	*/
	void PreOrderVisitor( pBSTNode root, void (*visitor)( const T&, const V& )  )
	{
		if( 0 == root )
			return;

		visitor( root->key, root->value );
		InorderVisitor( root->leftNode, visitor );
		InorderVisitor( root->rightNode, visitor );
	}

	/*
	* Implement postorder traversal
	*
	*/
	void PostOrderVisitor( pBSTNode root, void (*visitor)( const T&, const V& ) )
	{
		if( 0 == root )
			return;

		InorderVisitor( root->leftNode, visitor );		
		InorderVisitor( root->rightNode, visitor );
		visitor( root->key, root->value );
	}

protected:

	pBSTNode  m_root;

	size_t    m_size;
};


/*
* Test STL map
*
*/
void TestSTLMapBST()
{
	const int Len = 200000;
	//int key[Len];
	//int value[Len];

	int* key = new int[Len];
	int* value = new int[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 );

	delete [] key;
	delete [] value;

}




/*
* vistior function for output information when traversal tree
*
*/
template<class T, class V>
void Visitor( const T& key, const V& value )
{
	std::cout << "key: "  << key << "," <<"value: " << value << std::endl;
}


/*
* unit test
*
*/
void TestBST()
{
	const int Len = 200000;
	//int key[Len];
	//int value[Len];

	int* key = new int[Len];
	int* value = new int[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();

	BinarySearchTree<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.FinMin( minKey );
	assert( minKey == 0 );

	int maxKey = -1;
	int* maxValue = treeObj.FindMax( maxKey );
	assert( maxKey == Len - 1 );

	size_t size = treeObj.Size();
	assert(  size == Len );

	int flagCount = 0;
	for( int i = 0; i < Len; i++ )
	{
		if( !(i % 15) )
		{
			treeObj.Delete( i );
			int* val = treeObj.Find( i );
			assert( !val );

			flagCount++;
		}
	}

	unsigned long interval = GetTickCount() - start;
	printf( " binary search tree consume time is %d \n", interval );

	size = treeObj.Size();
	size_t count = treeObj.GetSize();

	BinarySearchTree<int, int> newTreeObj;
	for( int i = 0; i < 10; i++ )
	{
		newTreeObj.Insert( key[i], value[i] );
	}

	treeObj = newTreeObj;
	newTreeObj.Clear();

	std::cout<< "begin inorder traversal " << std::endl;
	treeObj.InorderVisitor( Visitor<int, int> );

	std::cout<< "begin postorder traversal " << std::endl;
	treeObj.PostOrderVisitor( Visitor<int, int> );

	std::cout<< "begin preorder traversal " << std::endl;
	treeObj.PreOrderVisitor( Visitor<int, int> );

	treeObj.Clear();


	delete [] key;
	delete [] value;
}


void TestBSTSuite()
{
	TestSTLMapBST();
	TestBST();
}



#endif 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/116647.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • clipper使用

    clipper使用一、clipper使用的redis库说明enumRedisDBTable{REDIS_STATE_DB_NUM=1,REDIS_MODEL_DB_NUM=2,REDIS_CONTAINER_DB_NUM=3,REDIS_RESOURCE_DB_NUM=4,REDIS_APPLICATION_DB_NUM=5,REDIS_METADATA_DB_NUM=6,//usedtostoreClipperconfigurationmetadat

    2025年8月23日
    6
  • java volatile详解

    java volatile详解本篇来自java并发编程实战关于volatile的总结。要说volatile,先得明白内存可见性。那我们就从内存可见性说起。一、内存可见性可见性是一种复杂的属性,因为可见性中的错误总是会违背我们的直觉。在单线程环境中,如果向某个变量先写入值,然后在没有其他写入操作的情况下读取这个变量,那么总能得到相同的值。这看起来很自然。然而,当读操作和写操作在不同的线程中执行时,情况却并非如此,这听

    2022年7月18日
    21
  • jvm常量池和字符串常量池_常量池中的字符串是对象吗

    jvm常量池和字符串常量池_常量池中的字符串是对象吗JVM——字符串常量池详解引言在Java开发中不管是前后端交互的JSON串,还是数据库中的数据存储,我们常常需要使用到String类型的字符串。作为最常用也是最基础的引用数据类型,JVM为String提供了字符串常量池来提高性能,本篇文章我们一起从底层JVM中认识并学习字符串常量池的概念和设计原理。字符串常量池由来在日常开发过程中,字符串的创建是比较频繁的,而字符串的分配和其他对象的分配是类似的,需要耗费大量的时间和空间,从而影响程序的运行性能,所以作为最基础最常用的引用数据类型,Java设计者在

    2022年7月28日
    4
  • ya系列圆振动筛_L型厨房设计好不好

    ya系列圆振动筛_L型厨房设计好不好‘资料下载链接’:https://download.csdn.net/download/dwf1354046363/21778034YAH2460型圆振动筛设计摘要目前我国各种选煤厂使用的设备中,振动筛(筛分机)是问题较多、维修量较大的设备之一。这些问题突出表现在筛箱断梁、裂帮、稀油润滑的箱式振动器漏油、齿轮打齿、轴承温升过高、噪声过大等问题,同时伴有传动带跳带、断带等故障。这类问题直接影响了振动筛(筛分机)的使用寿命,严重影响了生产。YAH—2460型圆振动筛可以很好的解决此类问题,因此本

    2022年10月2日
    2
  • 国产数据库乱象_四代户户通怎么开户

    国产数据库乱象_四代户户通怎么开户其实这篇文章是我周末开始写的,写这篇文章的这个周末,我的很多时候都是在思考一个数据库国产化替代的建设方案,翻阅了大量的资料。今年正好是我参加工作后的第31个年头,工作的最初十年,我写了十年代码,从汇编、COBOL到C语言,写了几十万行代码;随后的十几年,我一直在帮助用户用好数据库,也在帮助Oracle推广RAC技术;2015年开始,我一边继续从事数据库优化的工作,一边在帮助客户如何从Oracle迁移到成本更低的数据库系统上。所以对国产数据库我一直有一种十分特殊的情感,这是一种爱恨交织的情感。所以今天最后用“

    2022年9月19日
    2
  • ghost备份还原详细步骤_ghost一键备份还原

    ghost备份还原详细步骤_ghost一键备份还原注意点1:整个过程中不可动鼠标,使用键盘和触摸板操作。开始备份或还原后中不要动键盘备份从大白菜系统盘等方法进入GHOST依次进入Local→Partition(分区)→ToImage(到镜像文件)选择备份分区所在磁盘选择分区选择储存分区,写文件名字注意点2:移动备份后的文件极易造成文件的损坏,所以这里的位置一定要选好,之后不要移动位置选择压缩率(一般…

    2025年9月19日
    4

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号