我在网上找到了一些红黑树的代码,我正在尝试实现它。
我不想使用原始代码所在的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
答案 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);
}