大小顶堆解决数据流中位数问题
相关阐述
- 小顶堆:Java中的PriorityQueue<>()默认为小顶堆实现,即队列的顶部元素为最小值,内部按照升序排好
- 大顶堆:跟小顶堆相反,需要使用PriorityQueue<>((x,y)->(y-x))来实现,队列的顶部元素为最大值,内部按照降序排好
分析
假设存在A为普通的小顶堆,B为实现的大顶堆,那么整个数据流存放在两个堆中的元素顺序应该是:B的队列尾->B的队列头->A的队列头->A的队列尾
所以,当A跟B的元素个数相同或者同为空时,我们需要将元素入B队列,否则,需要将元素入B队列;在每次入队列的时候都需要在插入完数据后将插入的队列的头部出队列放入另一个队列以保持两个队列的元素稳定有序;

代码
Queue<Integer> A, B;
Queue<Integer> A, B;
public MedianFinder() {
A = new PriorityQueue<>(); // 小顶堆,保存较大的一半
B = new PriorityQueue<>((x, y) -> (y - x)); // 大顶堆,保存较小的一半
}
public void addNum(int num) {
if(A.size() != B.size()) {
A.add(num);
B.add(A.poll());
} else {
B.add(num);
A.add(B.poll());
}
}
public double findMedian() {
return A.size() != B.size() ? A.peek() : (A.peek() + B.peek()) / 2.0;
}

浙公网安备 33010602011771号