问题叙述性说明:

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

泛型Binary Search Tree实现,And和STL map比较的经营业绩的更多相关文章

  1. [数据结构]——二叉树(Binary Tree)、二叉搜索树(Binary Search Tree)及其衍生算法

    二叉树(Binary Tree)是最简单的树形数据结构,然而却十分精妙.其衍生出各种算法,以致于占据了数据结构的半壁江山.STL中大名顶顶的关联容器--集合(set).映射(map)便是使用二叉树实现 ...

  2. 二叉搜索树(Binary Search Tree)(Java实现)

    @ 目录 1.二叉搜索树 1.1. 基本概念 1.2.树的节点(BinaryNode) 1.3.构造器和成员变量 1.3.公共方法(public method) 1.4.比较函数 1.5.contai ...

  3. Leetcode 笔记 99 - Recover Binary Search Tree

    题目链接:Recover Binary Search Tree | LeetCode OJ Two elements of a binary search tree (BST) are swapped ...

  4. Leetcode 笔记 98 - Validate Binary Search Tree

    题目链接:Validate Binary Search Tree | LeetCode OJ Given a binary tree, determine if it is a valid binar ...

  5. Leetcode: Convert sorted list to binary search tree (No. 109)

    Sept. 22, 2015 学一道算法题, 经常回顾一下. 第二次重温, 决定增加一些图片, 帮助自己记忆. 在网上找他人的资料, 不如自己动手. 把从底向上树的算法搞通俗一些. 先做一个例子: 9 ...

  6. [LeetCode] Closest Binary Search Tree Value II 最近的二分搜索树的值之二

    Given a non-empty binary search tree and a target value, find k values in the BST that are closest t ...

  7. [LeetCode] Closest Binary Search Tree Value 最近的二分搜索树的值

    Given a non-empty binary search tree and a target value, find the value in the BST that is closest t ...

  8. [LeetCode] Verify Preorder Sequence in Binary Search Tree 验证二叉搜索树的先序序列

    Given an array of numbers, verify whether it is the correct preorder traversal sequence of a binary ...

  9. [LeetCode] Lowest Common Ancestor of a Binary Search Tree 二叉搜索树的最小共同父节点

    Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BS ...

随机推荐

  1. ALV调用的几个标准函数

    ALV的调用主要由以下几个标准函数实现,所有函数的输入输出参数必须大写,否则系统会出现异常中止,相关函数如下: 1)REUSE_ALV_FIENDCATALOG_MERGE:根据内表结构返回FIELD ...

  2. tomcat path设置

    zjtest7-app:/usr/local/apache-tomcat-7.0.55_8082/logs# netstat -nap | grep 8082 tcp 0 0 :::8082 :::* ...

  3. <摘录>详谈高性能UDP服务器的开发

    上一篇文章我详细介绍了如何开发一款高性能的TCP服务器的网络传输层.本章我将谈谈如何开发一个高性能的UDP服务器的网络层.UDP服务器的网络层开 发相对与TCP服务器来说要容易和简单的多,UDP服务器 ...

  4. Esper学习之四:Context

    上周末打球实在太累了,就没来得及更新,只是列了个提纲做做准备,发现Context还是有很多内容的.结果也花了不少时间才写完,所以这篇需要各位慢慢消化,并且最好多写几个例子加深理解. 如果有不了解Esp ...

  5. HttpSession具体解释

    session的机制 http是无状态的协议,客户每次读取web页面时,server都打开新的会话,并且server也不会自己主动维护客户的上下文信息,那么要怎么才干实现会话跟踪呢?session就是 ...

  6. [iOS]简单的APP引导页的实现 (Swift)

    在第一次打开APP或者APP更新后通常用引导页来展示产品特性 我们用NSUserDefaults类来判断程序是不是第一次启动或是否更新,在AppDelegate.swift中加入以下代码: func ...

  7. WPF入门介绍

    Windows Vista已经于2007年1月30正式发行零售版本,安装Vista的计算机将会大量出现.在Vista时代,身为编程员,就一定要具备Vista桌面应用开发的能力.而开发Vista桌面应用 ...

  8. DMP文件的生成和使用

    1.生成dmp的程序 #include  <dbghelp.h> #pragma comment(lib,  "dbghelp.lib") //设置异常处理回调函数Se ...

  9. linux cent os putty 问题彻底解决办法

    出现乱码的根本原因: linux系统和putty使用的编码格式不一致. 解决办法: 1.首先使用命令查看linux当前使用的是什么编码格式 echo $LANG 返回的结果有如下几种情况:1)zh_C ...

  10. cocos2d-x中使用JNI的调用JAVA方法

    用cocos2d-x公布Android项目时.都应该知道要用JAVA与C/C++进行交互时会涉及到JNI的操作(Java Native Interface).JNI是JAVA的一个通用接口.旨在本地化 ...