📅  最后修改于: 2023-12-03 15:28:39.186000             🧑  作者: Mango
这是GATE CS 2021设置2中的第9个问题。该问题主要涉及Hashing,要求我们设计一个数据结构,支持插入,删除和最小价值查询操作。
我们可以使用散列表和堆来设计该数据结构。具体来说,我们维护一个散列表,用于维护元素的值和堆中相应节点之间的映射关系。散列表的值是由键值和一个指向最小堆节点的指针组成的。在最小堆中,我们维护元素值的小根堆,并在节点叶子节点中存储指向散列表中相应元素的指针。这个堆中的元素是从散列表中的键值中提取的。
当我们需要插入元素时,我们首先将元素添加到堆中,并用散列表中的键值和一个指向叶子节点的指针更新对应记录。然后我们重新组织堆,以确保其仍是小根堆。
当我们需要删除元素时,我们首先从散列表中获取元素的指针,并将其与堆中的叶子节点交换。然后我们从堆中删除该节点,并将相应的散列表条目设置为NULL。
当我们需要查询最小元素时,我们可以直接从堆的根节点提取元素值。
插入操作需要O(log n)的时间,其中n是元素的数量。删除元素也需要O(log n)的时间。查询最小元素可以在O(1)时间内完成。
#include<bits/stdc++.h>
using namespace std;
struct Node {
int val;
Node* left;
Node* right;
Node(int v) : val(v), left(nullptr), right(nullptr) {}
};
class HashedHeap {
public:
HashedHeap() {
table.resize(1000);
heap.push_back(nullptr);
}
void insert(int val) {
Node* node = new Node(val);
heap.push_back(node);
int idx = heap.size() - 1;
table[val] = make_pair(idx, node);
int i = idx;
while (i > 1 && heap[i]->val < heap[i / 2]->val) {
swap(heap[i], heap[i / 2]);
table[heap[i]->val].first = i;
table[heap[i / 2]->val].first = i / 2;
i /= 2;
}
}
void remove(int val) {
auto entry = table[val];
int idx = entry.first;
heap[idx] = nullptr;
table[val] = make_pair(-1, nullptr);
while (idx > 1 && heap[idx]->val < heap[idx / 2]->val) {
swap(heap[idx], heap[idx / 2]);
table[heap[idx]->val].first = idx;
table[heap[idx / 2]->val].first = idx / 2;
idx /= 2;
}
if (heap[idx] != nullptr) {
while (idx * 2 < heap.size()) {
int j = idx * 2;
if (j + 1 < heap.size() && heap[j + 1]->val < heap[j]->val) {
j++;
}
if (heap[idx]->val > heap[j]->val) {
swap(heap[idx], heap[j]);
table[heap[idx]->val].first = idx;
table[heap[j]->val].first = j;
}
idx = j;
}
}
}
int getMin() {
if (heap.size() <= 1 || heap[1] == nullptr) {
return -1;
}
return heap[1]->val;
}
private:
vector<pair<int, Node*>> table;
vector<Node*> heap;
};
以上是部分C++代码,供作参考。