在二叉搜索树中删除结点要比插入结点复杂得多,在当前递归层级一共要考虑五种不同的情况:
● 当前递归结点 (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;
}
};