对顶堆 随笔
程序员文章站
2024-02-14 10:12:22
...
对顶推用二个堆实现,能够在nlog(n)的时间复杂度内找出,数组中第 K 小的元素。
把堆中的大根堆想成一个上宽下窄的三角形,把小根堆想成一个上窄下宽的三角形,那么对顶堆就可以具体地被想象成一个“陀螺”或者一个“沙漏”,通过这两个堆的上下组合,我们可以把一组数据分别加入到对顶堆中的大根堆和小根堆,以维护我们不同的需要。
priority_queue<int,vector<int>, less<int>> up; //大根堆
priority_queue<int, vector<int>, greater<int> > down;//小顶推
我们需要维护这两个堆, 大根堆的堆顶元素 < 小根堆的堆顶元素,这样大根堆所有元素都小于小根堆的堆顶元素,另外我们维护小根堆的元素数量一定为K个, 那么 K的位置:
POJ 3784:
寻找中位数
#include <algorithm>
#include <iostream>
#include <queue>
using namespace std;
int main() {
int P;
cin >> P;
while (P--) {
int n, m,val;
cin >> n >> m;
cout << n << " " << (m + 1) / 2 << "\n";
priority_queue<int, vector<int>, less<int> > up; //大根堆
priority_queue<int, vector<int>, greater<int> > down;//小根推
int cnt = 0;
for (int i = 1; i <= m; i++) {
cin >> val;
if (down.empty() || val > down.top()) down.push(val);
else up.push(val);
if (down.size() - 1 > up.size()) up.push(down.top()), down.pop();
if (up.size() > down.size()) down.push(up.top()), up.pop();
if (i % 2) {
cnt++;
cout << down.top() << " ";
if (cnt % 10 == 0) cout << "\n";
}
}
if (cnt % 10 ) cout << endl;
}
}
推荐阅读
-
黑盒子--------------------------------思维(对顶堆)
-
对顶堆 随笔
-
Binary Tree Traversals(ACM训练 - 对顶堆学习笔记)
-
动态中位数(对顶堆)
-
动态中位数-----------------------------------对顶堆
-
C++实现最小堆及插入,调整顺序,删除堆顶元素的操作
-
JAVA 堆的使用 (大顶堆,小顶堆)即优先队列 再TopK 和求中位数中用此种数据结构
-
(leetcode 295)数据流的中位数(暴力、二分、小顶堆以及进阶)
-
在Ubuntu下对c语言全局变量、局部变量、堆、栈等详解
-
Java 堆排序实例(大顶堆、小顶堆)