二叉查找树 模板实现 C++
1、二叉查找树的性质:对于树中每个结点X,它的左子树中所有项的值小于X中的值,而它的右子树中所有项的值大于X中的值。
2、二叉树的操作主要是:插入,删除,查找。
2.1 查找 contains
实现思路:如果待查找的项X在树中,返回true;否则返回false。若当前比较的结点为T,如果T为空,则返回false;如果X的值小于T的值,则递归查找T的左子树;如果X的值大于T的值,则递归查找T的右子树;如果X的值等于T的值,则返回true。
bool contains(object& x)const{return contains(x,root);}
template<typename object>
bool BinarySearchTree<object>::contains(object& x,BinaryNode* t)const
{
if(t==NULL)
return false;
else if(t->element>x)
contains(x,t->left);
else if(t->element<x)
contains(x,t->right);
else
return true;
}
2.2 插入 insert
实现思路:为了将X插入到树中,可以像使用contains一样沿着树查找,如果找到X,则什么都不做;否则将X插入到遍历的路径上的最后一个节点上。
void insert(const object& x){insert(x,root);}
template<typename object>
void BinarySearchTree<object>::insert(const object& x,BinaryNode*& t)
{
if(t==NULL)
t=new BinaryNode(x,NULL,NULL);
else if(t->element>x)
insert(x,t->left);
else if(t->element<x)
insert(x,t->right);
else
;
}
2.3 删除 remove
实现思路:首先先查找待删除的项X,如果不存在,则删除失败;如果存在,则进行以下操作:
(1)如果节点是一片树叶,则直接删除;
(2)如果节点有一个儿子,则该节点可以在其父节点调整它的链以绕过该节点后被删除。
(3)如果该节点有两个儿子,则用该节点的右子树的最小的数据代替该节点的数据而递归地删除那个节点。
void remove(const object& x){remove(x,root);}
template<typename object>
void BinarySearchTree<object>::remove(const object& x,BinaryNode*& t)
{
if(t==NULL)
return;
if(t->element>x)
remove(x,t->left);
else if(t->element<x)
remove(x,t->right);
else if(t->left!=NULL && t->right!=NULL)
{
t->element=findMin(t->right)->element;
remove(t->element,t->right);
}
else
{
BinaryNode* tmp=t;
t=(t->left!=NULL)?t->left : t->right;
delete tmp;
}
}
3、全部的代码实现如下:
#ifndef BinarySearchTree_H
#define BinarySearchTree_H
#include<iostream>
using namespace std;
template<typename object>
class BinarySearchTree
{
private:
struct BinaryNode
{
object element;
BinaryNode* left;
BinaryNode* right;
BinaryNode(object X,BinaryNode* l,BinaryNode* r):element(X),left(l),right(r){}
};
public:
BinarySearchTree():root(NULL){}
BinarySearchTree(const BinarySearchTree& rhs);
~BinarySearchTree();
bool empty()const;
const object& findMin()const{BinaryNode* t=findMin(root); return t->element;}
const object& findMax()const{BinaryNode* t=findMax(root); return t->element;}
void printTree()const{printTree(root);}
bool contains(object& x)const{return contains(x,root);}
void makeEmpty(){makeEmpty(root);}
void insert(const object& x){insert(x,root);}
void remove(const object& x){remove(x,root);}
const BinarySearchTree& operator =(const BinarySearchTree& rhs);
private:
BinaryNode* root;
BinaryNode* findMin(BinaryNode* t)const;
BinaryNode* findMax(BinaryNode* t)const;
bool contains(object& x,BinaryNode* t)const;
void makeEmpty(BinaryNode*& t);
void insert(const object& x,BinaryNode*& t);
void remove(const object& x,BinaryNode*& t);
BinaryNode* clone(BinaryNode* t);
void printTree(BinaryNode* t)const;
};
template<typename object>
BinarySearchTree<object>::BinarySearchTree(const BinarySearchTree& rhs)
{
root=clone(rhs->root);
}
template<typename object>
BinarySearchTree<object>::~BinarySearchTree(){makeEmpty();}
template<typename object>
bool BinarySearchTree<object>::empty()const{return root==NULL;}
template<typename object>
typename BinarySearchTree<object>::BinaryNode* BinarySearchTree<object>::findMin(BinaryNode* t)const
{
if(t!=NULL)
while(t->left!=NULL)
t=t->left;
return t;
}
template<typename object>
typename BinarySearchTree<object>::BinaryNode* BinarySearchTree<object>::findMax(BinaryNode* t)const
{
if(t!=NULL)
while(t->right!=NULL)
t=t->right;
return t;
}
template<typename object>
void BinarySearchTree<object>::printTree(BinaryNode* t)const
{
if(t==NULL)
return;
printTree(t->left);
cout<<t->element<<" ";
printTree(t->right);
cout<<endl;
}
template<typename object>
bool BinarySearchTree<object>::contains(object& x,BinaryNode* t)const
{
if(t==NULL)
return false;
else if(t->element>x)
contains(x,t->left);
else if(t->element<x)
contains(x,t->right);
else
return true;
}
template<typename object>
void BinarySearchTree<object>::makeEmpty(BinaryNode*& t)
{
if(t!=NULL)
{
makeEmpty(t->left);
makeEmpty(t->right);
delete t;
}
t=NULL;
}
template<typename object>
void BinarySearchTree<object>::insert(const object& x,BinaryNode*& t)
{
if(t==NULL)
t=new BinaryNode(x,NULL,NULL);
else if(t->element>x)
insert(x,t->left);
else if(t->element<x)
insert(x,t->right);
else
;
}
template<typename object>
void BinarySearchTree<object>::remove(const object& x,BinaryNode*& t)
{
if(t==NULL)
return;
if(t->element>x)
remove(x,t->left);
else if(t->element<x)
remove(x,t->right);
else if(t->left!=NULL && t->right!=NULL)
{
t->element=findMin(t->right)->element;
remove(t->element,t->right);
}
else
{
BinaryNode* tmp=t;
t=(t->left!=NULL)?t->left : t->right;
delete tmp;
}
}
template<typename object>
const BinarySearchTree<object>& BinarySearchTree<object>::operator =(const BinarySearchTree& rhs)
{
if(*this!=&rhs)
{
makeEmpty();
root=clone(rhs.root);
}
return *this;
}
template<typename object>
typename BinarySearchTree<object>::BinaryNode* BinarySearchTree<object>::clone(BinaryNode* t)
{
if(t==NULL)
return NULL;
return new BinaryNode(t->element,clone(t->left),clone(t->right));
}
#endif BinarySearchTree_H