最大堆和最小堆找中位数

利用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;
*/


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值