在二叉排序树中删除一个结点
在二叉排序树中删除一个结点时,不能把以该结点为根的子树上的结点都删除,必须先把被删除结点从存储二叉排序树的链表上摘下,将因删除结点而断开的二叉链表重新链接起来,同时确保二叉排序树的性质不会丢失。
二叉排序树的删除要考虑三种情况:
- 若被删除结点x是叶子结点,则直接删除,并修改x的父结点的指针为NULL;
- 若被删除结点x只有一棵左子树或右子树,则让x的子树成为x父结点的子树,替代x的位置;
- 若被删除结点x有左、右两棵子树,则用另一结点替代被删除的结点x:x右子树的最小元素或者x左子树的最大元素,然后删除这个替代结点(因为在二叉排序树中右子树的最小元素、左子树的最大元素要么是叶子结点,要么只有一棵左子树或右子树,一定不会同时有左、右子树,这样就转换成了第一或第二种情况);
如有谬误或者不足还请批评指正!
BSTree Delete(BSTree BST, int x)
{
BSTNode *p;
if (BST == NULL) //如果树为空直接返回
return NULL;
else if (x < BST->data) //小于则左子树递归删除
BST->lchild = Delete(BST->lchild, x);
else if (x > BST->data) //大于则右子树递归删除
BST->rchild = Delete(BST->rchild, x);
else //等于则找到了要删除的结点
{
//如果被删除的结点有左、右两个孩子结点
if (BST->lchild && BST->rchild)
{
//找到右子树的最小元素
p = FindMin(BST->rchild);
//替代被删除的结点
BST->data = p->data;
//在被删除结点的右子树中删除刚才找到的右子树的最小元素
BST->rchild = Delete(BST->rchild, p->data);
}
//如果被删除结点只有一个孩子结点或没有孩子结点
else
{
p = BST;
if (BST->lchild == NULL) //有右孩子结点或没有孩子结点
BST = BST->rchild;
else if (BST->rchild == NULL) //有左孩子结点或没有孩子结点
BST = BST->lchild;
free(p); //释放结点
}
}
return BST;
}
BSTree FindMin(BSTree BST)
{
if(BST == NULL) //树为空直接放回
return NULL;
else if(BST->lchild == NULL) //找到最左叶子结点并返回
return BST;
else
return FindMin(BST->lchild); //沿左分支继续递归查找
}
强烈推荐浙江大学的数据结构课程,讲的非常好!