|
算法 9.7
bool DeleteBST (BiTree &T,
KeyType kval ) {
//
若二叉查找树T中存在关键字等于 kval 的数据元素时,则删除
// 该数据元素结点 *p,并返回 TRUE;否则返回
FALSE
if (!T) return FALSE; //
不存在关键字等于kval的数据元素
else {
if ( kval == T->data.key) )
{ DeleteNode (T);
// 找到关键字等于 kval 的数据元素
return TRUE;}
else if ( kval < T->data.key)
return DeleteBST ( T->lchild, kval );
// 返回在左子树上查找的结果
else return DeleteBST ( T->rchild,
kval );
// 返回在右子树上查找的结果
} // else
} // DeleteBST
其中删除操作过程如下所描述:
void DeleteNode ( BiTree &p ){
//
从二叉查找树中删除结点 p,并重接它的左或右子树
if (!p->rchild) { //
右子树空则只需重接它的左子树
q = p; p = p->lchild; delete q;
}
else if (!p->lchild) { //
只需重接它的右子树
q = p; p = p->rchild; delete q;
}
else { //
左右子树均不空
q = p; s = p->lchild;
while (!s->rchild) { q = s; s = s->rchild;
}
p->data = s->data; //
s 指向被删结点的前驱
if (q != p ) q->rchild = s->lchild;
else q->lchild = s->lchild; //
重接 *q 的左子树
delete s;
}
} // Delete |
|
对算法9.7中的删除操作
DeleteNode(T) 需作三点说明:
(1) 叶子结点的情况可归入到"右子树空"的情况,此时因左子树也空,自然 p=NULL;
(2) 注意,T在函数 DeleteBST 中是一个递归调用的引用型参数,第一次调用时的参数是指向根结点的指针,当继续在子树中进行查找时,自然就是双亲结点的左指针或右指针,因此在函数
DeleteNode(p) 中修改指针 p,实际上修改的是被删结点的双亲结点的指针域;
(3) 在被删结点的左右子树均不空时,需删除其 "前驱结点"*s,一般情况下应将 *s 的左子树接为其双亲的右子树,但当
*s 即为被删结点的左子树根时,应将 *s 的左子树接为其双亲的左子树。 |
|