您的位置:首页 > 其它

动态查找表--二叉排序树的实现

2011-07-11 21:05 232 查看
动态查找表的特点是表结构本身是在查找过程中动态生成的。二叉排序树的定义是:或者是一颗空树,或者是具有下列性质的二叉树:(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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: