T60:数据流中的中位数(Java)

题目:如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。我们使用Insert()方法读取数据流,使用GetMedian()方法获取当前读取数据的中位数。

分析:建立2个大根堆,一个max用于存放数据中较小的部分,一个min存放较大的部分。整体思路是最后若max+min的个数为奇数则middle=max.last(用于取出最大的数)。若为偶数,则middle=(max.last+min.first)/2.0(即max的最大数和min的最小数的平均值)。这就是GetMedian()函数。

而insert()函数,是用于存放数据的,该如何有序存放。开始max和min都为空,将一个数存入max.add(num)。再来一个数,则需要放一个数到min中去,直接放?当然不是。需要将num和max.last()比较。若num<max.last(),即第二个数比第一个数小,那么此时应该将num放入max中,然后取出max中最大的数放入Min中。第三个数也如此,总之这三个数有2个是要放在max中。至此就可以归纳出偶数个时,放max中,奇数个数放min中。

import java.util.TreeSet;

/*
 * 如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。
 * 如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。
 * 我们使用Insert()方法读取数据流,使用GetMedian()方法获取当前读取数据的中位数。
 */
public class GetMedian1 {
	TreeSet<Integer> max =new TreeSet<Integer>();
	TreeSet<Integer> min =new TreeSet<Integer>();
	public void Insert(Integer num) {
	    if((max.size()+min.size())%2==0){
	    	if(min.size()>0&&num>min.last()){
	    		min.add(num);
	    		num=min.first();
	    		min.remove(num);
	    	}
	    	max.add(num);
	    }else{
	    	if(max.size()>0&&num<max.first()){
	    		max.add(num);
	    		num=max.last();
	    		max.remove(num);
	    	}
	    	min.add(num);
	    }
    }

    public Double GetMedian() {
    	int size =max.size()+min.size();
    	if(size==0){
    		return 0.0;
    	}
    	if(size%2==0){
    		return  ((max.last()+min.first())/2.0);
    	}else{
    		return (double)max.last();
    	}
		
        
    }
}

参考:https://blog.csdn.net/junjunba2689/article/details/80661948

猜你喜欢

转载自blog.csdn.net/qq_40516725/article/details/85004980