二叉搜索树又叫二叉排序树、二叉查找树,便于排序和查找,其性质如下:
(1)非空左子树的所有键值小于其根结点的键值;
(2)非空右子树的所有键值大于其根结点的键值;
(3)左、右子树都是二叉搜索树。
关于二叉搜索树的主要操作有:
- 动态查找:找元素X、最大元素、最小元素
- 插入元素
- 删除元素
一、动态查找
(一)查找元素X
若结点键值等于X,返回指向此结点的指针;
若结点键值小于X,在该结点左子树查找;
若结点键值大于X,在该节点右子树查找。
递归实现:
/*二叉搜索树查找的递归算法*/
BinTree *RecurFind(BinTree *BST,ElementType X)
{
if(!BST)
return NULL;
if(X>BST->data)
return(RecurFind(BST->Right,X));
else if(X<BST->data)
return(RecurFind(BST->Left,X));
else
return(BST);
}
非递归的迭代实现:
/*二叉搜索树查找的非递归算法*/
BinTree *NonRecurFind(BinTree *BST,ElementType X)
{
if(!BST)
return NULL;
while(BST){
if(X>BST->data)
BST=BST->Right;
else if(X<BST->data)
BST=BST->Left;
else
break;
}
return(BST);
}
(二)查找最大元素
最大元素在二叉搜索树最右分支的端结点上,所以一直往右直到遇到空指针即可。
递归实现:
/*递归查找最大元素*/
BinTree *RecurFindMax(BinTree *BST)
{
if(!BST)
return NULL;
else if(!BST->Right)
return(BST);
else
return(RecurFindMax(BST->Right));
}
非递归的迭代实现:
/*迭代查找最大元素*/
BinTree *NonRecurFindMax(BinTree *BST)
{
if(BST)
while(BST->Right)
BST=BST->Right;
return(BST);
}
(三)查找最小元素
最小元素在二叉搜索树最左分支的端结点上,所以一直往左直到遇到空指针即可。
递归实现:
/*递归查找最小元素*/
BinTree *RecurFindMin(BinTree *BST)
{
if(!BST)
return NULL;
else if(!BST->Left)
return(BST);
else
return(RecurFindMin(BST->Left));
}
非递归的迭代实现:
/*迭代查找最小元素*/
BinTree *NonRecurFindMin(BinTree *BST)
{
if(!BST)
return NULL;
while(BST->Left){
BST=BST->Left;
}
return(BST);
}
二、插入
插入元素X的关键是找到X插入的位置。若在二叉搜索树中找到X,说明X已存在,可放弃插入操作;否则查找终止的位置就是X应插入的位置。
/*二叉搜索树的插入
若用此函数创建一棵搜索二叉树,在第一次调用前,需BST=NULL*/
BinTree *Insert(BinTree *BST,ElementType X)
{
if(!BST){
BST=new BinTree;
BST->data=X;
BST->Left=BST->Right=NULL;
}
else if(BST->data>X)
BST->Left=Insert(BST->Left,X);
else if(BST->data<X)
BST->Right=Insert(BST->Right,X);
else;
return(BST);
}
三、删除
删除的结点为BST结点的子结点;
删除的结点为BST结点的子结点(BST结点有两个子结点;BST结点有一个子结点或没有子结点)。
/*二叉搜索树删除操作*/
BinTree *Delete(BinTree *BST,ElementType X)
{
BinTree *Tmp;
if(!BST){
cout<<"未找到要删除的元素"<<endl;
return(BST);
}
if(BST->data>X)
Delete(BST->Left,X);
else if(BST->data<X)
Delete(BST->Right,X);
else{
if(BST->Left && BST->Right){
Tmp=NonRecurFindMin(BST->Right);
BST->data=Tmp->data;
BST=Delete(BST->Right,BST->data);
}
else{
Tmp=BST;
if(!BST->Left)
BST=BST->Right;
else
BST=BST->Left;
delete(Tmp);
}
}
return(BST);
}
以下是一个可直接运行的完整程序:
按从一至十二月的顺序输入一年十二个月的英文缩写,产生一棵搜索二叉树,查找其中的Feb值、最小键值和最大键值,删除并不存在的Leo值。
#include <iostream>
#define NoInfo "000"
using namespace std;
typedef string ElementType;
/*定义二叉树结点类型*/
typedef struct BinNode
{
ElementType data;
BinNode *Left;
BinNode *Right;
}BinTree;
BinTree *RecurFind(BinTree *BST,ElementType X);
BinTree *NonRecurFind(BinTree *BST,ElementType X);
BinTree *RecurFindMin(BinTree *BST);
BinTree *NonRecurFindMin(BinTree *BST);
BinTree *RecurFindMax(BinTree *BST);
BinTree *NonRecurFindMax(BinTree *BST);
BinTree *Insert(BinTree *BST,ElementType X);
BinTree *Delete(BinTree *BST,ElementType X);
int main()
{
BinTree *BST,*T;
BST=NULL;
ElementType x;
cout<<"输入:"<<endl;
cin>>x;
while(x!=NoInfo){
BST=Insert(BST,x);
cin>>x;
}
cout<<"输出:"<<endl;
T=RecurFind(BST,"Feb");
cout<<"查找:"<<T->data<<endl;
T=NonRecurFindMin(BST);
cout<<"最小键值:"<<T->data<<endl;
T=NonRecurFindMax(BST);
cout<<"最大键值:"<<T->data<<endl;
cout<<"查找Leo:";
BST=Delete(BST,"Leo");
return 0;
}
/*二叉搜索树查找的递归算法*/
BinTree *RecurFind(BinTree *BST,ElementType X)
{
if(!BST)
return NULL;
if(X>BST->data)
return(RecurFind(BST->Right,X));
else if(X<BST->data)
return(RecurFind(BST->Left,X));
else
return(BST);
}
/*二叉搜索树查找的非递归算法*/
BinTree *NonRecurFind(BinTree *BST,ElementType X)
{
if(!BST)
return NULL;
while(BST){
if(X>BST->data)
BST=BST->Right;
else if(X<BST->data)
BST=BST->Left;
else
break;
}
return(BST);
}
/*递归查找最小元素*/
BinTree *RecurFindMin(BinTree *BST)
{
if(!BST)
return NULL;
else if(!BST->Left)
return(BST);
else
return(RecurFindMin(BST->Left));
}
/*迭代查找最小元素*/
BinTree *NonRecurFindMin(BinTree *BST)
{
if(!BST)
return NULL;
while(BST->Left){
BST=BST->Left;
}
return(BST);
}
/*递归查找最大元素*/
BinTree *RecurFindMax(BinTree *BST)
{
if(!BST)
return NULL;
else if(!BST->Right)
return(BST);
else
return(RecurFindMax(BST->Right));
}
/*迭代查找最大元素*/
BinTree *NonRecurFindMax(BinTree *BST)
{
if(BST)
while(BST->Right)
BST=BST->Right;
return(BST);
}
/*二叉搜索树的插入
若用此函数创建一棵搜索二叉树,在第一次调用前,需BST=NULL*/
BinTree *Insert(BinTree *BST,ElementType X)
{
if(!BST){
BST=new BinTree;
BST->data=X;
BST->Left=BST->Right=NULL;
}
else if(BST->data>X)
BST->Left=Insert(BST->Left,X);
else if(BST->data<X)
BST->Right=Insert(BST->Right,X);
else;
return(BST);
}
/*二叉搜索树删除操作*/
BinTree *Delete(BinTree *BST,ElementType X)
{
BinTree *Tmp;
if(!BST){
cout<<"未找到要删除的元素"<<endl;
return(BST);
}
if(BST->data>X)
Delete(BST->Left,X);
else if(BST->data<X)
Delete(BST->Right,X);
else{
if(BST->Left && BST->Right){
Tmp=NonRecurFindMin(BST->Right);
BST->data=Tmp->data;
BST=Delete(BST->Right,BST->data);
}
else{
Tmp=BST;
if(!BST->Left)
BST=BST->Right;
else
BST=BST->Left;
delete(Tmp);
}
}
return(BST);
}
运行结果: