📅  最后修改于: 2023-12-03 15:42:21.003000             🧑  作者: Mango
门门 CS 1997问题16是一个蓝题目,考察了代码实现的基本技能和思维能力。题目要求实现一种数据结构,支持以下操作:
本题可以使用平衡树实现,常用的平衡树种类有红黑树和AVL树。它们都能够在O(logn)的时间复杂度内完成以上操作。
我们可以按照以下步骤实现:
struct Node {
int key, height;
Node* left, *right;
Node(int x) : key(x), height(1), left(nullptr), right(nullptr) {}
};
int height(Node* p) {
return p ? p->height : 0;
}
int balanceFactor(Node* p) {
return height(p->right) - height(p->left);
}
void fixHeight(Node* p) {
int hl = height(p->left);
int hr = height(p->right);
p->height = (hl > hr ? hl : hr) + 1;
}
Node* rotateRight(Node* p) {
Node* q = p->left;
p->left = q->right;
q->right = p;
fixHeight(p);
fixHeight(q);
return q;
}
Node* rotateLeft(Node* q) {
Node* p = q->right;
q->right = p->left;
p->left = q;
fixHeight(q);
fixHeight(p);
return p;
}
Node* balance(Node* p) {
fixHeight(p);
if (balanceFactor(p) == 2) {
if (balanceFactor(p->right) < 0)
p->right = rotateRight(p->right);
return rotateLeft(p);
}
if (balanceFactor(p) == -2) {
if (balanceFactor(p->left) > 0)
p->left = rotateLeft(p->left);
return rotateRight(p);
}
return p;
}
Node* insert(Node* root, int key) {
if (!root)
return new Node(key);
if (key < root->key)
root->left = insert(root->left, key);
else
root->right = insert(root->right, key);
return balance(root);
}
Node* findMin(Node* p) {
return p->left ? findMin(p->left) : p;
}
Node* removeMin(Node* p) {
if (p->left == nullptr)
return p->right;
p->left = removeMin(p->left);
return balance(p);
}
Node* remove(Node* root, int key) {
if (!root)
return nullptr;
if (key < root->key)
root->left = remove(root->left, key);
else if (key > root->key)
root->right = remove(root->right, key);
else {
Node* l = root->left;
Node* r = root->right;
delete root;
if (!r) return l;
Node* min = findMin(r);
min->right = removeMin(r);
min->left = l;
return balance(min);
}
return balance(root);
}
Node* search(Node* root, int key) {
if (!root)
return nullptr;
if (root->key == key)
return root;
if (root->key > key)
return search(root->left, key);
else
return search(root->right, key);
}
Node* next(Node* root, int key) {
Node* res = nullptr;
while (root) {
if (root->key > key) {
if (!res || res->key > root->key)
res = root;
root = root->left;
}
else
root = root->right;
}
return res;
}
Node* prev(Node* root, int key) {
Node* res = nullptr;
while (root) {
if (root->key < key) {
if (!res || res->key < root->key)
res = root;
root = root->right;
}
else
root = root->left;
}
return res;
}