static HklTreeNode* hkl_treenode_remove(HklTree* tree, HklTreeNode* node, HklString* key) { assert(node != NULL); assert(key != NULL); // If key < current node key, go left if (hkl_string_compare(key, node->pair->key) < 0) { if (node->left != NULL) { if (!hkl_treenode_isred(node->left) && hkl_treenode_isred(node->left->left)) node = hkl_treenode_redleft(node); node->left = hkl_treenode_remove(tree, node->left, key); } } else { if (hkl_treenode_isred(node->left)) node = hkl_treenode_rotright(node); if (hkl_string_compare(key, node->pair->key) == 0 && (node->right == NULL)) { --tree->size; hkl_treenode_free(node); return NULL; } if (node->right != NULL) { if (!hkl_treenode_isred(node->right) && !hkl_treenode_isred(node->right->left)) node = hkl_treenode_redright(node); if (hkl_string_compare(key, node->pair->key) == 0) { node->pair->value = hkl_treenode_findmin(node->right)->pair->value; node->right = hkl_treenode_removemin(tree, node->right); } else { node->right = hkl_treenode_remove(tree, node->right, key); } } } return hkl_treenode_fixup(node); }
static HklTreeNode* hkl_treenode_removemin(HklTreeNode* node) { if (node->left == NULL) { hkl_treenode_free(node); return NULL; } if (!hkl_treenode_isred(node->left) && !hkl_treenode_isred(node->left->left)) node = hkl_treenode_redleft(node); node->left = hkl_treenode_removemin(node->left); return hkl_treenode_fixup(node); }