📅  最后修改于: 2023-12-03 15:12:38.353000             🧑  作者: Mango
这是 2018 年 GATE 计算机科学模拟考试套装 2 的第 58 题。本题考查的是二叉搜索树(BST)的基本操作。
实现一个函数 delete_key
,删除给定二叉搜索树中的一个键。该函数应接受两个参数:一个指向 BST 根节点的指针 root
,以及要删除的键 key
。函数应返回指向修改后 BST 根节点的指针。
函数原型如下:
BSTNode* delete_key(BSTNode* root, int key);
你可以假设在给定的 BST 中仅有一个键与 key
相等。
函数最开始接收的 root
指针指向的 BST 的样本输入数据格式如下(每个节点占据一行):
k1
/k \
k2
/ \
k3 k4
其中每个 k
代表一个整数键,/
和 \
表示指针。
函数返回指向修改后 BST 根节点的指针,输出格式与输入格式相同。
输入:
50
/ \
30 70
/ \
60 80
要删除键 50
。
输出:
60
/ \
30 70
\ \
80
输入:
20
/ \
10 30
/ \
25 35
要删除键 30
。
输出:
20
/ \
10 35
/
25
由于本题考察 BST 的常见操作之一,因此我们需要对 BST 的特点和常见操作有足够的了解。
对于 BST 中的任何节点都满足以下两个条件:
由此可以推出:BST 的中序遍历是有序的。
因此,我们可以考虑分两种情况来处理待删除的键:
min
,将其替换待删除键的位置,然后删除 min
。具体实现细节见代码片段。
struct BSTNode {
int key;
BSTNode *left, *right;
};
BSTNode* delete_key(BSTNode* root, int key) {
if (root == nullptr) {
return nullptr;
}
if (root->key > key) {
root->left = delete_key(root->left, key);
} else if (root->key < key) {
root->right = delete_key(root->right, key);
} else {
if (root->left == nullptr) {
BSTNode* temp = root->right;
delete root;
root = temp;
} else if (root->right == nullptr) {
BSTNode* temp = root->left;
delete root;
root = temp;
} else {
BSTNode* temp = root->right;
while (temp->left != nullptr) {
temp = temp->left;
}
root->key = temp->key;
root->right = delete_key(root->right, temp->key);
}
}
return root;
}
上述代码实现了 delete_key
函数。其时间复杂度为 $O(h)$,其中 $h$ 为树的高度。由于 BST 的性质,$h$ 的最坏情况为 $O(n)$(即树退化为链表),因此该函数最坏情况下的时间复杂度为 $O(n)$。