// do a little dance static inline BSTreeNode *BSTree_node_delete(BSTree *map, BSTreeNode *node, void *key) { int cmp = map->compare(node->key, key); if (cmp < 0) { if (node->left) { return BSTree_node_delete(map, node->left, key); } else { return NULL; } } else if (cmp > 0) { if (node->right) { return BSTree_node_delete(map, node->right, key); } else { return NULL; } } else { if (node->left && node->right) { BSTreeNode *successor = BSTree_find_min(node->right); BSTree_swap(successor, node); BSTree_replace_node_in_parent(map, successor, successor->right); return successor; } else if (node->left) { BSTree_replace_node_in_parent(map, node, node->left); } else if (node->right) { BSTree_replace_node_in_parent(map, node, node->right); } else { BSTree_replace_node_in_parent(map, node, NULL); } return node; } }
static inline BSTreeNode *BSTree_node_delete(BSTree *map, BSTreeNode *node, void *key) { int cmp = map->compare(node->key, key); if (cmp < 0) { if (node->left) { return BSTree_node_delete(map, node->left, key); } else { // not found return NULL; } } else if (cmp > 0) { if (node->right) { return BSTree_node_delete(map, node->right, key); } else { // not found return NULL; } } else { map->count--; if (node->left && node->right) { // swap this node for the smallest node that is bigger than us BSTreeNode *successor = BSTree_find_min(node->right); BSTree_swap(successor, node); // this leaves the old successor with possibly a right child // so replace it with that right child BSTree_replace_node_in_parent(map, successor, successor->right); // finally it's swapped, so return successor instead of node return successor; } else if (node->left) { BSTree_replace_node_in_parent(map, node, node->left); } else if (node->right) { BSTree_replace_node_in_parent(map, node, node->right); } else { BSTree_replace_node_in_parent(map, node, NULL); } return node; } }