「学习笔记」对顶堆

介绍#

对顶堆是由两个堆来维护的数据结构,两个堆一个是较大数的小根堆,一个是较小数的大根堆,可以动态维护第 K 大的值

原理#

在对顶堆中,要保证小根堆的所有数始终比大根堆大,两个队中的元素进行转移时,将堆顶插入到另一个堆中,将堆顶弹出。
可以用元素转移来维护堆内的元素个数

代码#

定义

priority_queue<ll> q1;
priority_queue<ll, vector<ll>, greater<ll> > q2;

转移

q2.push(q1.top());
q1.pop();

或者是

q1.push(q2.top());
q2.pop();

来道例题
P1168中位数
是一道很简单也很基础的对顶堆 虽然用 vector 可以简洁清晰的水过吧
代码:

#include <iostream>
#include <cstdio>
#include <queue>
#include <vector>
typedef long long ll;
using namespace std;
int n;
priority_queue<ll> q1;
priority_queue<ll, vector<ll>, greater<ll> > q2;

inline ll read() {
	ll x = 0;
	int fg = 0;
	char ch = getchar();
	while(ch < '0' || ch > '9') {
		fg |= (ch == '-');
		ch = getchar();
	}
	while(ch >= '0' && ch <= '9') {
		x = (x << 3) + (x << 1) + (ch ^ 48);
		ch = getchar();
	}
	return fg ? ~x + 1 : x;
}

int main() {
	n = read();
	q1.push(read());
	printf("%lld\n", q1.top());
	for(int i = 2; i <= n; ++i) {
		ll val = read();
		if(val > q1.top())	q2.push(val);
		else	q1.push(val);
		int siz1 = q1.size(), siz2 = q2.size();
		while(abs(siz1 - siz2) > 1) {
			if(q1.size() > q2.size()) {
				q2.push(q1.top());
				q1.pop();
			}
			else {
				q1.push(q2.top());
				q2.pop();
			}
			siz1 = q1.size(), siz2 = q2.size();
		}
		if(i & 1) printf("%lld\n", siz1 > siz2 ? q1.top() : q2.top());
	}
	return 0;
}

作者:yifan0305

出处:https://www.cnblogs.com/yifan0305/p/16560845.html

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

转载时还请标明出处哟!

posted @   yi_fan0305  阅读(93)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
more_horiz
keyboard_arrow_up light_mode palette
选择主题
menu
点击右上角即可分享
微信分享提示