题目
题目: https://leetcode.cn/problems/delete-node-in-a-bst/description/
解法
先找到该结点,然后删除,分为两种情况
- 删除结点为叶子结点,直接删除。如果是迭代写法,要记录其父结点,使父结点的左或右指针置空;如果是递归写法,直接删除,然后 return nullptr 就行。
- 删除结点有左或右子树,找到左子树中的最大值,或者右子树中的最小值,赋值给删除节点,然后删除左子树那个最大值结点或者右子树那个最小值结点。
递归写法
class Solution {
public:
TreeNode* deleteNode(TreeNode* root, int key) {
if (!root) {
return nullptr;
}
if (root->val == key) {
TreeNode* left = root->left;
TreeNode* right = root->right;
if (left) {
TreeNode* left_max = left, *parent = root;
while(left_max->right) {
parent = left_max;
left_max = left_max->right;
}
root->val = left_max->val;
if (parent != root) {
parent->right = left_max->left;
} else {
root->left = left_max->left;
}
delete left_max;
} else if (right) {
TreeNode* right_min = right, *parent = root;
while(right_min->left) {
parent = right_min;
right_min = right_min->left;
}
root->val = right_min->val;
if (parent != root) {
parent->left = right_min->right;
} else {
root->right = right_min->right;
}
delete right_min;
}else {
delete root;
root = nullptr;
}
return root;
}
else if (root->val > key) {
// 涉及到树结构改变的,一定要这样写
root->left = deleteNode(root->left, key);
}
else {
// 涉及到树结构改变的,一定要这样写
root->right = deleteNode(root->right, key);
}
return root;
}
};
迭代
class Solution {
public:
TreeNode* deleteNode(TreeNode* root, int key) {
TreeNode* p = root, *pre;
while (p) {
if (p->val == key) {
if (!p->left && !p->right) {
if (pre == p) {
root = nullptr;
} else if (pre->left == p) {
pre->left = nullptr;
} else {
pre->right = nullptr;
}
delete p;
}
else {
if (p->left) {
TreeNode* left = p->left, *f = p;
while (left->right) {
f = left;
left = left->right;
}
p->val = left->val;
if (f->left == left) {
f->left = left->left;
} else {
f->right = left->left;
}
delete left;
} else {
TreeNode* right = p->right, *f = p;
while (right->left) {
f= right;
right = right->left;
}
p->val = right->val;
if (f->left == right) {
f->left = right->right;
} else {
f->right = right->right;
}
delete right;
}
}
break;
}
else if (p->val > key) {
pre = p;
p = p->left;
}
else {
pre = p;
p = p->right;
}
}
return root;
}
};