问题描述:
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
时间: 2024-10-10 08:21:50