您的位置:首页 > 其它

4-11 求自定类型元素序列的中位数*

2017-03-17 21:44 567 查看
本题要求实现一个函数,求
N
个集合元素
A[]
的中位数,即序列中第\lfloor
N/2 +1\rfloor⌊N/2+1⌋大的元素。其中集合元素的类型为自定义的
ElementType


函数接口定义:

ElementType Median( ElementType A[], int N );


其中给定集合元素存放在数组
A[]
中,正整数
N
是数组元素个数。该函数须返回
N
A[]
元素的中位数,其值也必须是
ElementType
类型。


裁判测试程序样例:

#include <stdio.h>

#define MAXN 10
typedef float ElementType;

ElementType Median( ElementType A[], int N );
int main ()
{
ElementType A[MAXN];
int N, i;

scanf("%d", &N);
for ( i=0; i<N; i++ )
scanf("%f", &A[i]);
printf("%.2f\n", Median(A, N));

return 0;
}

/* 你的代码将被嵌在这里 */


以上是题目,基本方法是用冒泡排序法:

ElementType Median(ElementType A[], int N)

{
if (N == 1)return A[0];
if (N == 2)
{
if (A[0]>A[1])return A[1];
else return A[0];
}
if (N>2 && N <= 10000)
{
int totalcount = 0;
if (N % 2 == 0)
totalcount = N / 2;
else totalcount = N / 2 + 1;
float t = 0;
float thenumber = 0;
for (int j = 0; j<totalcount; j++)
{
for (int i = 0; i<N - 1 - j; i++)
{
if (A[i]>A[i + 1])
{
t = A[i + 1];
A[i + 1] = A[i];
A[i] = t;
}
}
}
return A[N - totalcount];
}

}

该法比全排速度快只需要排出最大到第N(中位数的序号)大的数,即可终止。但对于数量较多(大概10000及以上个数)排列就会超时了。
故参照网上的解法,如下:
void Swap(ElementType *a, ElementType *b){

    ElementType temp = *a;

    *a = *b;

    *b = temp;

}

ElementType Medians(ElementType A[], int Left, int Right){

    int Center = (Left + Right) / 2;

    if(A[Left]>A[Center])

        Swap( &A[Left], &A[Center] );

    if(A[Left]>A[Right])

        Swap( &A[Left], &A[Right] );

    if(A[Center]>A[Right])

        Swap( &A[Center], &A[Right] );

    Swap( &A[Center], &A[Right-1] );

    return A[Right-1];

}

void QSort(ElementType A[], int Left, int Right){

    if(Left>=Right) return;

    ElementType Pivot = Medians(A, Left, Right);

    int i = Left, j = Right - 1;

    while(1){

        while( A[++i] < Pivot ) { }

        while( A[--j] > Pivot) { }

        if( i<j ) 

            Swap(&A[i], &A[j]);

        else break;

    }

    Swap(&A[i], &A[Right-1]);   

    QSort(A, Left, i-1);

    QSort(A, i+1, Right);

}

ElementType Median( ElementType A[], int N ){

    QSort(A, 0, N-1);

    ElementType p,x;

    if(N%2==0){

        x = A[N/2]+A[N/2+1];

        p = x/2;

    }else{

        p = A[(N+1)/2];

    }

    return p;

}

对以上算法进行改进:

void searchmin(ElementType A[], int left, int right, ElementType *finalelement)
{
ElementType tmp = A[left];
for (int i = left; i <= right; i++)
{
if (A[i] <= tmp)tmp = A[i];
}
*finalelement = tmp;
}
void searchmax(ElementType A[], int left, int right, ElementType *finalelement)
{
ElementType tmp = A[left];
for (int i = left; i <= right; i++)
{
if (A[i] >= tmp)tmp = A[i];
}
*finalelement = tmp;
}
void swap(ElementType *a, ElementType *b)
{
ElementType c = 0;
c = *a;
*a = *b;
*b = c;
}

ElementType changeposition(ElementType A[], int left, int right)
{
int center = (l
cd71
eft + right) / 2;
if (A[left] > A[center])swap(&A[left], &A[center]);
if (A[left]>A[right])swap(&A[left], &A[right]);
if (A[center]>A[right])swap(&A[right], &A[center]);
swap(&A[center], &A[right - 1]);
return A[right - 1];
}
void algorithem(ElementType A[], int left, int right, int totalcount, ElementType *finalelement)
{

//核心部分

//解析:对于区间为包含序号为totalcount(即为中位数的序号),只需算出

//最大或最小值,而对于不含totalcount的区间,直接舍去,无需排序,故

//比原法节省时间
if (left == totalcount){ searchmin(A,left,right,finalelement); return; }
if (right == totalcount){ searchmax(A, left, right, finalelement);  return; }
if (right < totalcount)return;
if (left>totalcount)return;
ElementType cmppos = changeposition(A,left,right);
int i = left, j = right - 1;
while (1)
{
while (A[++i] < cmppos){}
while (A[--j]>cmppos){}
if (i < j)
{
changeposition(A,i,j);
}
else break;
}

swap(&A[i], &A[right - 1]);
if (i == totalcount){ *finalelement = A[i]; return; }
algorithem(A, left, i - 1, totalcount,finalelement);
algorithem(A, i + 1, right, totalcount, finalelement);

}
ElementType Median(ElementType A[], int N)
{
ElementType t = 0;
if (N == 1)return A[0];
if (N == 2)
{
if (A[0]>A[1])return A[1];
else return A[0];
}
if (N>2)
{
int totalcount = 0;
if (N % 2 == 0)
totalcount = N / 2;
else totalcount = N/2+1 ;
totalcount = N - totalcount;
algorithem(A, 0, N - 1,totalcount, &t);
return t;
}

}

改进的方法比原法快2-4ms(为测试用例给出的用时),但各算法的时间复杂度待确定。

——————————————————————————————————————————————————————
20170516   本题核心即为快速排序

参见博客:http://blog.csdn.net/wxf2012301351/article/details/72240440
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  C