Cho cây tìm kiếm nhị phân (BST) và khóa k. Xóa khóa k khỏi BST và trả về BST đã cập nhật. Ví dụ: xóa khóa 3 từ cây cho kết quả cây mới.
Giải thuật
- Hàm
deleteRoot(root)xóa nút gốc:- Nếu
root == nulltrả về null. - Nếu không có cây con phải: trả về cây con trái.
- Tìm nút kế thừa inorder
xcủa gốc. - Gán
x->left = root->left. - Trả về
root->right.
- Nếu
- Hàm
deleteNode(root, key):- Nếu
root == nullhoặcroot->val == keytrả vềdeleteRoot(root). curr := root.- Vòng lặp vô tận:
x := curr->val.- Nếu
key < x:- Nếu
curr->left == nullhoặccurr->left->val == key:curr->left = deleteRoot(curr->left), thoát. curr = curr->left.
- Nếu
- Ngược lại:
- Nếu
curr->right == nullhoặccurr->right->val == key:curr->right = deleteRoot(curr->right), thoát. curr = curr->right.
- Nếu
- Trả về
root.
- Nếu
Ví dụ mã C++
#include <bits/stdc++.h>
using namespace std;
class TreeNode {
public:
int val;
TreeNode *left, *right;
TreeNode(int data) { val = data; left = NULL; right = NULL; }
};
class Solution {
public:
TreeNode* deleteNode(TreeNode* root, int key) {
if (!root || root->val == key) return deleteRoot(root);
TreeNode* curr = root;
while (true) {
int x = curr->val;
if (key < x) {
if (!curr->left || curr->left->val == key) {
curr->left = deleteRoot(curr->left);
break;
}
curr = curr->left;
} else {
if (!curr->right || curr->right->val == key) {
curr->right = deleteRoot(curr->right);
break;
}
curr = curr->right;
}
}
return root;
}
TreeNode* deleteRoot(TreeNode* root) {
if (!root) return NULL;
if (!root->right) return root->left;
TreeNode* x = root->right;
while (x->left) x = x->left;
x->left = root->left;
return root->right;
}
};
Đầu vào
[5,3,6,2,4,null,7] 3
Đầu ra
[5, 4, 6, 2, null, 7, ]