1 问题
给定一个二叉搜索树的根节点 root 和一个值 key,删除二叉搜索树中的 key 对应的节点,并保证二叉搜索树的性质不变。返回二叉搜索树(有可能被更新)的根节点的引用。
一般来说,删除节点可分为两个步骤:
首先找到需要删除的节点;如果找到了,删除它。说明:要求算法时间复杂度为 O(h),h 为树的高度。
示例:
2 解法
/**
* 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) {
//1.没找到删除的节点,遍历到空节点,直接返回根节点
if(root == nullptr)
return root;
//找到key值所在的节点
if(root->val == key)
{
//2.删除的节点左、右子树都为空,直接删除该节点
//3.删除的节点左子树为空,右子树不为空,删除节点,右子树补位,返回右节点为根节点
if(root->left == nullptr)
return root->right;
//4.删除的节点右子树为空,删除节点,左子树补位,返回左节点为根节点
else if(root->right == nullptr)
return root->left;
//5.删除的节点左右子树都不为空,将删除节点的左子树放到删除节点右子树最左边节点的左孩子位置
//删除节点,并返回删除节点的右节点为新的根节点
else
{
//5.1找到右子树最左边的节点
TreeNode* cur = root->right;
while(cur->left != nullptr)
{
cur = cur->left; //循环结束时,cur指向最左边节点
}
//5.2将删除结点的左子树放到cur的位置
cur->left = root->left;
//5.3记录删除节点,稍后释放内存
TreeNode* tmp = root;
//5.4将删除结点的右节点放到删除节点处
root = root->right;
//5.5释放删除节点
delete tmp;
//返回新的根节点
return root;
}
}
if(root->val > key) root->left = deleteNode(root->left, key);
if(root->val < key) root->right = deleteNode(root->right, key);
return root;
}
};