二叉排序树是指有以下性质的的二叉树:或者是一颗空树,或者1)它的左子树不为空,则左子树所有关键字都小于根节点的值,2)右子树不空,则右子树所有关键字都大于它根节点的值,它的左右子树都为二叉排序树;
二叉排序树的插入操作:
bool SearchBST(BiTree &T, KeyType key,BiTree f,BiTree &p)
{
//节点T指向二叉排序树递归的查找中关键字与key相等的数据元素,若查找成功,则
//指针p指向该数据节点,返回true,否则指针p指向访问路径中的最后一个节点,返回false
if(!T) {p=f; return false}
else
{
if(EQ(key,T->data) ) {p=T;return true;}
else if(LQ(key,T->data)) {f=T; SearchBST(T->lchild,key,T,p);}
else SearchBST(T->rchild,key,T,p);}
//如果没有查找到,插入key值作为新的节点
bool SearchBST(BiTree &T, KeyType key)
{
BiTree p;
if(!SearchBST(T, key,null,p))
{
s=new BiTree;
s->data=key; s->lchild=s->rchild=null;
if(!p) T=s;
else if(LQ(key,p->data)) p->lchild=s;
else p->rchild=s;
return true;
}
else return false;
}
//二叉排序树的删除操作
删除操作分三种情况进行讨论(假设将要删除节点p为其双亲节点f的左孩子节点):
1)p为叶子节点,则直接删除该节点,修改其双亲节点即可
2)p只有左子树或右子树时,此时只需要直接令p的左子树或右子树成为其双亲节点的左子树(如果p为f的右孩子节点,则p的左子树或右子树成为其双亲节点的右子树)
3)如果p的左右子树都不为空,一种比较容易理解的做法是令p的左子树为其双亲的左子树,p的右子树为“p的左子树按中序遍历最后访问的一个节点”的右子树(即p的直接前驱);另一种做法:p被“p的左子树按中序遍历最后访问的一个节点(即p的直接前驱,暂且用s代替)”替换,第二种方法比较容易实现;
boll DeleteBST(BiTree &T,BiTree f)
{
BiTree p;
if(!T) return false;
else
{
if(EQ(key,T->data)) {p=f; return Delete(T,p);}
else if(LQ(key,T->data)) return DeleteBST(T->lchild,T);
else return DeleteBST(T->rchild,T);
}
}
//查找成功,删除该节点
boll Delete(BiTree &root,BiTree &f)
{
if(!p->rchild) {//右子树空,只需要接它的左子树
q=root; root=root->lchild; f->lchild=p;delete q;
}
else if(!p->lchild) {// 左子树空,只需要接它的右子树
q=root; root=root->rchild; f->lchild=p;delete q;
}
else
{
q=p;
BiTree s=p->lchild;
while(s->rchild) {q=s; s=s->rchild;}
p->data=s->data; //p被它的直接前驱s代替
if(q==p) q->lchild=s->lchild;
else q->rchild=s->lchild;
delete s;
}
return true;}