我已经负责在ANSI C中反复实施RB树。
我的支持代码似乎都工作正常,但是当我针对已知结果测试代码时,预订遍历不正确,并且所有节点都设置为红色。
我怀疑我的rbt_fix()
功能应该受到责备 - 主要是因为它是唯一一个我在玩色彩分配而不完全确定我在做什么的领域。我已根据建议的psudo代码检查了我的代码,看起来是正确的。
旋转后处理节点是否正确?我应该将我的根节点指针设置为' new root'额外的分配 - 虽然因为轮换代码更新节点并返回新的根,但是不需要手动重新分配?
我是否忘记了RBT的基本内容?我已经检查了我的插入代码,并且我确定他们在适当的时间调用rbt_fix - 在返回之前。
完整的代码在这里复制粘贴有点冗长,但我已经将副本作为要点放在on github上,对于那些愿意阅读丑陋代码的少数人来说。
static rbt rbt_fix(rbt r) {
rbt R = r;
rbt A = R == NULL || R->left == NULL ? NULL : R->left;
rbt C = A == NULL || A->left == NULL ? NULL : A->left;
rbt D = A == NULL || A->right == NULL ? NULL : A->right;
rbt B = R == NULL || R->right == NULL ? NULL : R->right;
rbt E = B == NULL || B->left == NULL ? NULL : B->left;
rbt F = B == NULL ||B->right == NULL ? NULL : B->right;
if (IS_RED(A)) {
if (IS_RED(C)) {
if (IS_RED(B)) {
R->colour = RED;
A->colour = BLACK;
B->colour = BLACK;
} else if (IS_BLACK(B)) {
R = rotate_right(R);
A->colour = BLACK;
R->colour = RED;
}
}
if (IS_RED(D)) {
if (IS_RED(B)) {
R->colour = RED;
A->colour = BLACK;
B->colour = BLACK;
} else if (IS_BLACK(B)) {
A = rotate_left(A);
R = rotate_right(R);
D->colour = BLACK;
R->colour = RED;
}
}
}
if (IS_RED(B)) {
if (IS_RED(E)) {
if (IS_RED(A)) {
R->colour = RED;
A->colour = BLACK;
B->colour = BLACK;
} else if (IS_BLACK(A)) {
B = rotate_right(B);
R = rotate_left(R);
E->colour = BLACK;
R->colour = RED;
}
}
if (IS_RED(F)) {
if (IS_RED(A)) {
R->colour = RED;
A->colour = BLACK;
B->colour = BLACK;
} else if (IS_BLACK(F)) {
R = rotate_left(R);
B->colour = BLACK;
R->colour = RED;
}
}
}
return R;
}
使用插入序列h,j,i,f,j,g,k,d,a,e,b,c
,我应该期待输出:
g(black), d(red), b(b), a(r), c(r), f(b), e(r), i(r), h(b), k(b), j(r), i(r)
从预订遍历,但我的程序目前输出:
h, f, d, a, b, c, e, g, l, i, j, k (all red)
感谢您的帮助。
^这些是代码^
中引用的节点