查找 - 树上的查找 - 二叉排序树(三)

 我来答
温屿17
2022-10-22 · TA获得超过1.2万个赞
知道小有建树答主
回答量:827
采纳率:0%
帮助的人:93.5万
展开全部

  ( )二叉排序树的删除

  从二叉排序树中删除一个结点 不能把以该结点为根的子树都删去 并且还要保证删除后所得的二叉树仍然满足BST性质

  ①删除操作的一般步骤

  ( ) 进行查找

  查找时 令p指向当前访问到的结点 parent指向其双亲(其初值为NULL) 若树中找不到被删结点则返回 否则被删结点是*p

  ( ) 删去*p

  删*p时 应将*p的子树(若有)仍连接在树上且保持BST性质不变 按*p的孩子数目分三种情况进行处理

  ②删除*p结点的三种情况

  ( )*p是叶子(即它的孩子数为 )

  无须连接*p的子树 只需将*p的双亲*parent中指向*p的指针域置空即可

  ( )*p只有一个孩子*child

  只需将*child和*p的双亲直接连接后 即可删去*p

  注意

  *p既可能是*parent的左孩子也可能是其右孩子 而*child可能是*p的左孩子或右孩子 故共有 种状态

  ( )*p有两个孩子

  先令q=p 将被删结点的地址保存在q中;然后找*q的中序后继*p 并在查找过程中仍用parent记住*p的双亲位置 *q的中序后继

  *p一定是*q的右子树中最左下的结点 它无左子树 因此 可以将删去*q的操作转换为删去的*p的操作 即在释放结点*p之前将其

  数据复制到*q中 就相当于删去了*q 具体【 参见动画演示 】

  ③二叉排序树删除算法

  分析

  上述三种情况都能统一到情况( ) 算法中只需针对情况( )处理即可

  注意边界条件 若parent为空 被删结点*p是根 故删去*p后 应将child置为根

  算法

  void DelBSTNode(BSTree *Tptr KeyType key)

  {//在二叉排序树*Tptr中删去关键字为key的结点

  BSTNode *parent=NUll *p=*Tptr *q *child;

  while(p){ //从根开始查找关键字为key的待删结点

  if(p >key==key) break;//已找到 跳出查找循环

  parent=p; //parent指向*p的双亲

  p=(key key)?p >lchild p >rchild; //在关p的左或右子树中继续找

  }

  if(!p) return; //找不到被删结点则返回

  q=p; //q记住被删结点*p

  if(q >lchild&&q >rchild) //*q的两个孩子均非空 故找*q的中序后继*p

  for(parent=q p=q >rchild; p >lchild; parent=p p=p= >lchild);

  //现在情况( )已被转换为情况( ) 而情况( )相当于是情况( )中child=NULL的状况

  child=(p >lchild)?p >lchild p >rchild;//若是情况( ) 则child非空;否则child为空

  if(!parent) //*p的双亲为空 说明*p为根 删*p后应修改根指针

  *Tptr=child; //若是情况( ) 则删去*p后 树为空;否则child变为根

  else{ //*p不是根 将*p的孩子和*p的双亲进行连接 *p从树上被摘下

  if(p==parent >lchild) //*p是双亲的左孩子

  parent >lchild=child; //*child作为*parent的左孩子

  else parent >rchild=child; //*child作为 parent的右孩子

  if(p!=q) //是情况( ) 需将*p的数据复制到*q

  q >key=p >key; //若还有其它数据域亦需复制

  } //endif

  free(p); /释放*p占用的空间

lishixinzhi/Article/program/sjjg/201311/23824

已赞过 已踩过<
你对这个回答的评价是?
评论 收起
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式