PTA基础编程题目集-6-11 求自定类型元素序列的中位数

本文介绍了一种使用快排思想优化的算法,用于计算自定义类型ElementType的数组A[]的中位数,通过partition函数调整元素并找到第(N+1)/2位置的元素。作者对偶数元素个数和中位数定义的理解偏差被修正,以解决超时问题。
摘要由CSDN通过智能技术生成

本题要求实现一个函数,求N个集合元素A[]的中位数,即序列中第⌊(N+1)/2⌋大的元素。其中集合元素的类型为自定义的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;
}

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

输入样例:

3
12.3 34 -5

输出样例:

12.30

代码长度限制 16 KB
时间限制 400 ms
内存限制 64 MB

题解

基于快排思想,前面一直在“偶数个”以及“超过10,中位数是第1个”卡了很久,搞半天题目写着第【(N+1)/2向下取整】大的元素,而我一直从小到大排序的。然后针对超时被卡,至于要将排序全部数字改为每次只排可能存在中位数的一部分即可。
以下是我自己写的,好像和快排不太一样,直接在partition里递归了,不过能通过。

int partition( ElementType A[],int start,int end,int N){
    //printf("partition%d~%d\n",start,end);
    if(start>=end) return start;
    int x=start,y=end;
    ElementType stand=A[start];
    //printf("stand=%f\n",stand);
    while(x<y){
        while(x<y && A[y]<stand){y--;}
        A[x]=A[y];//printf("change%fand%f\n",A[x],A[y]);
        while(x<y && A[x]>=stand){x++;}
        A[y]=A[x];//printf("change%fand%f\n",A[y],A[x]);
    }
    A[x]=stand;
    if(x==((N+1)/2-1)) return x;
    else if(x>(N+1)/2-1)partition(A,start,x-1,N);
    else partition(A,x+1,end,N);
}
ElementType Median( ElementType A[], int N ){
    int x=partition(A,0,N-1,N);
    /* for(int i=0;i<N;i++){
        printf("%.2f ",A[i]);
    }
    printf("\n"); */
    x=(N+1)/2-1;
    return A[x];
}

以下是chatGPT改后

int partition(ElementType A[], int low, int high, int medianPos) {
    ElementType pivot = A[low];
    int start = low, end = high;
    while (start < end) {
        while (start < end && A[end] <= pivot) end--;
        A[start] = A[end];
        while (start < end && A[start] >= pivot) start++;
        A[end] = A[start];
    }
    A[start] = pivot;
    return start;
}

ElementType Median(ElementType A[], int N) {
    int low = 0, high = N - 1, medianPos = (N - 1) / 2;
    int pos = -1;
    while (pos != medianPos) {
        pos = partition(A, low, high, medianPos);
        if (pos < medianPos) low = pos + 1;
        else if (pos > medianPos) high = pos - 1;
    }
    return A[medianPos];
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值