Esempio n. 1
0
Node * node_uncle(Node * n)
{
    Node * g = node_grandparent(n);
    if (!g)
    {
        return NULL;
    }
    if (n->parent == g->left)
    {
        return g->right;
    }
    else
    {
        return g->left;
    }
}
Esempio n. 2
0
void map_insert(map_t *map, mapkey_t key, void *p)
{
  allocator_t *alloc = map->allocator;
  mapnode_t *parent = map->root;
  mapnode_t **slot = &map->root;
  mapnode_t *insert;

  while (parent != NIL) {
    int comparison = map->ops.compare_key(key, parent->key);
    if (comparison == 0) {
      map->ops.destroy_value(parent->p, alloc);
      parent->p = map->ops.copy_value(p, alloc);
      return;
    } else if (comparison < 0) {
      if (parent->left != NIL) {
        parent = parent->left;
        continue;
      } else {
        slot = &parent->left;
        break;
      }
    } else {
      if (parent->right != NIL) {
        parent = parent->right;
        continue;
      } else {
        slot = &parent->right;
        break;
      }
    }
  }

  map->size += 1;
  insert = (mapnode_t *)com_malloc(map->allocator, sizeof(mapnode_t));
  insert->left = insert->right = NIL;
  insert->key = map->ops.copy_key(key, alloc);
  insert->p = map->ops.copy_value(p, alloc);
  insert->color = RED;
  insert->parent = parent;

  *slot = insert;

  while (IS_RED(insert->parent) && node_grandparent(insert) != NIL) {
    mapnode_t *uncle = node_sibling(insert->parent);
    if (IS_RED(uncle)) {
      insert->parent->color = BLACK;
      uncle->color = BLACK;
      uncle->parent->color = RED;
      insert = uncle->parent;
    } else {
      int insleft = IS_LEFT(insert);
      int parleft = IS_LEFT(insert->parent);

      if (!insleft && parleft) {
        insert = insert->parent;
        node_rotate_left(map, insert);
      } else if (insleft && !parleft) {
        insert = insert->parent;
        node_rotate_right(map, insert);
      }

      insert->parent->parent->color = RED;
      insert->parent->color = BLACK;

      if (parleft)
        node_rotate_right(map, insert->parent->parent);
      else
        node_rotate_left(map, insert->parent->parent);
    }
  }

  map->root->color = BLACK;

#if !defined(NDEBUG)
  map_test(map->root);
#endif
}