示例#1
0
static chula_avl_generic_node_t *
node_balance (chula_avl_generic_node_t *node)
{
	if (node->balance < -1) {
		if (node->left->balance > 0)
			node->left = node_rotate_left (node->left);
		node = node_rotate_right (node);

	} else if (node->balance > 1) {
		if (node->right->balance < 0)
			node->right = node_rotate_right (node->right);
		node = node_rotate_left (node);
	}

	return node;
}
示例#2
0
void rb_tree_insert_repair(tree_t *tree, node_t *n)
{
	// przypadek 1: korzeń
    if (is_nil(parent(n)))
	{
        n->color = BLACK;
		return;
	}
    
	// przypadek 2: rodzic czarny
	if (parent(n)->color == BLACK)
		return;

	// przypadek 3: rodzic czerwony; wuj czerwony;
	if (!is_nil(uncle(n)) && uncle(n)->color == RED)
	{
		parent(n)->color = BLACK;
		uncle(n)->color = BLACK;
		grandparent(n)->color = RED;

		rb_tree_insert_repair(tree, grandparent(n));
	}
	else
	// przypadek 4: rodzic czerwony; wuj czarny;
	{
		if (is_right_child(n) && is_left_child(parent(n)))
		{
			node_rotate_left(tree, parent(n));
			n = n->left;
		}
		else if (is_left_child(n) && is_right_child(parent(n)))
		{
			node_rotate_right(tree, parent(n));
			n = n->right;
		}

		// case 5: wuj czarny; nowy, rodzic, dziadek na prostej; nowy i rodzic czerwoni;
		parent(n)->color = BLACK;
		grandparent(n)->color = RED;

		if (is_left_child(n) && is_left_child(parent(n)))
			node_rotate_right(tree, grandparent(n));
		else
			node_rotate_left(tree, grandparent(n));
	}
}
示例#3
0
static inline
avl_tree_node_t *node_balance(avl_tree_node_t *n) {
    node_fix_height(n);

    switch (node_balance_factor(n)) {
        case 2:
            if (node_balance_factor(n->left) < 0)
                n->left = node_rotate_left(n->left);

            n = node_rotate_right(n);
            break;

        case -2:
            if (node_balance_factor(n->right) > 0)
                n->right = node_rotate_right(n->right);

            n = node_rotate_left(n);
            break;
    }

    return n;
}
示例#4
0
void rb_tree_delete_repair(tree_t *tree, node_t *n)
{
	// przypadek 1: korzeń lub czerwony
    if (is_nil(parent(n)) || n->color == RED)
        return;
    
	// przypadek 2:
    if (sibling(n)->color == RED)
	{
        parent(n)->color = RED;
        sibling(n)->color = BLACK;

        if (is_left_child(n))
            node_rotate_left(tree, parent(n));
        else
            node_rotate_right(tree, parent(n));
    }

	// przypadek 3: 
    if (parent(n)->color == BLACK && sibling(n)->color == BLACK && sibling(n)->left->color == BLACK && sibling(n)->right->color == BLACK)
    {
        sibling(n)->color = RED;
        rb_tree_delete_repair(tree, parent(n));
		return;
    }

	// przypadek 4:
    if (parent(n)->color == RED && sibling(n)->color == BLACK && sibling(n)->left->color == BLACK && sibling(n)->right->color == BLACK)
    {
        sibling(n)->color = RED;
        parent(n)->color = BLACK;
		return;
    }

	// przypadek 5
    if (is_left_child(n) && sibling(n)->color == BLACK && sibling(n)->left->color == RED && sibling(n)->right->color == BLACK)
    {
        sibling(n)->color = RED;
        sibling(n)->left->color = BLACK;

        node_rotate_right(tree, sibling(n));
    }
    else if (is_right_child(n) && sibling(n)->color == BLACK &&	sibling(n)->right->color == RED && sibling(n)->left->color == BLACK)
    {
        sibling(n)->color = RED;
        sibling(n)->right->color = BLACK;

        node_rotate_left(tree, sibling(n));
    }

	// przypadek 6:
    sibling(n)->color = parent(n)->color;
    parent(n)->color = BLACK;

    if (is_left_child(n))
	{
        sibling(n)->right->color = BLACK;

        node_rotate_left(tree, parent(n));
    }
    else
    {
        sibling(n)->left->color = BLACK;

        node_rotate_right(tree, parent(n));
    }
}
示例#5
0
文件: map.c 项目: nilium/snow-palm
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
}