LeetCode #450:Delete Node In A BST(删除二叉搜索树中的节点)

题目描述

在二叉搜索树中删除结点要比插入结点复杂得多,在当前递归层级一共要考虑五种不同的情况:

● 当前递归结点 (root) 为空,表明没有找到要删除的结点,返回 NULL;
● 当前递归结点 (root) 为叶子结点,直接删除并将空结点返回上层;
● 当前递归结点 (root) 左子树为空但右子树不空,用 root 的右子树替代 root 的位置;
● 当前递归结点 (root) 右子树为空但左子树不空,用 root 的左子树替代 root 的位置;
● 当前递归结点 (root) 左右子树都不空,把 root 的左子树,挂在 root 右子树的最左侧结点 (即 root 的中序后继) 的左子树处,再用 root 的右子树替代 root 的位置。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    TreeNode* deleteNode(TreeNode* root, int key) {
        if(root == NULL) // 没有找到待删除结点,直接返回
            return NULL;
        
        if(root->val == key) { // 当前结点即为待删除结点
            if(root->left == NULL && root->right == NULL) { // 当前结点(root)为叶子结点,直接删除并将空结点返回上层
                delete root;
                return NULL;
            } else if(root->left == NULL && root->right) { // 当前结点左子树为空但右子树不空,用root的右子树替代root的位置
                auto p = root->right;
                delete root;
                return p;
            } else if(root->left && root->right == NULL) { // 当前结点右子树为空但左子树不空,用root的左子树替代root的位置
                auto p = root->left;
                delete root;
                return p;
            } else { // 当前结点左右子树都不空,把root的左子树,挂在root右子树的最左侧结点(即root的中序后继)的左子树处,再用root的右子树替代root的位置
                auto q = root->right;
                while(q->left != NULL) {
                    q = q->left;
                }
                q->left = root->left;
                q = root->right;
                delete root;
                return q;
            }              
        } else if(root->val > key) { // 当前结点不为待删除结点,将下层递归删除的结果赋给左右子树
            root->left = deleteNode(root->left, key);
        } else {
            root->right = deleteNode(root->right, key);
        }

        return root;
    }
};

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注