diff --git a/qpkg/jrb.c b/qpkg/jrb.c index 64b8731..103af12 100644 --- a/qpkg/jrb.c +++ b/qpkg/jrb.c @@ -46,11 +46,6 @@ Fax: 865-974-4404 #include #include "jrb.h" -static void mk_new_int(JRB l, JRB r, JRB p, int il); -static JRB lprev(JRB n); -static JRB rprev(JRB n); -static void recolor(JRB n); -static void single_rotate(JRB y, int l); #define isred(n) (n->red) #define isblack(n) (!isred(n)) @@ -96,6 +91,97 @@ static void delete_item(JRB item) /* Deletes an arbitrary iterm */ } +static void single_rotate(JRB y, int l) +{ + int rl = 0 /* for gcc */, ir; + JRB x, yp; + + ir = isroot(y); + yp = y->parent; + if (!ir) + rl = isleft(y); + + if (l) { + x = y->flink; + y->flink = x->blink; + setleft(y->flink); + y->flink->parent = y; + x->blink = y; + setright(y); + } else { + x = y->blink; + y->blink = x->flink; + setright(y->blink); + y->blink->parent = y; + x->flink = y; + setleft(y); + } + + x->parent = yp; + y->parent = x; + if (ir) { + yp->parent = x; + setnormal(y); + setroot(x); + } else { + if (rl) { + yp->flink = x; + setleft(x); + } else { + yp->blink = x; + setright(x); + } + } +} + + +static void recolor(JRB n) +{ + JRB p, gp, s; + int done = 0; + + while (!done) { + if (isroot(n)) { + setblack(n); + return; + } + + p = n->parent; + + if (isblack(p)) + return; + + if (isroot(p)) { + setblack(p); + return; + } + + gp = p->parent; + s = sibling(p); + if (isred(s)) { + setblack(p); + setred(gp); + setblack(s); + n = gp; + } else { + done = 1; + } + } + /* p's sibling is black, p is red, gp is black */ + + if ((isleft(n) == 0) == (isleft(p) == 0)) { + single_rotate(gp, isleft(n)); + setblack(p); + setred(gp); + } else { + single_rotate(p, isleft(n)); + single_rotate(gp, isleft(n)); + setblack(n); + setred(gp); + } +} + + static JRB mk_new_ext(void *key, void *val) { JRB new; @@ -268,97 +354,6 @@ static JRB jrb_insert_b(JRB n, void *key, void *val) } -static void recolor(JRB n) -{ - JRB p, gp, s; - int done = 0; - - while (!done) { - if (isroot(n)) { - setblack(n); - return; - } - - p = n->parent; - - if (isblack(p)) - return; - - if (isroot(p)) { - setblack(p); - return; - } - - gp = p->parent; - s = sibling(p); - if (isred(s)) { - setblack(p); - setred(gp); - setblack(s); - n = gp; - } else { - done = 1; - } - } - /* p's sibling is black, p is red, gp is black */ - - if ((isleft(n) == 0) == (isleft(p) == 0)) { - single_rotate(gp, isleft(n)); - setblack(p); - setred(gp); - } else { - single_rotate(p, isleft(n)); - single_rotate(gp, isleft(n)); - setblack(n); - setred(gp); - } -} - - -static void single_rotate(JRB y, int l) -{ - int rl = 0 /* for gcc */, ir; - JRB x, yp; - - ir = isroot(y); - yp = y->parent; - if (!ir) - rl = isleft(y); - - if (l) { - x = y->flink; - y->flink = x->blink; - setleft(y->flink); - y->flink->parent = y; - x->blink = y; - setright(y); - } else { - x = y->blink; - y->blink = x->flink; - setright(y->blink); - y->blink->parent = y; - x->flink = y; - setleft(y); - } - - x->parent = yp; - y->parent = x; - if (ir) { - yp->parent = x; - setnormal(y); - setroot(x); - } else { - if (rl) { - yp->flink = x; - setleft(x); - } else { - yp->blink = x; - setright(x); - } - } -} - - void jrb_delete_node(JRB n) { JRB s, p, gp, x, z;