void rbtree_delete(rbtree t, void* key, compare_func compare) { node child; node n = lookup_node(t, key, compare); if (n == NULL) return; /* Key not found, do nothing */ if (n->left != NULL && n->right != NULL) { /* Copy key/value from predecessor and then delete it instead */ node pred = maximum_node(n->left); n->key = pred->key; n->value = pred->value; n = pred; } assert(n->left == NULL || n->right == NULL); child = n->right == NULL ? n->left : n->right; if (node_color(n) == BLACK) { n->color = node_color(child); delete_case1(t, n); } replace_node(t, n, child); if (n->parent == NULL && child != NULL) child->color = BLACK; free(n); verify_properties(t); }
void rbtree_insert(rbtree t, void* key, void* value, compare_func compare) { node inserted_node = new_node(key, value, RED, NULL, NULL); if (t->root == NULL) { t->root = inserted_node; } else { node n = t->root; while (1) { int comp_result = compare(key, n->key); if (comp_result == 0) { n->value = value; /* inserted_node isn't going to be used, don't leak it */ free (inserted_node); return; } else if (comp_result < 0) { if (n->left == NULL) { n->left = inserted_node; break; } else { n = n->left; } } else { assert (comp_result > 0); if (n->right == NULL) { n->right = inserted_node; break; } else { n = n->right; } } } inserted_node->parent = n; } insert_case1(t, inserted_node); verify_properties(t); }
/* * l_rbtreeCreate() * * Input: keytype (defined by an enum for an RB_TYPE union) * Return: rbtree (container with empty ptr to the root) */ L_RBTREE * l_rbtreeCreate(l_int32 keytype) { PROCNAME("l_rbtreeCreate"); if (keytype != L_INT_TYPE && keytype != L_UINT_TYPE && keytype != L_FLOAT_TYPE && keytype) return (L_RBTREE *)ERROR_PTR("invalid keytype", procName, NULL); L_RBTREE *t = (L_RBTREE *)LEPT_CALLOC(1, sizeof(L_RBTREE)); t->keytype = keytype; verify_properties(t); return t; }
/* * l_rbtreeInsert() * * Input: t (rbtree, including root node) * key (insert a node with this key, if the key does not already * exist in the tree) * value (typically an int, used for an index) * Return: void * * Notes: * (1) If a node with the key already exists, this just updates the value. */ void l_rbtreeInsert(L_RBTREE *t, RB_TYPE key, RB_TYPE value) { node *n, *inserted_node; PROCNAME("l_rbtreeInsert"); if (!t) { L_ERROR("tree is null\n", procName); return; } inserted_node = new_node(key, value, L_RED_NODE, NULL, NULL); if (t->root == NULL) { t->root = inserted_node; } else { n = t->root; while (1) { int comp_result = l_compareKeys(t->keytype, key, n->key); if (comp_result == 0) { n->value = value; LEPT_FREE(inserted_node); return; } else if (comp_result < 0) { if (n->left == NULL) { n->left = inserted_node; break; } else { n = n->left; } } else { /* comp_result > 0 */ if (n->right == NULL) { n->right = inserted_node; break; } else { n = n->right; } } } inserted_node->parent = n; } insert_case1(t, inserted_node); verify_properties(t); }
/* * l_rbtreeDelete() * * Input: t (rbtree, including root node) * key (delete the node with this key) * Return: void */ void l_rbtreeDelete(L_RBTREE *t, RB_TYPE key) { node *n, *child; PROCNAME("l_rbtreeDelete"); if (!t) { L_ERROR("tree is null\n", procName); return; } n = lookup_node(t, key); if (n == NULL) return; /* Key not found, do nothing */ if (n->left != NULL && n->right != NULL) { /* Copy key/value from predecessor and then delete it instead */ node *pred = maximum_node(n->left); n->key = pred->key; n->value = pred->value; n = pred; } /* n->left == NULL || n->right == NULL */ child = n->right == NULL ? n->left : n->right; if (node_color(n) == L_BLACK_NODE) { n->color = node_color(child); delete_case1(t, n); } replace_node(t, n, child); if (n->parent == NULL && child != NULL) /* root should be black */ child->color = L_BLACK_NODE; LEPT_FREE(n); verify_properties(t); }
rbtree rbtree_create() { rbtree t = malloc(sizeof(struct rbtree_t)); t->root = NULL; verify_properties(t); return t; }