动态查找表的特点是表结构本身是在查找过程中动态生成的。二叉排序树的定义是:或者是一颗空树,或者是具有下列性质的二叉树:(1)若它的左子树不空,则左子树上所有结点的值均小于它的根节点的值;(2)若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;(3)它的左右子树也分别是二叉排序树。可以用二叉链表作为二叉排序树的存储结构。程序实现如下:
/*****************************静态查找表的建立及顺序查找操作******************************/
//by vipper.zhang 2011.7.11 如果有什么问题或者可以改进的建议,请发邮件至vipper.zhang@gmail.com
//O(∩_∩)0
#include <iostream>
using namespace std;
typedef int KeyType;
//二叉链表存储二叉查找树结点
typedef struct BSTNode{
KeyType key;
BSTNode *lchild,*rchild;
}*BSTree;
//查找元素
bool SearchBST(BSTree bst,KeyType key,BSTree f,BSTree &p) //f为bst双亲,p返回等于key的结点
{
if(!bst)
{
p=f;
return false;
}
else if((bst->key)==key)
{
p=bst;
return true;
}
else if((bst->key) >key) return SearchBST(bst->lchild,key,bst,p);
else if((bst->key) <key) return SearchBST(bst->rchild ,key,bst,p);
}
//插入元素
bool InsertBST(BSTree &bst,KeyType key)
{
BSTree p=new BSTNode;
if(!SearchBST(bst,key,NULL,p))
{
BSTree s=new BSTNode();
s->key =key;
s->lchild =s->rchild =NULL;
if(!p) bst=s;
else if(key< p->key)
p->lchild=s;
else if(key>p->key)
p->rchild=s;
return true;
}
return false;
}
//创建二叉排序树
void CreateBST(BSTree &bst)
{
KeyType key;
while (cin>>key)
{
if(key==-1)
break;
else
InsertBST(bst,key);
}
}
BSTree GetFather(BSTree bst,BSTree p)
{
if(bst==NULL||p==bst)
return NULL;
else if(bst->lchild ==p||bst->rchild==p)
return bst;
else if(bst->key <p->key)
{
GetFather(bst->rchild ,p);
}
else if(bst->key >p->key )
GetFather(bst->lchild ,p);
}
//删除结点
bool DeleteBST(BSTree &bst,KeyType key)
{
BSTree p,q,s,f;
p=bst;
if(!bst)
{
cout<<"bst tree does not exit"<<endl;
return false;
}
do //找到关键字所在结点p
{
if(p->key==key)
{
break;
}
else if(bst->key >key)
p=p->lchild ;
else if(bst->key <key)
p=p->rchild;
}while(p);
if(p==NULL)
{
cout<<"no such element "<<endl;
return false;
}
else{
f=GetFather(bst,p); //找到p结点的父亲结点
if(!p->lchild&&(!p->rchild)&&f!=NULL) //p是叶子结点, 且不是根结点
{
if(f->lchild ==p)
{
delete p;
f->lchild =NULL;
}
else
{
delete p;
f->rchild =NULL;
}
return true;
}
if(!p->lchild && !p->rchild && f==NULL) //p是叶子结点, 且是根结点
{
bst=NULL;
delete p;
return true;
}
if(!p->lchild&&f!=NULL) //p左孩子为空结点,且不是根结点
{
q=p;
p=p->rchild;
delete q;
f->rchild =p;
return true;
}
if(!p->lchild&&f==NULL) //p左孩子为空结点,且p是根结点
{
q=p;
p=p->rchild;
bst=p;
delete q;
return true;
}
if(!p->rchild&&f!=NULL) //p右孩子为空结点,且不是根结点
{
q=p;
p=p->lchild ;
delete q;
f->lchild =p;
return true;
}
if(!p->rchild&&f==NULL) //p右孩子为空结点,且是根结点
{
q=p;
p=p->lchild ;
bst=p;
delete q;
return true;
}
else if(p->lchild &&p->rchild ) //p的两个子树都不空
{
q=p;
s=p->lchild ;
while(s->rchild){q=s;s=s->rchild ;}
p->key =s->key ;
if(q!=p)
q->rchild =s->lchild ;
else
q->lchild =s->lchild ;
delete s;
}
}
return true;
}
//中序遍历并输出所有结点
void PrintBST(BSTree bst)
{
if(!bst)
cout<<"n\t";
else
{
PrintBST(bst->lchild);
cout<<bst->key<<"\t";
PrintBST(bst->rchild);
}
}
int main()
{
BSTree bst=new BSTNode; //查了半天错误,原来是没有为其分配内存,导致读取内存错误
bst->key=0;
bst->lchild=bst->rchild =NULL;
cout<<"input the element of the bst, -1 finish : "<<endl;
CreateBST(bst);
PrintBST(bst); cout<<endl;
DeleteBST(bst,6);
PrintBST(bst); cout<<endl;
//BSTree f=GetFather(bst,bst->rchild ->rchild );
//cout<<f->key<<" "<<endl;
system("pause");
return 0;
}
测试用例:1 2 3 4 5 6 7 -1
5 3 2 4 6 7 -1