4-11 求自定类型元素序列的中位数*
2017-03-17 21:44
567 查看
本题要求实现一个函数,求
N/2 +1\rfloor⌊N/2+1⌋大的元素。其中集合元素的类型为自定义的
其中给定集合元素存放在数组
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;
}
对以上算法进行改进:
改进的方法比原法快2-4ms(为测试用例给出的用时),但各算法的时间复杂度待确定。
——————————————————————————————————————————————————————
20170516 本题核心即为快速排序
参见博客:http://blog.csdn.net/wxf2012301351/article/details/72240440
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
相关文章推荐
- 4-11 求自定类型元素序列的中位数 (25分)
- pta 6-11 求自定类型元素序列的中位数
- 4-11 求自定类型元素序列的中位数
- 4-11 求自定类型元素序列的中位数 (25分)
- PAT基础题 4-11 求自定类型元素序列的中位数
- PAT-C-4-11 求自定类型元素序列的中位数 (25分)
- 4-11 求自定类型元素序列的中位数
- 6-11 求自定类型元素序列的中位数(25 分)
- 4-11 求自定类型元素序列的中位数
- PTA 6-11 求自定类型元素序列的中位数
- 4-11 求自定类型元素序列的中位数 (25分)
- PTA 4-11 求自定类型元素序列的中位数 (25分)
- 求自定类型元素序列的中位数
- PTA求自定类型元素序列的中位数
- PTA 求自定类型元素序列的中位数,冒泡超时,改为希尔排序
- 求自定类型元素序列的中位数 PAT
- 求自定类型元素序列的中位数
- PAT练习基础编程题目之求自定类型元素序列的中位数
- 4-11 求自定类型元素的平均 (10分)
- 4-5 求自定类型元素的最大值 (10分)