【问题标题】:Error in inserting nodes in red black trees在红黑树中插入节点时出错
【发布时间】:2015-06-13 06:42:05
【问题描述】:

我正在尝试在红黑树中插入节点。函数 rotate_left、rotate_right、插入是正确的,但 rb_fixup 似乎是错误的。红色显示为 1,黑色显示为 0。我已经实现了 CLRS 的算法。当插入第三个元素时,它会产生分段错误。 rb_fixup的代码是:

struct node
{
    int data;

    int color;
    struct node *left;
    struct node *right;
    struct node *parent;
}*root;


rb_fixup(struct node *z)
{

    struct node *y;
    y=(struct node *)malloc(sizeof(struct node));
    while(z->parent->color==1)
    {
        if(z->parent==z->parent->parent->left)
        {
            y=z->parent->parent->right;
            if(y->color==1)
            {
                z->parent->color=0;
                y->color=0;
                z->parent->parent->color=1;
                z=z->parent->parent;
            }
            else if(z==z->parent->right)
            {
                z=z->parent;
                rotate_left(z);
            }
            z->parent->color=0;
            z->parent->parent->color=1;
            rotate_right(z->parent->parent);

        }
        else if(z->parent==z->parent->parent->right)
        {
            y=z->parent->parent->left;
            if(y->color==1)
            {
                z->parent->color=0;
                y->color=0;
                z->parent->parent->color=1;
                z=z->parent->parent;
            }
            else if(z->parent->left==z)
            {
                z=z->parent;
                rotate_right(z);
            }
            z->parent->color=0;
            z->parent->parent->color=1;
            rotate_left(z->parent->parent);
        }
    }
    root->color=0;
}

【问题讨论】:

  • 您的代码假定很多指针不为空。添加断言以确保它们不为空。例如,while(z->parent->color==1) 假定 z 不为空且z->parent 不为空。可以在循环前加assert(z != 0 && z->parent != 0);,保护第一次迭代;您需要做更多工作以确保后续迭代是安全的。或者使用调试器找出导致崩溃的语句并检查该语句中涉及的所有指针。
  • 我添加了行但没有帮助。为了调试,我确实在每个 if/while 之后添加了打印语句,以了解它可能在哪里出现问题。如果我输入数据 4、41、14,它会显示 after while, after else if(else if(z->parent==z->parent->parent->right) 的打印语句,但随后显示分段错误。所以问题可能出在以下几行:z=z->parent;rotate_right(z);@Johnathan
  • 那么,你用调试器运行程序了吗?它在哪条线上崩溃?你在valgrind下运行过吗?它是否告诉你问题出在哪里?崩溃前有什么问题吗?如果没有您使用其他函数创建的 RB-tree 示例,我们如何测试您的代码?你怎么知道旋转和插入功能没问题?你什么时候打电话给rb_fixup(),为什么?你有一个转储整个 RB-tree 的函数吗?如果没有,请继续制作并使用它。如果是这样,它在你崩溃之前对这棵树有什么看法?
  • 我用 valgrind 运行了代码,我已经解决了这个错误。谢谢你的帮助:) @JonathanLeffler
  • 在解决问题方面做得很好,只需指向可以帮助您的工具。我可以建议你删除这个问题。如果您不想失去投票的分数,那么您应该发布一个答案,其中包含您对代码(和固定代码)所做的更改的摘要。但是,如果问题出在您未显示的代码中(或者您未显示的代码中也存在问题),那么要么也显示该代码,要么删除该问题。如果问题和答案对其他人没有帮助,那么它不应该出现在 SO 上,并且仅仅指向 Valgrind 和/或调试器是不够的。

标签: c insertion red-black-tree


【解决方案1】:

我解决了上述问题。上面代码的错误是,如果叔叔是红色的,它确实将叔叔和父母着色为黑色,祖父母着色为红色,但它会继续执行每个条件的else if之后编写的操作,并且许多条件没有完成正确。最终代码如下所示:-

rb_fixup(struct node *z)
{

    struct node *y;
    y=(struct node *)malloc(sizeof(struct node));
    while(z->parent->color==1 && z->parent!=NULL)
    {
        if(z->parent==z->parent->parent->left)
        {
            if(z->parent->parent->right!=NULL)
            y=z->parent->parent->right;
            if(y->color==1)
            {
                z->parent->color=0;
                y->color=0;
                z->parent->parent->color=1;
                z=z->parent->parent;
            }
            else if(z==z->parent->right)
            {
                z=z->parent;
                rotate_left(z,z->right);
                z->parent->color=0;
                z->parent->parent->color=1;
                rotate_right(z->parent->parent,z->parent);
            }
            else
            {
                z->parent->color=0;
                z->parent->parent->color=1;
                rotate_right(z->parent->parent,z->parent);
            }
        }
        else 
        {
            if(z->parent->parent->left!=NULL)
            {
                y=z->parent->parent->left;
            }           
            if(y->color==1)
            {
                z->parent->color=0;
                y->color=0;
                z->parent->parent->color=1;
                z=z->parent->parent;                
            }
            else if(z==z->parent->left)
            {
                z=z->parent;
                rotate_right(z,z->left);
                z->parent->color=0;
                z->parent->parent->color=1;
                rotate_left(z->parent->parent,z->parent);
            }
            else
            {
                z->parent->color=0;
                z->parent->parent->color=1;
                rotate_left(z->parent->parent,z->parent);
            }
        }
    }
    root->color=0;
}

【讨论】:

    猜你喜欢
    • 2013-03-05
    • 2018-11-06
    • 2013-11-17
    • 2016-05-16
    • 2018-10-04
    • 2015-11-17
    • 2013-02-28
    • 2011-08-18
    相关资源
    最近更新 更多