左神基础班- 数据流一直来-判断所有数据的中位数

生成两个堆:大根堆 和小根堆。

第一个数 默认放入大根堆。

然后一直有数进来,按照以下逻辑放入两个堆中:

把进来的数和大根堆的堆顶比较,如果比堆顶小(=),则放进大根堆中。

如果比堆顶大,则放入小根堆。

每次放入都要检查 当前两个堆得 size的绝对值是否小于等于1, 如果大于一,则把size较大的堆弹出一个元素加入到另外一个堆中。

#include<iostream>
#include<queue>
#include<cmath>
using namespace std;
int main(){
	priority_queue<int> s;
	priority_queue<int,vector<int>,greater<int> > big;
	int n;
	int help;
	while(cin >>n && n!= 0){
		if(s.empty()){
			s.push(n);
			cout<<"now ,the medium is: " << s.top()<<endl;
			continue;
		}
		if(n <= s.top()){
			s.push(n);
			if(	s.size() - big.size() > 1){
				help = s.top();
				big.push(help);
				s.pop();
			}
		}else{
			big.push(n);
			if( big.size() - s.size() > 1){
				help = big.top();
				s.push(help);
				big.pop();
			}
		}
		if(s.size() == big.size()){
			cout << "now ,the medium is: " << (s.top() + big.top()) /2.0<<endl;
		}else if(s.size() > big.size()){
			cout << "now ,the medium is: " << s.top() <<endl;
		}else{
			cout << "now ,the medium is: " << big.top()<<endl;
		}
		
	}
	return 0;
}

 

 

为什么要这样做呢?

我们解析一下:

我们每次进来一个数 都要和大根堆的堆顶比较,比他大的放另一个小根堆里,比他小的放大根堆里,

这样的结果是,小根堆里存的都是比大根堆大的值。

 

ok,继续:

当我们连续进来都是比大根堆顶大的值,则数据一直加入小根堆,没几次小根堆的元素个数就超过了大根堆,这是出现问题了啊,生病了啊,得治,医生一看发现 : 哦,你大根堆的堆顶元素选的值太小的,需要更新一个更大的值了, 刚好旁边的小根堆里存的都是比 大根堆的堆顶大的值, 取小根堆的堆顶就更棒了,取所有比它大的值中最小的取更新。

另外啊,还顺便调整了双方堆内元素的个数,不是很棒吗。

 

对于一直进来的都是比大根堆顶小的元素。也是一个意思,说明大根堆的堆顶选的元素太大了,需要换一个更小的,且比他小的都在自己这个堆内,所以把堆顶拿走后,重新得到的堆顶就是比原来刚好小一号的值了,也是很棒的。

 

这样调整的后果:类似于中位数partition,比它小的都在大根堆里,比他大的都在小根堆里。

算中位数还很方便。  

ok 88~~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值