用一个 maxheap 和一个minHeap 来找中值。
默认 maxheap.size()>= minHeap.size() 所以每次读出应该是从maxheap 中,或者是两者的中值。
maxHeap = new PriorityQueue<Integer>(20, revCmp);
minHeap = new PriorityQueue<Integer>(20);
addNumber(6); max [] min [6]
addNumber(4); 4 6
addNumber(3); 4,3 6
addNumber(10); 4,3 6,10
addNumber(12); 6,4,3 10,12
System.out.println(minHeap);
System.out.println(maxHeap);
System.out.println(getMedian());
addNumber(5); 5,4,3 6,10,12
System.out.println(minHeap);
System.out.println(maxHeap);
System.out.println(getMedian());
addNumber(7); 6, 5,3,4 7,10,12
addNumber(8);
System.out.println(minHeap);
System.out.println(maxHeap);
System.out.println(getMedian());
input value
1: if maxHeap.size()==minHeap.size()
比小得一堆 大。于是需要从大的一堆中 调一个到小的里面
a: if minHeap.peak()!=null && value > maxHeap.peek()
maxHeap.offer(minHeap.poll())
minHeap.offer(value)
b: else
maxHeap.offer(value)
2:
a: value<maxHeap.peek()
比小的一堆最大的小,于是要从小的一堆中放一个到大的一堆中去:
minHeap.offer(maxHeap.poll())
maxHeap.offer(value)
b:
minHeap.offer(value) 直接放到大的一堆中去
实现:
private static void addNumber(int value) {
if(maxHeap.size() == minHeap.size()){
if(minHeap.peek() != null && value > minHeap.peek()){
maxHeap.offer(minHeap.poll());
minHeap.offer(value);
}
else{
maxHeap.offer(value);
}
}
else{
if(value < maxHeap.peek()){
minHeap.offer(maxHeap.poll());
maxHeap.offer(value);
}
else{
minHeap.offer(value);
}
}
}
/*
* If maxHeap and minHeap are of different sizes,
* then maxHeap must have one extra element.
*/
private static double getMedian() {
if(maxHeap.isEmpty())
return 0;
if(maxHeap.size() == minHeap.size()){
return ((double)maxHeap.peek() + (double)minHeap.peek()) / 2;
}
else
return maxHeap.peek();
}