检索树--删除算法

前言

为了记录下检索树删除算法,我来发个博客开心一下。

一 简要

1.1 基本原则

  • 如何删除二叉树的元素?

    • 通常删除以此元素为根的子树
  • 如何删除检索树中的元素?

    • 通常仅删除此元素且保中序有序

1.2 步骤

想要删除检索树中的结点,步骤:

  1. 找到要删除结点
    • 找到要删除结点的父结点
    • 找到要删除结点自己
    • 找到删除
  2. 删除结点
    • 该结点是叶子
    • 该结点只有一个儿子:只有左儿子或者只有右儿子(同时要区分,该结点是它爹的哪个儿子,左儿子还是右儿子)
    • 该结点有两个儿子:
      • 该结点的左儿子没有右儿子:直接替代
      • 该结点的左儿子有右儿子:先找到最右边的孙子,然后再替代。

二 代码

2.1 代码结构

在这里插入图片描述

https://naotu.baidu.com/file/2c072953bc2f3f1d768b4c90a2a00178

2.2 代码

int deleteT(element_type x, Bptr root)
{
	Bptr f, p, q, s, r; //f: 要删除结点的父结点
    p = NULL; // p将指向要删除的结点
    f = root; // f的初值指向虚根(无穷小)
    q = root->Rson; //q搜索指针
    
    // 先找到
    while (q) //循环查找x
    {
        if (x == q->data)
        {
            p = q;
            q = NULL;
        }
        if (x < q->data) //向左搜索
        {
            f = q;
            q = q->Lson;
        }
        else //向右搜索
        {
            f = q;
            q = q->Rson;
        }
    }
    if (!p) //未找到
        return 0;
    
    if (!p->Rson) //p没有右儿子,用左儿子代替p
    {
        if (p == f->Lson) //如果p是其父结点的左儿子
        {
            f->Lson = p->Lson;
            delete p;
        }
        else //如果p是其父结点的右儿子
        {
            f-Rson = p->Lson;
            delete p;
        }
    }
    if (!p->Lson) //p没有左儿子,用右儿子代替p
    {
        if (p == f->Lson) //如果p是其父结点的左儿子
        {
            f->Lson = p->Rson;
            delete p;
        }
        else //如果p是其父结点的右儿子
        {
            f-Rson = p->Rson;
            delete p;
        }
    }
    else //p有两个儿子,用中序前驱代替p
    {
        s = p->Lson; //s是p的左儿子
        if (s->Rson == NULL) //左儿子s没有右儿子,用s代替p:左儿子带着它的儿子集体上位
        {
            p->data = s->data; //用s的值域代换p的值域
            p->Lson = s->Lson; //删去s
            delete s;
        }
        else //左儿子s有右儿子,查找p的左儿子的最右子孙r
        {
            r = s->Rson;
            while (r->Rson) //找最右的子孙r
            {
                s = r;
                r = r->Rson;
            }
            p->data = r->data; //用r的值域代换p的值域
            s->Rson = r->Lson; //删去r
            delete r;
        }
    }
    
    return 1; //返回删除成功信息
} //函数结束

猜你喜欢

转载自blog.csdn.net/ALexander_Monster/article/details/107026358