二叉树搜索概念:http://baike.baidu.com/link?url=RK7ax6iDk2wiEzUxjKBfyOTcYKLgaDuAcyih0a6qjAewfYeK9PoIhWzjdSZl7ylwhkOdx-6ZCFhGuF0aIG1phG-X2sc9QP8KFWavC95c-ocAL9cs71wZhCOHVHsdRs3Ugr1Z85Iycv1zosbpZiRHea
.H:
//尾递归可以用一个while循环很轻易解决!
template<class T>
class BinarySearchTree
{
public:
BinarySearchTree( )
:_root(NULL)
{}
~BinarySearchTree( )
{
MakeEmpty( );
}
const T& FindMin( ) const
{
Node* ret = _FindMin( _root );
if ( NULL == ret ) //这样写可以吗?调用T类型默认构造函数
{
return T( );
}
else
{
return ret->_data;
}
}
const T& FindMax( ) const
{
Node* ret = _FindMax( _root );
if ( NULL == ret ) //这样写可以吗?调用T类型默认构造函数
{
return T( );
}
else
{
return ret->_data;
}
}
bool IsEmpty( ) const
{
return (NULL == _root) ? true : false;
}
bool Contains( const T& x ) const
{
return _Contains( x, _root );
}
void PrintTree( )const //采用中序遍历打印树
{
_PrintTree( _root );
}
void MakeEmpty( )
{
_MakeEmpty( _root );
}
void Insert( const T& x )
{
_Insert( x, _root );
}
void Remove( const T& x )
{
_Remove( x, _root );
}
const BinarySearchTree& operator=( const BinarySearchTree& rhs )
{
if ( this != &rhs )
{
MakeEmpty( );
_root = Clone( rhs._root );
}
return *this;
}
private:
struct Node
{
T _data;
Node* _leftChild;
Node* _rightChild;
Node( const T& x, Node* leftChild, Node* rightChild )
:_data(x)
,_leftChild(leftChild)
,_rightChild(rightChild)
{}
}; //别忘了;
Node* _root;
void _Insert( const T& x, Node*& root )//想, 它是怎么链起来的, 因为下一个root是 它父亲的左或右孩子的引用, 如果传引用, new后,它的父亲的左右孩子就被链起来了。 否则的话, 临时变量, 孩子被new值赋予后不会影响到调用它的函数的值(父亲的左or右孩子的值)
{
if ( NULL == root )
{
root = new Node( x, NULL, NULL );
}
else if ( x < root->_data )
{
_Insert( x, root->_leftChild );
}
else if ( x > root->_data )
{
_Insert( x, root->_rightChild );
}
else
{
; //相等,目前什么都不做,当然,也可以更新值什么的.
}
}
void _Remove( const T& x, Node*& root ) //注意此时指针为引用
{
if ( NULL == root )
{
return;
}
else if ( x < root->_data )
{
_Remove( x, root->_leftChild );
}
else if ( x > root->_data )
{
_Remove( x, root->_rightChild );
}
else if ( (NULL != root->_leftChild) && (NULL != root->_rightChild) )//两个孩子为一种情况
{
root->_data = _FindMin( root->_rightChild )->_data;
_Remove( root->_data, root->_rightChild );
}
else
{
Node* oldNode = root;
root = (NULL == root->_leftChild ? root->_rightChild : root->_leftChild);
delete oldNode;
} //一个孩子,或叶子节点 归为一种情况
}
Node* _FindMin( Node* root ) const
{
if ( NULL == root )
{
return NULL;
}
if ( NULL == root->_leftChild )
{
return root;
}
return _FindMin( root->_leftChild );
}
Node* _FindMax( Node* root ) const
{
if ( NULL != root )
{
while ( NULL != root->_rightChild )
{
root = root->_rightChild;
}
}
return root;
}
bool _Contains( const T& x, Node* root ) const
{
if ( NULL == root )
{
return false;
}
else if ( x < root->_data )
{
return _Contains( x, root->_leftChild );
}
else if ( x > root->_data )
{
return _Contains( x, root->_rightChild );
}
else
{
return true;
}
//利用while循环代替尾递归(递归语句在结尾)
//while ( NULL != root )
//{
// if ( x < root->_data )
// {
// root = root->_leftChild;
// }
// else if ( x > root->_data )
// {
// root = root->_rightChild;
// }
// else
// {
// return true;
// }
//}
//return false; //只要跳出循环,肯定没找到
}
void _MakeEmpty( Node*& root ) const
{
if ( NULL == root )
{
;
}
else
{
_MakeEmpty( root->_leftChild ); //后序删除
_MakeEmpty( root->_rightChild );
delete root;
}
root = NULL; //别忘了置NULL
}
void _PrintTree( Node* root ) const //中序
{
if ( NULL == root )
{
return;
}
_PrintTree( root->_leftChild );
cout << root->_data << " ";
_PrintTree( root->_rightChild );
}
Node* Clone( Node* root ) const
{
if ( NULL == root )
{
return NULL;
}
else
{
return ( new Node(root->_data, Clone(root->_leftChild), Clone(root->_rightChild)) );
}
}
};
#include <iostream>
#include <windows.h>
using namespace std;
#include "BinarySearchTree.h"
void test( );
int main( )
{
test( );
system( "pause" );
return 0;
}
void test( )
{
BinarySearchTree<int> t1;
int a[] = { 5, 3, 4, 1, 7, 8, 2, 6, 0, 9 };
for ( size_t i = 0; i < (sizeof(a) / sizeof(a[0])); ++i )
{
t1.Insert( a[i] );
}
t1.PrintTree( );
cout << endl;
cout << t1.FindMin( ) << " " << t1.FindMax( ) << " " << endl;
/*t1.MakeEmpty( );
cout << t1.FindMin( ) << " " << t1.FindMax( ) << " " << endl;*/
cout << t1.IsEmpty( ) << endl;
cout << t1.Contains( 77 ) << endl;
cout << t1.Contains( 7 ) << endl;
t1.Remove( 9 );
t1.PrintTree( );
cout << endl;
t1.Remove( 5 );
t1.PrintTree( );
cout << endl;
t1.Remove( 0 );
t1.Remove( 7 );
t1.Remove( 6 );
t1.Remove( 4 );
t1.Remove( 3 );
t1.Remove( 2 );
t1.Remove( 1 );
t1.Remove( 8 );
t1.PrintTree( );
}