求两个有序数组的中位数

package kpp.base;
/**
 * 求两个有序数组的中位数
 * 此代码适用于两个数组长度不等的情况:长度不等的情况下,两个数组分别从相反方向去掉元素,且去掉的元素个数相同
 * @author kpp
 *
 */
public class TwoArrayMedian {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        float a[] = {1,2,3,4};
        //float b[] = {2,3,4,5,8,9,10};
        float b[] = {8,9,10,11};
        System.out.println("中位数"+getTwoArrayMedian(a,b));
    }
    /**
     * 获取两个有序数组的中位数
     * @param a
     * @param b
     * @return
     */
    private static float getTwoArrayMedian(float a[],float b[]){
        int aLen = a.length;
        int bLen = b.length;
        //判断哪个数组长度短
        float shorterArray[] = aLen <= bLen? a:b;
        float longerArray[] = aLen > bLen? a:b;
        
        //以长度短的数组shorterArray为基准,shorterArray去掉几个元素,longerArray同时在反方向去掉相同个数元素
        while(shorterArray.length > 1 && longerArray.length > 1){
            //如果短数组的中位数>长数组的中位数,则两个数组的中位数是在短数组的前半部分和长数组的后半部分
            //留下短数组的0至n/2元素,去掉其他元素
            //长数组去掉相同个数元素
            if(getArrayMedian(shorterArray) > getArrayMedian(longerArray)){
                float temp1[] = new float[shorterArray.length/2+1];
                System.arraycopy(shorterArray, 0, temp1, 0, shorterArray.length/2+1);
                
                int delCount = shorterArray.length-shorterArray.length/2-1;
                float temp2[] = new float[longerArray.length-delCount];
                System.arraycopy(longerArray, delCount-1, temp2, 0,longerArray.length-delCount);
                
                shorterArray = temp1;
                longerArray = temp2;
            }
            //如果短数组的中位数<长数组的中位数,则两个数组的中位数是在短数组的后半部分和长数组的前半部分
            //留下短数组的n/2至n-1元素,去掉其他元素
            //长数组去掉相同个数元素
            else if(getArrayMedian(shorterArray) < getArrayMedian(longerArray)){
                float temp1[] = new float[shorterArray.length-shorterArray.length/2];
                System.arraycopy(shorterArray, shorterArray.length/2, temp1, 0, shorterArray.length-shorterArray.length/2);
                
                int delCount = shorterArray.length/2;
                float temp2[] = new float[longerArray.length-delCount];
                System.arraycopy(longerArray, 0, temp2, 0,longerArray.length-delCount);
                
                shorterArray = temp1;
                longerArray = temp2;
            }
            //如果短数组的中位数=长数组的中位数,则两个数组的中位数就是该中位数
            else{
                return getArrayMedian(shorterArray);
            }
            
        }
        
        //如果长度短的数组中只剩余一个元素,而长度长的数组还有多个元素,则将该元素插入到长数组中进行插入排序
        //中位数为排好序后的数组的中位数
        if(longerArray.length > 1){
            float key = shorterArray[0];
            float rsArray[] = new float[longerArray.length+1];
            System.arraycopy(longerArray, 0, rsArray, 0,longerArray.length);
            rsArray[rsArray.length-1] = key;
            
            if(key < rsArray[rsArray.length-2]){
                float temp = key;
                
                int j = 0;
                for( j = rsArray.length-2;j >=0&&temp < rsArray[j];j--);
                //统一向右移动
                for(int k = rsArray.length-2;k >= j+1;k--){
                    rsArray[k+1]=rsArray[k];
                }
                //插入正确位置
                rsArray[j+1] = temp;
            }
            
            for(int i = 0;i < rsArray.length;i++){
                System.out.print(rsArray[i]+" ");
            }
            
            
            return getArrayMedian(rsArray);
        }
        //如果两个数组各剩1个元素,则取二者平均
        else{
            return (shorterArray[0]+longerArray[0])/2;
        }
        
        
    }
    /**
     * 求一个数组的中位数
     * @param data
     * @return
     */
    private static float getArrayMedian(float data[]){
        int len = data.length;
        int mid = len/2;
        if(len%2 == 0){
            return (data[mid]+data[mid-1])/2;
        }else{
            return data[mid];
        }
    }
    

}

 

posted @ 2015-03-31 22:49  kpp  阅读(340)  评论(0编辑  收藏  举报