chiark / gitweb /
untabify source files, make indenting more uniform with GNU indent -kr --no-tabs...
[nlopt.git] / src / util / redblack.c
index 267733b9c031d0a16d5dd115c4d2d0fd9cd49d82..6765c506353a93708cf281d07b1c104a80889886 100644 (file)
 /* it is convenient to use an explicit node for NULL nodes ... we need
    to be careful never to change this node indirectly via one of our
    pointers!  */
-rb_node nil = {&nil, &nil, &nil, 0, BLACK};
+rb_node nil = { &nil, &nil, &nil, 0, BLACK };
+
 #define NIL (&nil)
 
-void rb_tree_init(rb_tree *t, rb_compare compare) {
-     t->compare = compare;
-     t->root = NIL;
-     t->N = 0;
+void rb_tree_init(rb_tree * t, rb_compare compare)
+{
+    t->compare = compare;
+    t->root = NIL;
+    t->N = 0;
 }
 
-static void destroy(rb_node *n)
+static void destroy(rb_node * n)
 {
-     if (n != NIL) {
-         destroy(n->l); destroy(n->r);
-         free(n);
-     }
+    if (n != NIL) {
+        destroy(n->l);
+        destroy(n->r);
+        free(n);
+    }
 }
 
-void rb_tree_destroy(rb_tree *t)
+void rb_tree_destroy(rb_tree * t)
 {
-     destroy(t->root);
-     t->root = NIL;
+    destroy(t->root);
+    t->root = NIL;
 }
 
-void rb_tree_destroy_with_keys(rb_tree *t)
+void rb_tree_destroy_with_keys(rb_tree * t)
 {
-     rb_node *n = rb_tree_min(t);
-     while (n) {
-         free(n->k); n->k = NULL;
-         n = rb_tree_succ(n);
-     }
-     rb_tree_destroy(t);
+    rb_node *n = rb_tree_min(t);
+    while (n) {
+        free(n->k);
+        n->k = NULL;
+        n = rb_tree_succ(n);
+    }
+    rb_tree_destroy(t);
 }
 
-static void rotate_left(rb_node *p, rb_tree *t)
+static void rotate_left(rb_node * p, rb_tree * t)
 {
-     rb_node *n = p->r; /* must be non-NIL */
-     p->r = n->l;
-     n->l = p;
-     if (p->p != NIL) {
-         if (p == p->p->l) p->p->l = n;
-         else p->p->r = n;
-     }
-     else
-         t->root = n;
-     n->p = p->p;
-     p->p = n;
-     if (p->r != NIL) p->r->p = p;
+    rb_node *n = p->r;          /* must be non-NIL */
+    p->r = n->l;
+    n->l = p;
+    if (p->p != NIL) {
+        if (p == p->p->l)
+            p->p->l = n;
+        else
+            p->p->r = n;
+    } else
+        t->root = n;
+    n->p = p->p;
+    p->p = n;
+    if (p->r != NIL)
+        p->r->p = p;
 }
 
-static void rotate_right(rb_node *p, rb_tree *t)
+static void rotate_right(rb_node * p, rb_tree * t)
 {
-     rb_node *n = p->l; /* must be non-NIL */
-     p->l = n->r;
-     n->r = p;
-     if (p->p != NIL) {
-         if (p == p->p->l) p->p->l = n;
-         else p->p->r = n;
-     }
-     else
-         t->root = n;
-     n->p = p->p;
-     p->p = n;
-     if (p->l != NIL) p->l->p = p;
+    rb_node *n = p->l;          /* must be non-NIL */
+    p->l = n->r;
+    n->r = p;
+    if (p->p != NIL) {
+        if (p == p->p->l)
+            p->p->l = n;
+        else
+            p->p->r = n;
+    } else
+        t->root = n;
+    n->p = p->p;
+    p->p = n;
+    if (p->l != NIL)
+        p->l->p = p;
 }
 
-static void insert_node(rb_tree *t, rb_node *n)
+static void insert_node(rb_tree * t, rb_node * n)
 {
-     rb_compare compare = t->compare;
-     rb_key k = n->k;
-     rb_node *p = t->root;
-     n->c = RED;
-     n->p = n->l = n->r = NIL;
-     t->N++;
-     if (p == NIL) {
-         t->root = n;
-         n->c = BLACK;
-         return;
-     }
-     /* insert (RED) node into tree */
-     while (1) {
-         if (compare(k, p->k) <= 0) { /* k <= p->k */
-              if (p->l != NIL)
-                   p = p->l;
-              else {
-                   p->l = n;
-                   n->p = p;
-                   break;
-              }
-         }
-         else {
-              if (p->r != NIL)
-                   p = p->r;
-              else {
-                   p->r = n;
-                   n->p = p;
-                   break;
-              }
-         }
-     }
- fixtree:
-     if (n->p->c == RED) { /* red cannot have red child */
-         rb_node *u = p == p->p->l ? p->p->r : p->p->l;
-         if (u != NIL && u->c == RED) {
-              p->c = u->c = BLACK;
-              n = p->p;
-              if ((p = n->p) != NIL) {
-                   n->c = RED;
-                   goto fixtree;
-              }
-         }
-         else {
-              if (n == p->r && p == p->p->l) {
-                   rotate_left(p, t);
-                   p = n; n = n->l;
-              }
-              else if (n == p->l && p == p->p->r) {
-                   rotate_right(p, t);
-                   p = n; n = n->r;
-              }
-              p->c = BLACK;
-              p->p->c = RED;
-              if (n == p->l && p == p->p->l)
-                   rotate_right(p->p, t);
-              else if (n == p->r && p == p->p->r)
-                   rotate_left(p->p, t);
-         }
-             
-     }
+    rb_compare compare = t->compare;
+    rb_key k = n->k;
+    rb_node *p = t->root;
+    n->c = RED;
+    n->p = n->l = n->r = NIL;
+    t->N++;
+    if (p == NIL) {
+        t->root = n;
+        n->c = BLACK;
+        return;
+    }
+    /* insert (RED) node into tree */
+    while (1) {
+        if (compare(k, p->k) <= 0) {    /* k <= p->k */
+            if (p->l != NIL)
+                p = p->l;
+            else {
+                p->l = n;
+                n->p = p;
+                break;
+            }
+        } else {
+            if (p->r != NIL)
+                p = p->r;
+            else {
+                p->r = n;
+                n->p = p;
+                break;
+            }
+        }
+    }
+  fixtree:
+    if (n->p->c == RED) {       /* red cannot have red child */
+        rb_node *u = p == p->p->l ? p->p->r : p->p->l;
+        if (u != NIL && u->c == RED) {
+            p->c = u->c = BLACK;
+            n = p->p;
+            if ((p = n->p) != NIL) {
+                n->c = RED;
+                goto fixtree;
+            }
+        } else {
+            if (n == p->r && p == p->p->l) {
+                rotate_left(p, t);
+                p = n;
+                n = n->l;
+            } else if (n == p->l && p == p->p->r) {
+                rotate_right(p, t);
+                p = n;
+                n = n->r;
+            }
+            p->c = BLACK;
+            p->p->c = RED;
+            if (n == p->l && p == p->p->l)
+                rotate_right(p->p, t);
+            else if (n == p->r && p == p->p->r)
+                rotate_left(p->p, t);
+        }
+
+    }
 }
 
-rb_node *rb_tree_insert(rb_tree *t, rb_key k)
+rb_node *rb_tree_insert(rb_tree * t, rb_key k)
 {
-     rb_node *n = (rb_node *) malloc(sizeof(rb_node));
-     if (!n) return NULL;
-     n->k = k;
-     insert_node(t, n);
-     return n;
+    rb_node *n = (rb_node *) malloc(sizeof(rb_node));
+    if (!n)
+        return NULL;
+    n->k = k;
+    insert_node(t, n);
+    return n;
 }
 
-static int check_node(rb_node *n, int *nblack, rb_tree *t)
+static int check_node(rb_node * n, int *nblack, rb_tree * t)
 {
-     int nbl, nbr;
-     rb_compare compare = t->compare;
-     if (n == NIL) { *nblack = 0; return 1; }
-     if (n->r != NIL && n->r->p != n) return 0;
-     if (n->r != NIL && compare(n->r->k, n->k) < 0)
-         return 0;
-     if (n->l != NIL && n->l->p != n) return 0;
-     if (n->l != NIL && compare(n->l->k, n->k) > 0)
-         return 0;
-     if (n->c == RED) {
-         if (n->r != NIL && n->r->c == RED) return 0;
-         if (n->l != NIL && n->l->c == RED) return 0;
-     }
-     if (!(check_node(n->r, &nbl, t) && check_node(n->l, &nbr, t))) 
-         return 0;
-     if (nbl != nbr) return 0;
-     *nblack = nbl + (n->c == BLACK);
-     return 1;
+    int nbl, nbr;
+    rb_compare compare = t->compare;
+    if (n == NIL) {
+        *nblack = 0;
+        return 1;
+    }
+    if (n->r != NIL && n->r->p != n)
+        return 0;
+    if (n->r != NIL && compare(n->r->k, n->k) < 0)
+        return 0;
+    if (n->l != NIL && n->l->p != n)
+        return 0;
+    if (n->l != NIL && compare(n->l->k, n->k) > 0)
+        return 0;
+    if (n->c == RED) {
+        if (n->r != NIL && n->r->c == RED)
+            return 0;
+        if (n->l != NIL && n->l->c == RED)
+            return 0;
+    }
+    if (!(check_node(n->r, &nbl, t) && check_node(n->l, &nbr, t)))
+        return 0;
+    if (nbl != nbr)
+        return 0;
+    *nblack = nbl + (n->c == BLACK);
+    return 1;
 }
-int rb_tree_check(rb_tree *t)
+
+int rb_tree_check(rb_tree * t)
 {
-     int nblack;
-     if (nil.c != BLACK) return 0;
-     if (nil.p != NIL || nil.r != NIL || nil.l != NIL) return 0;
-     if (t->root == NIL) return 1;
-     if (t->root->c != BLACK) return 0;
-     return check_node(t->root, &nblack, t);
+    int nblack;
+    if (nil.c != BLACK)
+        return 0;
+    if (nil.p != NIL || nil.r != NIL || nil.l != NIL)
+        return 0;
+    if (t->root == NIL)
+        return 1;
+    if (t->root->c != BLACK)
+        return 0;
+    return check_node(t->root, &nblack, t);
 }
 
-rb_node *rb_tree_find(rb_tree *t, rb_key k)
+rb_node *rb_tree_find(rb_tree * t, rb_key k)
 {
-     rb_compare compare = t->compare;
-     rb_node *p = t->root;
-     while (p != NIL) {
-         int comp = compare(k, p->k);
-         if (!comp) return p;
-         p = comp <= 0 ? p->l : p->r;
-     }
-     return NULL;
+    rb_compare compare = t->compare;
+    rb_node *p = t->root;
+    while (p != NIL) {
+        int comp = compare(k, p->k);
+        if (!comp)
+            return p;
+        p = comp <= 0 ? p->l : p->r;
+    }
+    return NULL;
 }
 
 /* find greatest point in subtree p that is <= k */
-static rb_node *find_le(rb_node *p, rb_key k, rb_tree *t)
+static rb_node *find_le(rb_node * p, rb_key k, rb_tree * t)
 {
-     rb_compare compare = t->compare;
-     while (p != NIL) {
-         if (compare(p->k, k) <= 0) { /* p->k <= k */
-              rb_node *r = find_le(p->r, k, t);
-              if (r) return r;
-              else return p;
-         }
-         else /* p->k > k */
-              p = p->l;
-     }
-     return NULL; /* k < everything in subtree */
+    rb_compare compare = t->compare;
+    while (p != NIL) {
+        if (compare(p->k, k) <= 0) {    /* p->k <= k */
+            rb_node *r = find_le(p->r, k, t);
+            if (r)
+                return r;
+            else
+                return p;
+        } else                  /* p->k > k */
+            p = p->l;
+    }
+    return NULL;                /* k < everything in subtree */
 }
 
 /* find greatest point in t <= k */
-rb_node *rb_tree_find_le(rb_tree *t, rb_key k)
+rb_node *rb_tree_find_le(rb_tree * t, rb_key k)
 {
-     return find_le(t->root, k, t);
+    return find_le(t->root, k, t);
 }
 
 /* find greatest point in subtree p that is < k */
-static rb_node *find_lt(rb_node *p, rb_key k, rb_tree *t)
+static rb_node *find_lt(rb_node * p, rb_key k, rb_tree * t)
 {
-     rb_compare compare = t->compare;
-     while (p != NIL) {
-         if (compare(p->k, k) < 0) { /* p->k < k */
-              rb_node *r = find_lt(p->r, k, t);
-              if (r) return r;
-              else return p;
-         }
-         else /* p->k >= k */
-              p = p->l;
-     }
-     return NULL; /* k <= everything in subtree */
+    rb_compare compare = t->compare;
+    while (p != NIL) {
+        if (compare(p->k, k) < 0) {     /* p->k < k */
+            rb_node *r = find_lt(p->r, k, t);
+            if (r)
+                return r;
+            else
+                return p;
+        } else                  /* p->k >= k */
+            p = p->l;
+    }
+    return NULL;                /* k <= everything in subtree */
 }
 
 /* find greatest point in t < k */
-rb_node *rb_tree_find_lt(rb_tree *t, rb_key k)
+rb_node *rb_tree_find_lt(rb_tree * t, rb_key k)
 {
-     return find_lt(t->root, k, t);
+    return find_lt(t->root, k, t);
 }
 
 /* find least point in subtree p that is > k */
-static rb_node *find_gt(rb_node *p, rb_key k, rb_tree *t)
+static rb_node *find_gt(rb_node * p, rb_key k, rb_tree * t)
 {
-     rb_compare compare = t->compare;
-     while (p != NIL) {
-         if (compare(p->k, k) > 0) { /* p->k > k */
-              rb_node *l = find_gt(p->l, k, t);
-              if (l) return l;
-              else return p;
-         }
-         else /* p->k <= k */
-              p = p->r;
-     }
-     return NULL; /* k >= everything in subtree */
+    rb_compare compare = t->compare;
+    while (p != NIL) {
+        if (compare(p->k, k) > 0) {     /* p->k > k */
+            rb_node *l = find_gt(p->l, k, t);
+            if (l)
+                return l;
+            else
+                return p;
+        } else                  /* p->k <= k */
+            p = p->r;
+    }
+    return NULL;                /* k >= everything in subtree */
 }
 
 /* find least point in t > k */
-rb_node *rb_tree_find_gt(rb_tree *t, rb_key k)
+rb_node *rb_tree_find_gt(rb_tree * t, rb_key k)
 {
-     return find_gt(t->root, k, t);
+    return find_gt(t->root, k, t);
 }
 
-rb_node *rb_tree_min(rb_tree *t)
+rb_node *rb_tree_min(rb_tree * t)
 {
-     rb_node *n = t->root;
-     while (n != NIL && n->l != NIL)
-         n = n->l;
-     return(n == NIL ? NULL : n);
+    rb_node *n = t->root;
+    while (n != NIL && n->l != NIL)
+        n = n->l;
+    return (n == NIL ? NULL : n);
 }
 
-rb_node *rb_tree_max(rb_tree *t)
+rb_node *rb_tree_max(rb_tree * t)
 {
-     rb_node *n = t->root;
-     while (n != NIL && n->r != NIL)
-         n = n->r;
-     return(n == NIL ? NULL : n);
+    rb_node *n = t->root;
+    while (n != NIL && n->r != NIL)
+        n = n->r;
+    return (n == NIL ? NULL : n);
 }
 
-rb_node *rb_tree_succ(rb_node *n)
+rb_node *rb_tree_succ(rb_node * n)
 {
-     if (!n) return NULL;
-     if (n->r == NIL) {
-         rb_node *prev;
-         do {
-              prev = n;
-              n = n->p;
-         } while (prev == n->r && n != NIL);
-         return n == NIL ? NULL : n;
-     }
-     else {
-         n = n->r;
-         while (n->l != NIL)
-              n = n->l;
-         return n;
-     }
+    if (!n)
+        return NULL;
+    if (n->r == NIL) {
+        rb_node *prev;
+        do {
+            prev = n;
+            n = n->p;
+        } while (prev == n->r && n != NIL);
+        return n == NIL ? NULL : n;
+    } else {
+        n = n->r;
+        while (n->l != NIL)
+            n = n->l;
+        return n;
+    }
 }
 
-rb_node *rb_tree_pred(rb_node *n)
+rb_node *rb_tree_pred(rb_node * n)
 {
-     if (!n) return NULL;
-     if (n->l == NIL) {
-         rb_node *prev;
-         do {
-              prev = n;
-              n = n->p;
-         } while (prev == n->l && n != NIL);
-         return n == NIL ? NULL : n;
-     }
-     else {
-         n = n->l;
-         while (n->r != NIL)
-              n = n->r;
-         return n;
-     }
+    if (!n)
+        return NULL;
+    if (n->l == NIL) {
+        rb_node *prev;
+        do {
+            prev = n;
+            n = n->p;
+        } while (prev == n->l && n != NIL);
+        return n == NIL ? NULL : n;
+    } else {
+        n = n->l;
+        while (n->r != NIL)
+            n = n->r;
+        return n;
+    }
 }
 
-rb_node *rb_tree_remove(rb_tree *t, rb_node *n)
+rb_node *rb_tree_remove(rb_tree * t, rb_node * n)
 {
-     rb_key k = n->k;
-     rb_node *m, *mp;
-     if (n->l != NIL && n->r != NIL) {
-         rb_node *lmax = n->l;
-         while (lmax->r != NIL) lmax = lmax->r;
-         n->k = lmax->k;
-         n = lmax;
-     }
-     m = n->l != NIL ? n->l : n->r;
-     if (n->p != NIL) {
-         if (n->p->r == n) n->p->r = m;
-         else n->p->l = m;
-     }
-     else
-         t->root = m;
-     mp = n->p;
-     if (m != NIL) m->p = mp;
-     if (n->c == BLACK) {
-         if (m->c == RED)
-              m->c = BLACK;
-         else {
-         deleteblack:
-              if (mp != NIL) {
-                   rb_node *s = m == mp->l ? mp->r : mp->l;
-                   if (s->c == RED) {
-                        mp->c = RED;
-                        s->c = BLACK;
-                        if (m == mp->l) rotate_left(mp, t);
-                        else rotate_right(mp, t);
-                        s = m == mp->l ? mp->r : mp->l;
-                   }
-                   if (mp->c == BLACK && s->c == BLACK
-                       && s->l->c == BLACK && s->r->c == BLACK) {
-                        if (s != NIL) s->c = RED;
-                        m = mp; mp = m->p;
-                        goto deleteblack;
-                   }
-                   else if (mp->c == RED && s->c == BLACK &&
-                            s->l->c == BLACK && s->r->c == BLACK) {
-                        if (s != NIL) s->c = RED;
-                        mp->c = BLACK;
-                   }
-                   else {
-                        if (m == mp->l && s->c == BLACK &&
-                            s->l->c == RED && s->r->c == BLACK) {
-                             s->c = RED;
-                             s->l->c = BLACK;
-                             rotate_right(s, t);
-                             s = m == mp->l ? mp->r : mp->l;
-                        }
-                        else if (m == mp->r && s->c == BLACK &&
-                                 s->r->c == RED && s->l->c == BLACK) {
-                             s->c = RED;
-                             s->r->c = BLACK;
-                             rotate_left(s, t);
-                             s = m == mp->l ? mp->r : mp->l;
-                        }
-                        s->c = mp->c;
-                        mp->c = BLACK;
-                        if (m == mp->l) {
-                             s->r->c = BLACK;
-                             rotate_left(mp, t);
-                        }
-                        else {
-                             s->l->c = BLACK;
-                             rotate_right(mp, t);
-                        }
-                   }
-              }
-         }
-     }
-     t->N--;
-     n->k = k; /* n may have changed during remove */
-     return n; /* the node that was deleted may be different from initial n */
+    rb_key k = n->k;
+    rb_node *m, *mp;
+    if (n->l != NIL && n->r != NIL) {
+        rb_node *lmax = n->l;
+        while (lmax->r != NIL)
+            lmax = lmax->r;
+        n->k = lmax->k;
+        n = lmax;
+    }
+    m = n->l != NIL ? n->l : n->r;
+    if (n->p != NIL) {
+        if (n->p->r == n)
+            n->p->r = m;
+        else
+            n->p->l = m;
+    } else
+        t->root = m;
+    mp = n->p;
+    if (m != NIL)
+        m->p = mp;
+    if (n->c == BLACK) {
+        if (m->c == RED)
+            m->c = BLACK;
+        else {
+          deleteblack:
+            if (mp != NIL) {
+                rb_node *s = m == mp->l ? mp->r : mp->l;
+                if (s->c == RED) {
+                    mp->c = RED;
+                    s->c = BLACK;
+                    if (m == mp->l)
+                        rotate_left(mp, t);
+                    else
+                        rotate_right(mp, t);
+                    s = m == mp->l ? mp->r : mp->l;
+                }
+                if (mp->c == BLACK && s->c == BLACK && s->l->c == BLACK && s->r->c == BLACK) {
+                    if (s != NIL)
+                        s->c = RED;
+                    m = mp;
+                    mp = m->p;
+                    goto deleteblack;
+                } else if (mp->c == RED && s->c == BLACK && s->l->c == BLACK && s->r->c == BLACK) {
+                    if (s != NIL)
+                        s->c = RED;
+                    mp->c = BLACK;
+                } else {
+                    if (m == mp->l && s->c == BLACK && s->l->c == RED && s->r->c == BLACK) {
+                        s->c = RED;
+                        s->l->c = BLACK;
+                        rotate_right(s, t);
+                        s = m == mp->l ? mp->r : mp->l;
+                    } else if (m == mp->r && s->c == BLACK && s->r->c == RED && s->l->c == BLACK) {
+                        s->c = RED;
+                        s->r->c = BLACK;
+                        rotate_left(s, t);
+                        s = m == mp->l ? mp->r : mp->l;
+                    }
+                    s->c = mp->c;
+                    mp->c = BLACK;
+                    if (m == mp->l) {
+                        s->r->c = BLACK;
+                        rotate_left(mp, t);
+                    } else {
+                        s->l->c = BLACK;
+                        rotate_right(mp, t);
+                    }
+                }
+            }
+        }
+    }
+    t->N--;
+    n->k = k;                   /* n may have changed during remove */
+    return n;                   /* the node that was deleted may be different from initial n */
 }
 
-rb_node *rb_tree_resort(rb_tree *t, rb_node *n)
+rb_node *rb_tree_resort(rb_tree * t, rb_node * n)
 {
-     n = rb_tree_remove(t, n);
-     insert_node(t, n);
-     return n;
+    n = rb_tree_remove(t, n);
+    insert_node(t, n);
+    return n;
 }
 
 /* shift all key pointers by kshift ... this is useful when the keys
    are pointers into another array, that has been resized with realloc */
-static void shift_keys(rb_node *n, ptrdiff_t kshift) /* assumes n != NIL */
-{
-     n->k += kshift;
-     if (n->l != NIL) shift_keys(n->l, kshift);
-     if (n->r != NIL) shift_keys(n->r, kshift);
+static void shift_keys(rb_node * n, ptrdiff_t kshift)
+{                               /* assumes n != NIL */
+    n->k += kshift;
+    if (n->l != NIL)
+        shift_keys(n->l, kshift);
+    if (n->r != NIL)
+        shift_keys(n->r, kshift);
 }
-void rb_tree_shift_keys(rb_tree *t, ptrdiff_t kshift)
+
+void rb_tree_shift_keys(rb_tree * t, ptrdiff_t kshift)
 {
-     if (t->root != NIL) shift_keys(t->root, kshift);
+    if (t->root != NIL)
+        shift_keys(t->root, kshift);
 }