自学内容网 自学内容网

代码随想录二刷 | 二叉树| 删除二叉搜索树中的节点

代码随想录二刷 | 二叉树| 删除二叉搜索树中的节点

题目描述

450.删除二叉搜索树中的节点

给定一个二叉搜索树的根节点 root 和一个值 key,删除二叉搜索树中的 key 对应的节点,并保证二叉搜索树的性质不变。返回二叉搜索树(有可能被更新)的根节点的引用。

一般来说,删除节点可分为两个步骤:

首先找到需要删除的节点; 如果找到了,删除它。 说明: 要求算法时间复杂度为 O ( h ) O(h) O(h),h 为树的高度。

示例:
在这里插入图片描述

解题思路

递归三部曲

  1. 确定递归函数参数以及返回值
    参数:根节点与值key
    返回值:TreeNode*
    TreeNode* deleteNode(TreeNode* root, int key)
    
  2. 确定递归函数的终止条件
    遇到空就返回。
    if (root == nullptr) return root;
    
  3. 确定单层递归的逻辑
    情况一:没找到删除的节点,遍历到空节点直接返回
    情况二:找到删除的节点,左右孩子都为空,删除节点,返回NULL为根节点。
    情况三:找到删除的节点,删除节点的左孩子为空,右孩子不为空,删除节点,右孩子补位,返回右孩子为根节点。
    情况四:找到删除的节点,删除节点的右孩子为空,左孩子不为空,删除节点,左孩子补位,返回左孩子为根节点。
    情况五:找到删除的节点,左右孩子节点都不为空,则将删除节点的左子树头节点(左孩子)放到删除节点的右子树的最左面节点的左孩子上,返回删除节点右孩子为新的根节点。
    if (root->val == key) {
    // 情况二、情况三
    if (root->left == nullptr) return root->right;
    // 情况四
    else if (root->right == nullptr) return root->left;
    // 情况五
    else {
    TreeNode* cur = root->right; // 找右子树最左面的节点
    while (cur->left != nullptr) {
    cur = cur->left;
    }
    cur->left = root->left; // 把要删除的节点的左子树放在cur的左孩子位置
    TreeNode* temp = root;// 保存一下root
    root = root->right; // 返回旧root的右孩子作为新root
    delete temp; // 释放内存
    return root;
    }
    }
    
    这里相当于把新的节点返回给上一层,上一层就要用 root->left 或者 root->right接住,代码如下:
    if (root->val > key) root->left = deleteNode(root->left, key);
    if (root->val < key) root->right = deleteNode(root->right, key);
    return root;
    

代码实现

class Solution {
public:
TreeNode* deleteNode(TreeNode* root, int key) {
if (root == nullptr) return root; // 情况一
if (root->val == key) {
// 情况二
if (root->left == nullptr && root->right == nullptr) {
delete root;
return nullptr;
} else if (root->left == nullptr) { // 情况三
auto retNode = root->right;
delete root;
return retNode;
} else if (root->right == nullptr) { // 情况四
auto retNode = root->left;
delete root;
return retNode;
} else { // 情况五
TreeNode* cur = root->right; // 找右子树最左面的节点
while (cur->left != nullptr) {
cur = cur->left;
}
cur->left = root->left; // 把要删除的节点的左子树放在cur的左孩子的位置
TreeNode* temp = root; // 把root节点保存一下
root = root->right; // 返回旧root的右孩子作为新root
delete temp; // 释放内存
return root;
}
}
if (root->val > key) root->left = deleteNode(root->left, key);
if (root->val < key) root->right = deleteNode(root->right, key);
}
};

原文地址:https://blog.csdn.net/jivvv/article/details/135705887

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!