一、二叉排序树删除操作

1、分析

  • 叶子结点的删除:直接删除;

    二叉排序树(二)_第1张图片

  • 仅有左或右子树的结点删除:删除后再连接子树;

    二叉排序树(二)_第2张图片

  • 左右子树都有结点:用该结点的前驱或后继替换该结点位置,再删除该结点;

       二叉排序树(二)_第3张图片

2、code

/*若二叉排序树T中存在关键字等于key的数据元素时,则删除该数据元素结点*/
/*并返回TRUE;否则返回FALSE*/
Status DeleteBST(BiTree *T,int key)
{
    if(!*T)    /*不存在关键字等于key的数据元素*/
        return FALSE;
    else
    {
        if(key==(*T)->data)    /*找到关键字等于key的数据元素*/
            return Delete(T);
        else if(key<(*T)->data)

            return DeleteBST(&(*T)->lchild,key);
        else
            return DeleteBST(&(*T)->rchild,key);
    }
}

/*从二叉排序树中删除结点p,并重接它的左或右子树*/
Status Delete(BiTree *p)
{
    BiTree q,s;
    if((*p)->rchild==NULL)    /*右子树空则只需要重接它的左子树*/
    {
        q=*p;
        *p=(*p)->lchild;
        free(q);
    }
    else if((*p)->lchild==NULL)    /*左子树空则只需要重接它的左子树*/
    {
        q=*p;
        *p=(*p)->rchild;
        free(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;    /*重接q的右子树*/
        else
            q->lchild=s->lchild;    /*重接q的左子树*/
        free(s);
        /*把上面的代码替代为下面的也一样,只是前面找的是前驱,后面找的是后继*/
        //s=(*p)->rchild;
        //while(s->lchild)    /*转右,然后向右到尽头(找待删除节点的后继)*/
        //{
        //    q=s;
        //    s=s->lchild;
        //}
        //(*p)->data=s->data;    /*s指向被删结点的直接前驱(后继)*/
        //if(q!=*p)
        //    q->lchild=s->rchild;    /*重接q的左子树*/
        //else
        //    q->rchild=s->lchild;    /*重接q的右子树*/
        //free(s);
    }
    return TRUE;
}