求自定义类型序列中的中位数

来源:互联网 发布:淘宝双皇冠店铺多少钱 编辑:程序博客网 时间:2024/06/08 16:59

题目要求是:pta测试基础题4-11
本题要求实现一个函数,求N个集合元素A[]的中位数,即序列中第[N/2+1]大的元素。其中集合元素的类型为自定义的ElementType。
我这儿有个疑问,这儿如果N为 偶数,那么中位数是哪一个?因为后面提交之后没有错误提示,我多次尝试提交,正确之后,发现这儿的中位数是,从小到大排列,第[N/2+1]个元素
我本来的代码是直接利用选择排序,之后直接选出中位数:

ElementType Median( ElementType A[], int N ){    int min,i,j;    ElementType temp;    for( i=0; i<N-1; i++){        min = i;        for(j=i+1; j<N; j++){            if(A[min] > A[j])   min = j;        }        temp = A[i];        A[i] = A[min];        A[min] = temp;    }    return A[N/2];}

但是运行之后是部分正确,我想可能是超时,所以在琢磨更快的方法求出中位数。
我们可以运用“快速排序”的思想,却又不需要排序,求中位数是求第K大数的特殊情况。这儿的具体方法就是利用一个数作为基准,将数组中的元素分解为两个集合,然后根据集合中元素的个数来判断中位数处于哪个集合中,然后继续从这个集合中找。本质上是一种分而治之的思想。
算法伪代码如下:

ElementType FindKth(ElementType S[], int K){    选取S中的第一个元素e;    根据e将集合S(不包含e)分解为小于e的集合S1和大于等于e的元素集合S2;        if(|S1| >= K)         return FindKth(S1,K);        else if(|S1|+1 == K)   return e;        else return FindKth(S2,K - |S1| - 1);}

我的最终代码如下:

ElementType FindKth( ElementType A[], int K ,int N){    ElementType e = A[0];    ElementType B[MAXN],C[MAXN];    int lenB=0,lenC=0,i;    for(i=1; i<N; i++){        if(A[i] < e){            B[lenB++] = A[i];        }else{            C[lenC++] = A[i];        }    }    if(lenB >= K)  return FindKth(B,K,lenB);    else if(lenB+1 == K)    return e;    else return FindKth(C,K-lenB-1,lenC);}ElementType Median( ElementType A[], int N ){    return FindKth(A,N/2+1,N);}

提交之后正确。

0 0
原创粉丝点击