您的位置:首页 > 编程语言 > C语言/C++

c++模板类递归实现二叉搜索树及其基本操作

2017-04-06 10:50 507 查看
二叉树搜索概念: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)) );
}
}
};


.cpp:

#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( );
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息