Beispiel #1
0
void jrb_iprint_tree(JRB t, int level)
{
  int i;
  if (ishead(t) && t->parent == t) {
    printf("tree 0x%x is empty\n", t);
  } else if (ishead(t)) {
    printf("Head: 0x%x.  Root = 0x%x, < = 0x%x, > = 0x%x\n", 
            t, t->parent, t->blink, t->flink);
    jrb_iprint_tree(t->parent, 0);
  } else {
    if (isext(t)) {
      for (i = 0; i < level; i++) putchar(' ');
      printf("Ext node 0x%x: %c,%c: p=0x%x, <=0x%x, >=0x%x k=%d\n", 
              t, isred(t)?'R':'B', isleft(t)?'l':'r', t->parent, 
              t->blink, t->flink, t->key.i);
    } else {
      jrb_iprint_tree(t->flink, level+2);
      jrb_iprint_tree(t->blink, level+2);
      for (i = 0; i < level; i++) putchar(' ');
      printf("Int node 0x%x: %c,%c: l=0x%x, r=0x%x, p=0x%x, lr=(%d,%d)\n", 
              t, isred(t)?'R':'B', isleft(t)?'l':'r', t->flink, 
              t->blink, 
              t->parent, getlext(t)->key.i, getrext(t)->key.i);
    }
  }
}
Beispiel #2
0
void rb_iprint_tree(Rb_node t, int level)
{
  int i;
  if (ishead(t) && t->p.parent == t) {
    printf("tree 0x%p is empty\n", (void *) t);
  } else if (ishead(t)) {
    printf("Head: 0x%p.  Root = 0x%p, < = 0x%p, > = 0x%p\n", 
	   (void *) t, (void *) t->p.root, 
	   (void *) t->c.list.blink, (void *) t->c.list.flink);
    rb_iprint_tree(t->p.root, 0);
  } else {
    if (isext(t)) {
      for (i = 0; i < level; i++) putchar(' ');
      printf("Ext node 0x%p: %c,%c: p=0x%p, <=0x%p, >=0x%p k=%d\n", 
	     (void *) t, isred(t)?'R':'B', isleft(t)?'l':'r', 
	     (void *) t->p.parent, (void *) t->c.list.blink, 
	     (void *) t->c.list.flink, t->k.ikey);
    } else {
      rb_iprint_tree(t->c.child.left, level+2);
      rb_iprint_tree(t->c.child.right, level+2);
      for (i = 0; i < level; i++) putchar(' ');
      printf("Int node 0x%p: %c,%c: l=0x%p, r=0x%p, p=0x%p, lr=(%d,%d)\n", 
	     (void *) t, isred(t)?'R':'B', isleft(t)?'l':'r', 
	     (void *) t->c.child.left, (void *) t->c.child.right, 
             (void *) t->p.parent, t->k.lext->k.ikey, t->v.rext->k.ikey);
    }
  }
}
Beispiel #3
0
static rbtree_node* fixup(rbtree_node *h) {
    if ( isred(h->right) )
        h = rotate_left(h);

    if ( isred(h->left) && isred(h->left->left) )
        h = rotate_right(h);

    if ( isred(h->left) && isred(h->right) )
        colorflip(h);

    return set_num_nodes(h);
}
Beispiel #4
0
static rbtree_node* delete_min(rbtree_node *h, VALUE *deleted_value) {
    if ( !h->left ) {
        if(deleted_value)
            *deleted_value = h->value;
        free(h);
        return NULL;
    }

    if ( !isred(h->left) && !isred(h->left->left) )
        h = move_red_left(h);

    h->left = delete_min(h->left, deleted_value);

    return fixup(h);
}
Beispiel #5
0
static rbtree_node* delete_max(rbtree_node *h, VALUE *deleted_value) {
    if ( isred(h->left) )
        h = rotate_right(h);

    if ( !h->right ) {
        *deleted_value = h->value;
        free(h);
        return NULL;
    }

    if ( !isred(h->right) && !isred(h->right->left) )
        h = move_red_right(h);

    h->right = delete_max(h->right, deleted_value);

    return fixup(h);
}
Beispiel #6
0
static rbtree_node* move_red_right(rbtree_node *h) {
    colorflip(h);
    if ( isred(h->left->left) ) {
        h = rotate_right(h);
        colorflip(h);
    }
    return h;
}
Beispiel #7
0
static rbtree_node* insert(rbtree *tree, rbtree_node *node, VALUE key, VALUE value) {
    int cmp;

    // This slot is empty, so we insert our new node
    if(!node) {
        rbtree_node *new_node = ALLOC(rbtree_node);
        new_node->key		= key;
        new_node->value		= value;
        new_node->color		= RED;
        new_node->height	= 1;
        new_node->num_nodes = 1;
        new_node->left		= NULL;
        new_node->right		= NULL;
        return new_node;
    }

    // Insert left or right, recursively
    cmp = tree->compare_function(key, node->key);
    if		(cmp == 0)	{
        node->value = value;
    }
    else if (cmp == -1) {
        node->left	= insert(tree, node->left, key, value);
    }
    else				{
        node->right = insert(tree, node->right, key, value);
    }

    // Fix our tree to keep left-lean
    if (isred(node->right)) {
        node = rotate_left(node);
    }
    if (isred(node->left) && isred(node->left->left)) {
        node = rotate_right(node);
    }
    if ( isred(node->left) && isred(node->right) ) {
        colorflip(node);
    }
    return set_num_nodes(node);
}
Beispiel #8
0
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);
    }
}
Beispiel #9
0
void jrb_delete_node(JRB n)
{
  JRB s, p, gp;
  char ir;

  if (isint(n)) {
    fprintf(stderr, "Cannot delete an internal node: 0x%p\n", (void *)n);
    exit(1);
  }
  if (ishead(n)) {
    fprintf(stderr, "Cannot delete the head of an jrb_tree: 0x%p\n", (void *)n);
    exit(1);
  }
  delete_item(n); /* Delete it from the list */
  p = n->parent;  /* The only node */
  if (isroot(n)) {
    p->parent = p;
    free(n);
    return;
  }
  s = sibling(n);    /* The only node after deletion */
  if (isroot(p)) {
    s->parent = p->parent;
    s->parent->parent = s;
    setroot(s);
    free(p);
    free(n);
    return;
  }
  gp = p->parent;  /* Set parent to sibling */
  s->parent = gp;
  if (isleft(p)) {
    gp->flink = s;
    setleft(s);
  } else {
    gp->blink = s;
    setright(s);
  }
  ir = isred(p);
  free(p);
  free(n);

  if (isext(s)) {      /* Update proper rext and lext values */
    p = lprev(s);
    if (!ishead(p)) setrext(p, s);
    p = rprev(s);
    if (!ishead(p)) setlext(p, s);
  } else if (isblack(s)) {
    fprintf(stderr, "DELETION PROB -- sib is black, internal\n");
    exit(1);
  } else {
    p = lprev(s);
    if (!ishead(p)) setrext(p, s->flink);
    p = rprev(s);
    if (!ishead(p)) setlext(p, s->blink);
    setblack(s);
    return;
  }

  if (ir) return;

  /* Recolor */

  n = s;
  p = n->parent;
  s = sibling(n);
  while(isblack(p) && isblack(s) && isint(s) &&
        isblack(s->flink) && isblack(s->blink)) {
    setred(s);
    n = p;
    if (isroot(n)) return;
    p = n->parent;
    s = sibling(n);
  }

  if (isblack(p) && isred(s)) {  /* Rotation 2.3b */
    single_rotate(p, isright(n));
    setred(p);
    setblack(s);
    s = sibling(n);
  }

  { JRB x, z; char il;

    if (isext(s)) {
      fprintf(stderr, "DELETION ERROR: sibling not internal\n");
      exit(1);
    }

    il = isleft(n);
    x = il ? s->flink : s->blink ;
    z = sibling(x);

    if (isred(z)) {  /* Rotation 2.3f */
      single_rotate(p, !il);
      setblack(z);
      if (isred(p)) setred(s); else setblack(s);
      setblack(p);
    } else if (isblack(x)) {   /* Recoloring only (2.3c) */
      if (isred(s) || isblack(p)) {
        fprintf(stderr, "DELETION ERROR: 2.3c not quite right\n");
        exit(1);
      }
      setblack(p);
      setred(s);
      return;
    } else if (isred(p)) { /* 2.3d */
      single_rotate(s, il);
      single_rotate(p, !il);
      setblack(x);
      setred(s);
      return;
    } else {  /* 2.3e */
      single_rotate(s, il);
      single_rotate(p, !il);
      setblack(x);
      return;
    }
  }
}