任务描述
本关任务:给定一个数组包含n个元素,统计前m大的数并且把这m个数输出。
相关知识
思路:用分治处理,把前m大的都交换到数组最右边,再输出。
可以调用函数Partition( ),在O(n)时间内把数组前m大的都交换到最右边。
- 设key=a[0], 调用Partition()函数将数组划分为两个子表,使得比key小的元素都在key左边,比key大的元素都在key右边(线性时间完成)
- 分以下三种情况选择数组的前子表或后子表再调用Partition函数 a = m 完成 a > m 对右边子表再进行Partition( ) a < m 对左边子表再进行Partition( )
编程要求
根据提示,在右侧编辑器补充代码,输出前m大的数。
测试说明
平台会对你编写的代码进行测试:
测试输入: 20 6
预期输出: Before sort:
11,58,97,59,96,81,62,41,40,81,50,24,47,9,44,9,65,7,79,59,
After sort:
7,9,9,11,58,44,47,41,40,24,50,59,62,59,65,79,81,81,96,97,
测试输入: 30 8
预期输出: Before sort:
33,71,30,21,52,54,34,72,82,99,98,39,70,54,66,85,13,7,69,47,39,57,97,29,49,59,75,29,93,44,
After sort:
29,29,30,21,7,13,33,44,71,59,49,39,70,54,66,52,34,54,69,47,39,57,72,97,85,98,75,99,93,82,
#include <stdio.h>
#include<stdlib.h>
int Partition(int *L,int low,int high) ; //交换顺序表L中子表L[low..high]的记录,使枢轴记录到位,并返回其所在位置,此时在它之前(后)的记录均不大(小)于它。
void QSortM(int *L,int low,int high,int m) ;
void output(int *a,int n) ;
void swap(int &a, int &b) ;
int main()
{
int *a=0;
int left=0,right=10; //初始化left和right的值
int k,m,n,i;
scanf("%d",&n);
srand(n);
a=new int[n];
for(i=0;i<n;i++)
{
a[i]=rand() % 100;
}
printf("Before sort:\n");
output(a,n);
scanf("%d",&m);
left=0,right=n-1; //初始化left和right的值
QSortM(a,left,right,m);
printf("After sort:\n");
output(a,n);
printf("\n");
system("pause");
return 0;
}
void swap(int &a, int &b)
{
int t;
t=a;a=b;b=t;
}
void output(int *a,int n)
{
int i;
for(i=0;i<n;i++)
{
printf("%d,",a[i]);
}
printf("\n");
}
//交换顺序表L中子表L[low..high]的记录,使枢轴记录到位,并返回其所在位置,此时在它之前(后)的记录均不大(小)于它。
int Partition(int *L,int low,int high)
{
int t;
int pivotkey;
pivotkey=L[low]; // 用子表的第一个记录作枢轴记录
while(low < high)
{ // 从表的两端交替地向中间扫描
while( low<high && L[high]>=pivotkey)
--high;
swap(L[low], L[high]); // 将比枢轴记录小的记录交换到低端
while(low<high && L[low]<=pivotkey)
++low;
swap(L[low],L[high]); ; // 将比枢轴记录大的记录交换到高端
}
return low; // 返回枢轴所在位置
}
void QSortM(int *L,int low,int high,int m)
{
/********** Begin **********/
if(low < high){
int pivot = Partition(L, low, high); // 将数组划分为两个子表
if(high - pivot + 1 == m) // 找到了前m大的数
return;
else if(high - pivot + 1 > m) // 前m大的数在右边子表
QSortM(L, pivot+1, high, m);
else // 前m大的数在左边子表
QSortM(L, low, pivot-1, m-(high-pivot+1));
}
/********** End **********/
}