从C中的断言函数更改为If语句

时间:2012-11-29 04:40:20

标签: c tree assert red-black-tree

我在网上找到了一些红黑树的代码,我正在尝试实现它。

我不想使用原始代码所在的assert函数here

我在删除修复之前就在n->color = child->color;行上遇到了段错误。调试后我发现在这种情况下孩子不存在,所以原始代码中断言语句的原因。我决定添加我认为合适的附加if子句,包括向下处理子项的所有内容。

但是,现在程序实际上并没有删除,因为如果孩子不存在,它永远不会进入循环。经过反复试验后,我仍无法找到关闭if子句的位置,以便正确取代断言语句。

请让我知道你的想法!

这是我没有断言的“已翻译”代码,而是使用if语句。

void delete_node(int key)
{
    node* child;
    node* n ;

   n = searchTree(key);

    if(n == NULL)return;

    if(n->left != NULL && n->right != NULL)
    {
        node* pred = n->left;
        while(pred->right != NULL)
            pred = pred->right;

        n->value = pred->value;
        n = pred;
    }
if(n->right != NULL || n->left != NULL){

    child = n->right == NULL ? n->left : n->right;
    if(n->color == 'b')
    {
        n->color = child->color;
        delete_fix1(n);
    }

    swap_nodes(n, child);
    if(n->parent == NULL && child != NULL)
        child->color = 'b';
    free(n);

}

}

测试数据(尝试删除4时发生Seg Fault): 我代表插入(据我所知,插入完美无缺) d代表删除

i 7
i 8
i 1
d 8
i 4
i 10
d 4
i 11

1 个答案:

答案 0 :(得分:1)

此:

assert(n->left == NULL || n->right == NULL)

无处附近:

if (n->right != NULL || n->left != NULL)

重新检查您的翻译。断言声明其中一个必须为NULL。如果 为NULL,那么你的if-expr就会证明为真。如果两者都为非null,那么if-expr将被传递,其中断言将失败。同样,如果两者都为NULL,则if-expr将失败,而断言将通过。

做这种事情时不要走捷径。第一。无论您添加的支票是什么,都会保留声明。其次,直到它完成并正常工作,在你的if(expr):或(!(expr))中逐字复制断言条款以获得救助条件。

逐字检查:

assert(n->left == NULL || n->right == NULL)
if (n->left == NULL || n->right == NULL)...

救助检查:

assert(n->left == NULL || n->right == NULL)
if (!(n->left == NULL || n->right == NULL))
    bailout loud.

编辑使用集成的if-expr

翻译链接代码
void rbtree_delete(rbtree t, void* key, compare_func compare)
{
    node child;
    node n = lookup_node(t, key, compare);
    if (n == NULL) return;  /* Key not found, do nothing */
    if (n->left != NULL && n->right != NULL) {
        /* Copy key/value from predecessor and then delete it instead */
        node pred = maximum_node(n->left);
        n->key   = pred->key;
        n->value = pred->value;
        n = pred;
    }

    assert(n->left == NULL || n->right == NULL);
    if (n->left == NULL || n->right == NULL) // << note: SAME as above
    {
        child = n->right == NULL ? n->left  : n->right;
        if (node_color(n) == BLACK) {
            n->color = node_color(child);
            delete_case1(t, n);
        }
        replace_node(t, n, child);
        if (n->parent == NULL && child != NULL)
            child->color = BLACK;
        free(n);
    }

    verify_properties(t);
}