BST树的删除

来源:互联网 发布:无线耳机推荐 知乎 编辑:程序博客网 时间:2024/06/06 03:41
 

1  删除操作过程分析

从BST树上删除一个结点,仍然要保证删除后满足BST的性质。设被删除结点为p,其父结点为f ,删除情况如下:

①  若p是叶子结点: 直接删除p。

②  若p只有一棵子树(左子树或右子树):直接用p的左子树(或右子树)取代p的位置而成为f的一棵子树。即原来p是f的左子树,则p的子树成为f的左子树;原来p是f的右子树,则p的子树成为f的右子树。  

③ 若p既有左子树又有右子树 :处理方法有以下两种,可以任选其中一种。

◆  用p的直接前驱结点代替p。即从p的左子树中选择值最大的结点s放在p的位置(用结点s的内容替换结点p内容),然后删除结点s。s是p的左子树中的最右边的结点且没有右子树,对s的删除同②。

◆ 用p的直接后继结点代替p。即从p的右子树中选择值最小的结点s放在p的位置(用结点s的内容替换结点p内容),然后删除结点s。s是p的右子树中的最左边的结点且没有左子树,对s的删除同②。

 

2  算法实现

void Delete_BST (BSTNode *T , KeyType  key )

    /*  在以T为根结点的BST树中删除关键字为key的结点   */

         BSTNode *p=T , *f=NULL , *q , *s ;

         while ( p!=NULL&&!EQ(p->key, key) )

         { 

                   f=p ;

                   if (LT(key, p->key) ) p=p->Lchild ;  /*  搜索左子树 */

                   else p=p->Rchild ;  /*  搜索右子树 */   

         }

         if  (p==NULL)  return ;     /*  没有要删除的结点   */

         s=p ;     /*  找到了要删除的结点为p   */

         if (p->Lchild!=NULL&& p->Rchild!=NULL)

         { 

                   f=p ;

                   s=p->Lchild ;         /*  从左子树开始找   */

                   while (s->Rchild!=NULL)

              {  

                            f=s ;

                            s=s->Rchild ;  

                   }

                   /*   左、右子树都不空,找左子树中最右边的结点  */

                   p->key=s->key ;

                   p->otherinfo=s->otherinfo ;

         /*  用结点s的内容替换结点p内容  */

         }   /*  将第3种情况转换为第2种情况*/

         if  (s->Lchild!=NULL)   /*  若s有左子树,右子树为空 */

                   q=s->Lchild ;

         else q=s->Rchild ;

         if  (f==NULL)  T=q ;

         else if (f->Lchild==s)  f->Lchild=q ;

      else f->Rchild=q ;

         free(s) ;

}