利用Java的PriorityQueue: PriorityQueue实际上是一个基于优先级的最大堆。
思路:
建立两个堆,一个最大堆和一个最小堆,始终保持两个堆的数据相等或者最大堆的数据比最小堆的数据多一个,则中位数为最大堆的根节点或者是两个堆根节点的平均值;
具体实现:
如果两个堆大小相等,往最大堆插入一个合适的数;
如果两个堆大小不相等,往最小堆插入一个合适的数;
Java code
package algorithm;
import java.util.Comparator;
import java.util.PriorityQueue;
public class GetMedian {
PriorityQueue<Integer> maxHeap = new PriorityQueue<Integer>(100,new myComparator());
PriorityQueue<Integer> minHeap = new PriorityQueue<Integer>();
public void addNewNumber(int num)
{
if(minHeap.size() == maxHeap.size())
{
if(!minHeap.isEmpty() && num >= minHeap.peek().intValue())
{
maxHeap.offer(minHeap.poll());
minHeap.offer(new Integer(num));
}
else
{
maxHeap.offer(new Integer(num));
}
}
else
{
if(num >= maxHeap.peek().intValue())
{
minHeap.offer(new Integer(num));
}
else
{
minHeap.offer(maxHeap.poll());
maxHeap.offer(new Integer(num));
}
}
}
public double getMedian(){
if(minHeap.size() == maxHeap.size()){
return (double)(minHeap.peek() + maxHeap.peek()) / 2;
}
else
{
return maxHeap.peek();
}
}
class myComparator implements Comparator<Integer>{
public int compare(Integer object1, Integer object2) {
return object2.intValue() - object1.intValue();
}
}
public static void main(String[] args) {
GetMedian g = new GetMedian();
int a[] = {2,4,6,8,10,5,7,9};
for(int i =0; i < 8; i++){
g.addNewNumber(a[i]);
System.out.println(g.getMedian());
}
}
}
#include <stdio.h>
#include <iostream>
using namespace std;
#define N 1000
int maxHeap[N + 5];
int minHeap[N + 5];
int maxSize = 0;
int minSize = 0;
int deleteMaxHeap()
{
int parent, child, value, target;
maxSize--;
value = maxHeap[0];
target = maxHeap[maxSize];
maxHeap[0] = maxHeap[maxSize];
parent = 0;
child = 2 * parent + 1;
while(child <= maxSize - 1)
{
if (child + 1 <= maxSize - 1 && maxHeap[child + 1] > maxHeap[child])
child = child + 1;
if (target < maxHeap[child])
{
//important
maxHeap[parent] = maxHeap[child];
parent = child;
child = 2 * parent + 1;
}
else
break;
maxHeap[parent] = target;
}
return value;
}
void addMaxHeap(int value)
{
int child = maxSize;
int parent = (child - 1) / 2;
//if using parent, it won't work, because parent is approximate value
while (child != 0 && value > maxHeap[parent])
{
//carefully, there is a promotion
maxHeap[child] = maxHeap[parent];
child = parent;
parent = (child - 1) / 2;
}
maxHeap[child] = value;
maxSize++;
}
int deleteMinHeap()
{
int parent, child, value, target;
minSize--;
value = minHeap[0];
target = minHeap[minSize];
minHeap[0] = minHeap[minSize];
parent = 0;
child = 2 * parent + 1;
while(child <= minSize - 1)
{
if (child + 1 <= minSize - 1 && minHeap[child + 1] < minHeap[child])
child = child + 1;
if (target > minHeap[child])
{
//important
minHeap[parent] = minHeap[child];
parent = child;
child = 2 * parent + 1;
}
else
break;
minHeap[parent] = target;
}
return value;
}
void addMinHeap(int value)
{
int child = minSize;
int parent = (child - 1) / 2;
//if using parent, it won't work, because parent is approximate value
while (child != 0 && value < minHeap[parent])
{
//carefully, there is a promotion
minHeap[child] = minHeap[parent];
child = parent;
parent = (child - 1) / 2;
}
minHeap[child] = value;
minSize++;
}
int main()
{
int i;
int a[6] = {0, 4, 7, 9, 1, 3};
int moveVal, input, count;
for (i = 1; i <= 5; i++)
{
if (i == 1)
addMaxHeap(a[i]);
else
{
if (a[i] > maxHeap[0])
addMinHeap(a[i]);
else
addMaxHeap(a[i]);
if (maxSize == minSize + 2)
{
moveVal = deleteMaxHeap();
addMinHeap(moveVal);
}
else if (maxSize + 2 == minSize)
{
moveVal = deleteMinHeap();
addMaxHeap(moveVal);
}
}
if (i % 2 == 0)
printf("even, %f\n", (maxHeap[0] + minHeap[0]) / 2.0);
else
{
if (maxSize > minSize)
printf("odd,max, %d\n", maxHeap[0]);
else
printf("odd,min, %d\n", minHeap[0]);
}
}
system("pause");
return 0;
}
/*
int i;
addMinHeap(5);
addMinHeap(3);
addMinHeap(8);
addMinHeap(9);
addMinHeap(11);
for (i = 0; i < 5; i++)
{
cout<<minHeap[i]<<" ";
}
cout<<endl;
for (i = 0; i < 5; i++)
{
cout<<deleteMinHeap()<<" "<<minSize<<endl;
}
cout<<minSize<<endl;
cout<<endl;
*/