最大堆和最小堆找中位数
2013-08-27 20:54
447 查看
利用Java的PriorityQueue: PriorityQueue实际上是一个基于优先级的最大堆。
思路:
建立两个堆,一个最大堆和一个最小堆,始终保持两个堆的数据相等或者最大堆的数据比最小堆的数据多一个,则中位数为最大堆的根节点或者是两个堆根节点的平均值;
具体实现:
如果两个堆大小相等,往最大堆插入一个合适的数;
如果两个堆大小不相等,往最小堆插入一个合适的数;
Java code
思路:
建立两个堆,一个最大堆和一个最小堆,始终保持两个堆的数据相等或者最大堆的数据比最小堆的数据多一个,则中位数为最大堆的根节点或者是两个堆根节点的平均值;
具体实现:
如果两个堆大小相等,往最大堆插入一个合适的数;
如果两个堆大小不相等,往最小堆插入一个合适的数;
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; */
相关文章推荐
- 百练+priority_queue应用+最大堆最小堆找出中位数
- Java实现用最大堆和最小堆查找中位数 Find median with min heap and max heap in Java
- Google 面试题:Java实现用最大堆和最小堆查找中位数 Find median with min heap and max heap in Java
- Algorithm_最大堆最小堆来求中位数
- [编程之美]使用最大堆和最小堆来求中位数
- 求中位数问题:最小堆,最大堆
- 最大堆和最小堆求数据流中的中位数【java实现】
- 使用最大堆和最小堆实现中位数的查找
- 用最大堆和最小堆实现中位数查找
- 堆排序 最大堆 最小堆 Java实现
- Java实现堆,最大堆,最小堆,左高树,左低树
- 三 概要模式 1)数值概要 (单词计数\记录计数\最大值/最小值/计数\平均值、中位数、标准差)
- 最大堆,最小堆插入/删除以及最大堆的排序
- 【数据结构】通用的最小堆(最大堆)D-ary Heap
- python 实现求和、计数、最大最小值、平均值、中位数、标准偏差、百分比。
- symbian中如何指定最大和最小堆和栈内存
- 堆排序:最大堆与最小堆
- 最大堆、最小堆、堆排序
- 最大最小堆
- 最大堆/最小堆、siftup和siftdown