struct node* delete(struct node* node, int target)
{
struct node *child = node, *parent = NULL, **branch = &node;
// Branch is a pointer to the left or right branch that we take to get to the correct node.
// This information is saved so we don't have to use an if/else test to determine it later.
while (child != NULL && target != child->data)
{
parent = child;
branch = target < child->data ? &child->left
: &child->right;
child = *branch;
}
if (child == NULL)
{
return NULL;
}
switch ((child->left == NULL) * 2 +
(child->right == NULL))
{
case 3: // leaf node
*branch = NULL;
break;
case 2: // node with right child
*branch = child->right;
break;
case 1: // node with left child
*branch = child->left;
break;
case 0: // node with both left and right children
parent = child;
child = child->right;
while (child->left != NULL) {
parent = child;
child = child->left;
}
*branch->data = child->data;
if (parent == *branch) {
parent->right = child->right;
}
else {
parent->left = NULL;
}
}
return node;
}
c3RydWN0IG5vZGUqIGRlbGV0ZShzdHJ1Y3Qgbm9kZSogbm9kZSwgaW50IHRhcmdldCkKewogICAgc3RydWN0IG5vZGUgKmNoaWxkID0gbm9kZSwgKnBhcmVudCA9IE5VTEwsICoqYnJhbmNoID0gJm5vZGU7CgogICAgLy8gQnJhbmNoIGlzIGEgcG9pbnRlciB0byB0aGUgbGVmdCBvciByaWdodCBicmFuY2ggdGhhdCB3ZSB0YWtlIHRvIGdldCB0byB0aGUgY29ycmVjdCBub2RlLgogICAgLy8gVGhpcyBpbmZvcm1hdGlvbiBpcyBzYXZlZCBzbyB3ZSBkb24ndCBoYXZlIHRvIHVzZSBhbiBpZi9lbHNlIHRlc3QgdG8gZGV0ZXJtaW5lIGl0IGxhdGVyLgogICAgd2hpbGUgKGNoaWxkICE9IE5VTEwgJiYgdGFyZ2V0ICE9IGNoaWxkLT5kYXRhKQogICAgewogICAgICAgIHBhcmVudCA9IGNoaWxkOwogICAgICAgIGJyYW5jaCA9IHRhcmdldCA8IGNoaWxkLT5kYXRhID8gJmNoaWxkLT5sZWZ0CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiAmY2hpbGQtPnJpZ2h0OwoKICAgICAgICBjaGlsZCA9ICpicmFuY2g7CiAgICB9CgogICAgaWYgKGNoaWxkID09IE5VTEwpCiAgICB7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgc3dpdGNoICgoY2hpbGQtPmxlZnQgPT0gTlVMTCkgKiAyICsKICAgICAgICAgICAgKGNoaWxkLT5yaWdodCA9PSBOVUxMKSkKICAgIHsKICAgICAgICBjYXNlIDM6IC8vIGxlYWYgbm9kZQogICAgICAgICAgICAqYnJhbmNoID0gTlVMTDsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAyOiAvLyBub2RlIHdpdGggcmlnaHQgY2hpbGQKICAgICAgICAgICAgKmJyYW5jaCA9IGNoaWxkLT5yaWdodDsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAxOiAvLyBub2RlIHdpdGggbGVmdCBjaGlsZAogICAgICAgICAgICAqYnJhbmNoID0gY2hpbGQtPmxlZnQ7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMDogLy8gbm9kZSB3aXRoIGJvdGggbGVmdCBhbmQgcmlnaHQgY2hpbGRyZW4KICAgICAgICAgICAgcGFyZW50ID0gY2hpbGQ7CiAgICAgICAgICAgIGNoaWxkID0gY2hpbGQtPnJpZ2h0OwogICAgICAgICAgICB3aGlsZSAoY2hpbGQtPmxlZnQgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgcGFyZW50ID0gY2hpbGQ7CiAgICAgICAgICAgICAgICBjaGlsZCA9IGNoaWxkLT5sZWZ0OwogICAgICAgICAgICB9CiAgICAgICAgICAgICpicmFuY2gtPmRhdGEgPSBjaGlsZC0+ZGF0YTsKICAgICAgICAgICAgaWYgKHBhcmVudCA9PSAqYnJhbmNoKSB7CiAgICAgICAgICAgICAgICBwYXJlbnQtPnJpZ2h0ID0gY2hpbGQtPnJpZ2h0OwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgcGFyZW50LT5sZWZ0ID0gTlVMTDsKICAgICAgICAgICAgfQogICAgfQoKICAgIGZyZWUoY2hpbGQpOwogICAgcmV0dXJuIG5vZGU7Cn0K