最大堆和最小堆找中位数

来源:互联网 发布:为什么淘宝登陆不上去 编辑:程序博客网 时间:2024/04/27 21:22

利用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 1000int 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]){//importantmaxHeap[parent] = maxHeap[child];parent = child;child = 2 * parent + 1;}elsebreak;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 valuewhile (child != 0 && value > maxHeap[parent]){//carefully, there is a promotionmaxHeap[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]){//importantminHeap[parent] = minHeap[child];parent = child;child = 2 * parent + 1;}elsebreak;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 valuewhile (child != 0 && value < minHeap[parent]){//carefully, there is a promotionminHeap[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]);elseaddMaxHeap(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]);elseprintf("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;*/

原创粉丝点击