LeetCode //C - 450. Delete Node in a BST

450. Delete Node in a BST

Given a root node reference of a BST and a key, delete the node with the given key in the BST. Return the root node reference (possibly updated) of the BST.

Basically, the deletion can be divided into two stages:

  1. Search for a node to remove.
  2. If the node is found, delete the node.
     
Example 1:

LeetCode //C - 450. Delete Node in a BST_第1张图片

Input: root = [5,3,6,2,4,null,7], key = 3
Output: [5,4,6,2,null,null,7]
Explanation: Given key to delete is 3. So we find the node with value 3 and delete it.
One valid answer is [5,4,6,2,null,null,7], shown in the above BST.
Please notice that another valid answer is [5,2,6,null,4,null,7] and it’s also accepted.

Example 2:

LeetCode //C - 450. Delete Node in a BST_第2张图片

Input: root = [5,3,6,2,4,null,7], key = 0
Output: [5,3,6,2,4,null,7]
Explanation: The tree does not contain a node with value = 0.

Example 3:

Input: root = [], key = 0
Output: []

Constraints:
  • The number of nodes in the tree is in the range [ 0 , 1 0 4 ] [0, 10^4] [0,104].
  • − 1 0 5 < = N o d e . v a l < = 1 0 5 -10^5 <= Node.val <= 10^5 105<=Node.val<=105
  • Each node has a unique value.
  • root is a valid binary search tree.
  • − 1 0 5 < = k e y < = 1 0 5 -10^5 <= key <= 10^5 105<=key<=105

From: LeetCode
Link: 450. Delete Node in a BST


Solution:

Ideas:

1. Base Case Check: If the root is NULL, there’s nothing to delete, and the function returns NULL.

2. Recursive Search:

  • If the key is less than root->val, we need to go to the left subtree (root->left), as in a BST all keys in the left subtree are smaller than the node’s key.
  • If the key is greater than root->val, we search in the right subtree (root->right), where all keys are greater.

3. Node Deletion: Once the node to be deleted (root) is found (i.e., root->val is equal to key), there are three scenarios to handle:

  • No Child or One Child: If the node is a leaf (no children) or has only one child, the node can be deleted and replaced by its child (if any). If there’s no left child, we return the right child, and vice versa. If there are no children, NULL is returned after freeing the node.
  • Two Children: If the node has two children, the algorithm finds the in-order successor of the node, which is the smallest value in the right subtree. This is handled by the helper function findMin, which iteratively goes to the leftmost node of the right subtree.
    • The root->val is replaced with the value of the in-order successor (temp->val).
    • The in-order successor node is then deleted from the right subtree. This is because we have now duplicated the in-order successor’s value at two places in the BST: the node to be deleted and the actual in-order successor’s position. Deleting the successor from its original position ensures the BST property is maintained.

4. Returning the New Tree: The function returns the updated root pointer, which points to the BST after the deletion operation is completed.

Code:
struct TreeNode* findMin(struct TreeNode* node) {
    while (node->left != NULL) node = node->left;
    return node;
}

struct TreeNode* deleteNode(struct TreeNode* root, int key) {
    if (root == NULL) return root; // Base case: the tree is empty
    
    // Recursive calls for the children of the node
    if (key < root->val) { // The key to be deleted is in the left subtree
        root->left = deleteNode(root->left, key);
    } else if (key > root->val) { // The key to be deleted is in the right subtree
        root->right = deleteNode(root->right, key);
    } else { // The node to be deleted has been found
        // Case 1: The node has no child or only one child
        if (root->left == NULL) {
            struct TreeNode* temp = root->right;
            free(root);
            return temp;
        } else if (root->right == NULL) {
            struct TreeNode* temp = root->left;
            free(root);
            return temp;
        }
        
        // Case 2: The node has two children
        struct TreeNode* temp = findMin(root->right); // Find the in-order successor
        
        // Copy the in-order successor's content to this node
        root->val = temp->val;
        
        // Delete the in-order successor
        root->right = deleteNode(root->right, temp->val);
    }
    return root; // Return the (possibly updated) root pointer
}

你可能感兴趣的:(LeetCode,leetcode,c语言,算法)