【LeetCode450】Delete Node in BST二叉搜索树删除节点
2017-04-09 21:16
537 查看
一、原题重现
题干中给定一个二叉搜索树(BST)的根节点以及一个给定的值,要求我们删除BST中与该值相等的节点,并且删除节点后,该树仍旧满足二叉搜索树的性质。下面举出一个例子
二、思路分析
二叉搜索树最大的特点就是左孩子节点的值小于或等于根节点,右孩子节点的值大于或等于根节点,再延伸一点就是左子树的每一个节点值都要小于根节点,而右子树的每一个节点值一定大于根节点。因此在删除原有节点后,树的结构需要作出一些调整后才能继续满足这个性质,这个调整也是这题的难点所在。
那么对于一个节点来说,它的可能情况就是只有左孩子,只有右孩子,左孩子右孩子都有,左孩子右孩子都没有。我们对于删除节点后树的调整也分为这四种情况进行。第一种,当被删除节点只有左孩子节点时,我们只需要将其左孩子节点替换掉该节点即可。当被删除节点只有右孩子节点时,同样的,我们只需要将右孩子节点替换掉该节点即可。当被删除节点既没有左孩子节点也没有右孩子节点时,即为叶节点,直接将该节点变为空值,即ROOT=NULL。当即有左孩子节点又有右孩子节点时,这时的变化较为复杂些,我们选择在被删除节点中找到它右子树中最小的那个节点,该节点一定是处于右子树的叶节点中,我们可以先将该叶节点的值赋予给被删除节点,然后将该叶节点赋予空值,即将该叶节点去替换掉被删除节点。
通过以上的思路,我们可以顺利删除节点使得BST仍然成立。只是在第四种情况下,还需要去寻找出右子树中的最小值节点。通过BST的规律我们可知,右子树的最小节点一定是该子树中最左边的那个叶节点,我们只需不断递归找出该子树中最左边那个叶节点即可。
三、C++代码实现
class Solution {
public:
TreeNode* deleteNode(TreeNode* root, int key) {
if(root == NULL) return NULL;
if(root->val > key) {
root->left = deleteNode(root->left,key);
} else if(root->val < key) {
root->right = deleteNode(root->right,key);
} else {
if(root->left == NULL) {
root = root->right;
} else if(root->right == NULL) {
root = root->left;
} else {
root->right = deleteMin(root->right);
root->val = min->val;
}
}
return root;
}
TreeNode* deleteMin(TreeNode* root){
if(root == NULL) return root;
if(root->left == NULL) {
min = root;
return root->right;
}
root->left = deleteMin(root->left);
return root;
}
private:
TreeNode* min;
};
题干中给定一个二叉搜索树(BST)的根节点以及一个给定的值,要求我们删除BST中与该值相等的节点,并且删除节点后,该树仍旧满足二叉搜索树的性质。下面举出一个例子
root = [5,3,6,2,4,null,7] key = 3 5 / \ 3 6 / \ \ 2 4 7 给定的有效值Key为 3,因此我们需要在该BST中删除值为3的节点。 下面是删除节点后所得到的一个有效的BST 5 / \ 4 6 / \ 2 7
二、思路分析
二叉搜索树最大的特点就是左孩子节点的值小于或等于根节点,右孩子节点的值大于或等于根节点,再延伸一点就是左子树的每一个节点值都要小于根节点,而右子树的每一个节点值一定大于根节点。因此在删除原有节点后,树的结构需要作出一些调整后才能继续满足这个性质,这个调整也是这题的难点所在。
那么对于一个节点来说,它的可能情况就是只有左孩子,只有右孩子,左孩子右孩子都有,左孩子右孩子都没有。我们对于删除节点后树的调整也分为这四种情况进行。第一种,当被删除节点只有左孩子节点时,我们只需要将其左孩子节点替换掉该节点即可。当被删除节点只有右孩子节点时,同样的,我们只需要将右孩子节点替换掉该节点即可。当被删除节点既没有左孩子节点也没有右孩子节点时,即为叶节点,直接将该节点变为空值,即ROOT=NULL。当即有左孩子节点又有右孩子节点时,这时的变化较为复杂些,我们选择在被删除节点中找到它右子树中最小的那个节点,该节点一定是处于右子树的叶节点中,我们可以先将该叶节点的值赋予给被删除节点,然后将该叶节点赋予空值,即将该叶节点去替换掉被删除节点。
通过以上的思路,我们可以顺利删除节点使得BST仍然成立。只是在第四种情况下,还需要去寻找出右子树中的最小值节点。通过BST的规律我们可知,右子树的最小节点一定是该子树中最左边的那个叶节点,我们只需不断递归找出该子树中最左边那个叶节点即可。
三、C++代码实现
class Solution {
public:
TreeNode* deleteNode(TreeNode* root, int key) {
if(root == NULL) return NULL;
if(root->val > key) {
root->left = deleteNode(root->left,key);
} else if(root->val < key) {
root->right = deleteNode(root->right,key);
} else {
if(root->left == NULL) {
root = root->right;
} else if(root->right == NULL) {
root = root->left;
} else {
root->right = deleteMin(root->right);
root->val = min->val;
}
}
return root;
}
TreeNode* deleteMin(TreeNode* root){
if(root == NULL) return root;
if(root->left == NULL) {
min = root;
return root->right;
}
root->left = deleteMin(root->left);
return root;
}
private:
TreeNode* min;
};
相关文章推荐
- [LeetCode] Delete Node in a BST 删除二叉搜索树中的节点
- LeetCode 450 Delete Node in a BST(删除BST节点)
- LeetCode.450 Delete Node in a BST(经典删除二叉树某个节点,必备题)
- 【二叉搜索树:删除指定结点】leetcode 450. Delete Node in a BST
- [LeetCode] Delete Node in a Linked List 删除链表的节点
- [CareerCup] 4.6 Find Next Node in a BST 寻找二叉搜索树中下一个节点
- LeetCode 237. Delete Node in a Linked List - 删除链表中的一个节点
- Delete Node in a Linked List(删除链表中的节点)
- leetcode237---Delete Node in a Linked List(删除指定节点)
- [CareerCup] 2.3 Delete Node in a Linked List 删除链表的节点
- Delete Node in a Linked List 删除链表的一个节点
- [LeetCode-237] Delete Node in a Linked List(删除链表中节点)
- LeetCode 237. Delete Node in a Linked List(删除链表中的一个节点)
- LintCode Delete Node in the Middle of Singly Linked List 在O(1)时间复杂度删除链表节点
- LeetCode237_Delete Node in a Linked List(删除链表中的节点) Java题解
- LeetCode OJ:Delete Node in a Linked List(链表节点删除)
- [LeetCode]79. Delete Node in a Linked List删除链表节点
- 372. 在O(1)时间复杂度删除链表节点 (delete-node-in-the-middle-of-singly-linked-list)(c++)----lintcode面试题之链表
- [LeetCode] 237. Delete Node in a Linked List 删除链表的节点
- Delete Node in a Linked List 删除链表的节点