求数据流中的中位数

如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。

思路:可以建立一个大堆maxHeap用来保存较小n/2的数,一个小堆minHeap用来保存Math.ceil(n/2)个数。

1.开始时,maxHeap和minHeap都为空,即大小都为0,则将第一个数保存到minHeap中。

2.后面的待插入的数,首先比较maxHeap和minHeap的元素个数的大小,相等则应该存储到小堆minHeap中,否则保存到元素个数小的那个。

3.假设要保存到大堆中,则这个数num应该要比minHeap的堆顶元素小或者相等,假若大于minHeap的堆顶元素,则应将minHeap的堆顶元素与num互换,重建minHeap,并将此时的num插入到大堆maxHeap,重建maxHeap;

4.假设要保存到小堆中,过程与步骤3类似。

5.获取中位数,若maxHeap和minHeap的元素个数相等,则为其两个堆顶元素的平均值,否则为minHeap堆顶元素的值。


java实现代码如下:

import java.util.*;
public class MedianNumber {
	public int maxHeapSize=0;
    public int minHeapSize=0;
    public ArrayList maxHeap=new ArrayList();
    public ArrayList minHeap=new ArrayList();
    
    // fg=0 表示 大根堆
    public void buildHead(ArrayList list,int length,int fg){
        
        for(int i=(length-2)/2;i>=0;i-- ){
            int k=i;
            while(2*k+1<=length-1){
                int bigIndex=2*k+1;
                if(bigIndexlist.get(bigIndex+1)){
                        	bigIndex++;
                    	}
                    }
                    
                }
                if(fg==0){
                    if(list.get(k)list.get(bigIndex)){
                    	 int temp1=list.get(k);
                         int temp2=list.get(bigIndex);
                         list.remove(k);
                         list.add(k, temp2);
                         list.remove(bigIndex);
                         list.add(bigIndex, temp1);
                         k=bigIndex;
                    }else{
                        break;
                    }
                }
                
            }           
        }
    }
    
    public void Insert(Integer num) {
    	if(minHeapSize==0){
    		minHeap.add(num);
    		minHeapSize++;
    		return;
    	}
 	
        if(maxHeapSize list){
    	System.out.print("[");
    	for(int i=0;i


你可能感兴趣的:(基本算法)