问题描述
本题是一道堆排序模板题。
你需要构建一个堆,可以实现如下操作:
push
:将一个正整数 xx 插入堆中。remove
:删除堆顶元素。若此时堆为空,则输出empty
。min
:输出堆中最小的元素。若此时堆为空,则输出empty
。print
:给定一个小于等于当前堆中元素的数字 kk,你需要在一行内输出当前堆中最小的 kk 个元素,并将其全部删除,数据保证该操作不会在堆为空时出现。
输入格式
第一行输入一个整数 nn,表示操作的数量。
接下来 nn 行,每行一个字符串,表示具体的操作。
输出格式
对于 remove
,min
,print
操作,按照题目要求进行输出。
样例输入
8
push 4
min
remove
remove
push 3
push 7
push 2
print 2
样例输出
4
empty
2 3
代码如下
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
int main() {
int n;
cin >> n;
//使用最小堆,优先队列默认是最大堆,需要使用 greater<int> 来实现最小堆
priority_queue<int, vector<int>, greater<int>> minHeap;
while (n--) {
string command;
cin >> command;
if (command == "push") {
int x;
cin >> x;
minHeap.push(x);
}
else if (command == "remove") {
if (minHeap.empty()) {
cout << "empty" << endl;
} else {
minHeap.pop();
}
}
else if (command == "min") {
if (minHeap.empty()) {
cout << "empty" << endl;
} else {
cout << minHeap.top() << endl;
}
}
else if (command == "print") {
int k;
cin >> k;
vector<int> toPrint;
//将堆中的前 k 个元素提取出来并输出
for (int i = 0; i < k; ++i) {
if (minHeap.empty()) break;
toPrint.push_back(minHeap.top());
minHeap.pop();
}
//输出堆中最小的 k 个元素
for (int i = 0; i < toPrint.size(); ++i) {
cout << toPrint[i] << " ";
}
cout << endl;
}
}
return 0;
}
操作过程详解
第 1 行:push 4
执行了 push
操作,将 4
插入到堆中。
插入后堆中的内容是 [4]
。
第 2 行:min
执行了 min
操作,输出当前堆的最小值。
当前堆中只有一个元素 4
,所以堆顶元素即最小值是 4
。
输出结果是 4
。
第 3 行:remove
执行了 remove
操作,删除堆顶元素。
当前堆中只有一个元素 4
,删除后堆变空。
输出结果是 empty
,因为堆空了。
第 4 行:remove
执行了 remove
操作,删除堆顶元素。
此时堆已经空了,所以执行删除操作时输出 empty
。
第 5 行:push 3
执行了 push
操作,将 3
插入到堆中。
插入后堆中的内容是 [3]
。
第 6 行:push 7
执行了 push
操作,将 7
插入到堆中。
插入后堆中的内容是 [3, 7]
。因为堆是最小堆,3
仍然是堆顶元素。
第 7 行:push 2
执行了 push
操作,将 2
插入到堆中。
插入后堆中的内容是 [2, 7, 3]
。插入 2
后,它成为了堆顶元素。
第 8 行:print 2
执行了 print 2
操作,需要输出堆中最小的 2
个元素并将它们删除。
当前堆的元素是 [2, 7, 3]
,其中最小的 2
个元素是 2
和 3
。
提取并删除堆顶元素 2
,然后堆变为 [3, 7]
。
再提取并删除堆顶元素 3
,堆变为 [7]
。
输出结果是 2 3
。