C++中的红黑树,删除算法

发布于 2024-11-28 10:52:13 字数 3261 浏览 1 评论 0原文

来自“算法简介,第二版”:C++ 中删除算法的实现如下所示:

template<class Tree_T, class Node_T>
void rb_delete(Tree_T* t,Node_T* z)
{
    Node_T* y = nullptr;
    Node_T* x = nullptr;
    if (!get_left(z) || !get_right(z))
    {
        y = z;
    }
    else
    {
        //y = rb_successor(z);
        y = rb_predecessor(z);
    }
    if (get_left(y))
    {
        x = get_left(y);
    }
    else
    {
        x = get_right(y);
    }
    set_parent(x,get_parent(y));
    if (!get_parent(y))
    {
        set_root(t,x);
    }
    else
    {
        if (y == get_left(get_parent(y)))
        {
            set_left(get_parent(y),x);
        }
        else
        {
            set_right(get_parent(y),x);
        }
    }
    if (y != z)
    {
        set_key(z,get_key(y));
        set_value(z,get_value(y));
    }
    if(get_color>(y) == Black)
    {
        rb_delete_fixup(t,x);
    }
}

template<class Tree_T, class Node_T>
void rb_delete_fixup(Tree_T* t, Node_T* x)
{
    while (x != get_root(t) && get_color(x) == Black)
    {
        //more code here but it never gets executed!
    }
    set_color(x,Black);
}

问题是,当我按 1,2,3,4,5,6,7,8 的顺序创建树时 树看起来像这样:

在此处输入图像描述

如果我要从这棵树中删除根,我会得到:

void rb_delete(Tree_T* t,Node_T* z)//t is the tree, z is a node with key 4
    {
        Node_T* y = nullptr;
        Node_T* x = nullptr;
        if (!get_left(z) || !get_right(z))//z has left && right so this will get skipped
        {
            y = z;
        }
        else
        {
            //y = rb_successor(z);
            y = rb_predecessor(z);//to here where y will be set to 3
        }
if (get_left(y))//this is false
        {
            x = get_left(y);
        }
        else//so we skipping to this place
        {
            x = get_right(y);//and here x goes set to nullptr!
        }
        set_parent(x,get_parent(y));//cannot set, x == nullptr
        if (!get_parent(y))//this is false
        {
            set_root(t,x);
        }
        else
        {
            if (y == get_left(get_parent(y)))//this is false
            {
                set_left(get_parent(y),x);
            }
            else
            {
                set_right(get_parent(y),x);//so here we set right of parent y to nullptr
            }
        }
        if (y != z)//this is true
        {
            set_key(z,get_key(y));
            set_value(z,get_value(y));
        }
        if(get_color>(y) == Black)//this is true aswell
        {
            rb_delete_fixup(t,x);//here we attempting to do fixup but x == nullptr!
        }
    }
//So we are going into rb_delete_fixup
     template<class Tree_T, class Node_T>
        void rb_delete_fixup(Tree_T* t, Node_T* x)//x == nullptr
        {
            while (x != get_root(t) && get_color(x) == Black)//this will get skipped because x == nullptr so no code will be executed within while loop!
            {
                //more code here but it never gets executed!
            }
            set_color(x,Black);//here x which is nullptr will get colored to Black
        }

这段代码显然不起作用,请记住它是从本问题开头提到的书中逐行实现的。

谁能帮助我并向我解释如何解决它?

From "Introduction to alghorithms, 2nd edition": Implementation of the deletion algorithm in C++ looks like this:

template<class Tree_T, class Node_T>
void rb_delete(Tree_T* t,Node_T* z)
{
    Node_T* y = nullptr;
    Node_T* x = nullptr;
    if (!get_left(z) || !get_right(z))
    {
        y = z;
    }
    else
    {
        //y = rb_successor(z);
        y = rb_predecessor(z);
    }
    if (get_left(y))
    {
        x = get_left(y);
    }
    else
    {
        x = get_right(y);
    }
    set_parent(x,get_parent(y));
    if (!get_parent(y))
    {
        set_root(t,x);
    }
    else
    {
        if (y == get_left(get_parent(y)))
        {
            set_left(get_parent(y),x);
        }
        else
        {
            set_right(get_parent(y),x);
        }
    }
    if (y != z)
    {
        set_key(z,get_key(y));
        set_value(z,get_value(y));
    }
    if(get_color>(y) == Black)
    {
        rb_delete_fixup(t,x);
    }
}

template<class Tree_T, class Node_T>
void rb_delete_fixup(Tree_T* t, Node_T* x)
{
    while (x != get_root(t) && get_color(x) == Black)
    {
        //more code here but it never gets executed!
    }
    set_color(x,Black);
}

The problem is that when I create tree in order 1,2,3,4,5,6,7,8
the tree looks like this:

enter image description here

If I were to delete root from this tree I'm getting:

void rb_delete(Tree_T* t,Node_T* z)//t is the tree, z is a node with key 4
    {
        Node_T* y = nullptr;
        Node_T* x = nullptr;
        if (!get_left(z) || !get_right(z))//z has left && right so this will get skipped
        {
            y = z;
        }
        else
        {
            //y = rb_successor(z);
            y = rb_predecessor(z);//to here where y will be set to 3
        }
if (get_left(y))//this is false
        {
            x = get_left(y);
        }
        else//so we skipping to this place
        {
            x = get_right(y);//and here x goes set to nullptr!
        }
        set_parent(x,get_parent(y));//cannot set, x == nullptr
        if (!get_parent(y))//this is false
        {
            set_root(t,x);
        }
        else
        {
            if (y == get_left(get_parent(y)))//this is false
            {
                set_left(get_parent(y),x);
            }
            else
            {
                set_right(get_parent(y),x);//so here we set right of parent y to nullptr
            }
        }
        if (y != z)//this is true
        {
            set_key(z,get_key(y));
            set_value(z,get_value(y));
        }
        if(get_color>(y) == Black)//this is true aswell
        {
            rb_delete_fixup(t,x);//here we attempting to do fixup but x == nullptr!
        }
    }
//So we are going into rb_delete_fixup
     template<class Tree_T, class Node_T>
        void rb_delete_fixup(Tree_T* t, Node_T* x)//x == nullptr
        {
            while (x != get_root(t) && get_color(x) == Black)//this will get skipped because x == nullptr so no code will be executed within while loop!
            {
                //more code here but it never gets executed!
            }
            set_color(x,Black);//here x which is nullptr will get colored to Black
        }

This code obviously doesn't work, bear in mind it is implemented line by line from book mentioned at the beginning of this question.

Could anyone help me and explain to me how shall I fix it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文