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; }
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)); } }
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; }
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)); } }
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 }