求解此问题最简单的方式就是先将数组排序,然后取出最小的k个数即可
递归实现:
首先找出一个中间数mid,本例中以数组中第一个数为中间数。然后以mid将数组分成两拨,小于等于mid的一拨存入low数组,大于mid的一拨存入max数组,如果low中元素个数m小于等于k,则表明low数组中全部元素和mid均为所求,并且还需要从max数组中取k-1-m个最小的数;
如果low中元素个数大于等于\k,则可以丢弃max数组,从low数组中找最小的k个数即可。(max数组的丢弃会使得计算规模变小)
//寻找最小的K个数
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
//保存结果,count表示当前已找到多少个结果
int result[100],count=0;
void getLowest(int *a,int n,int k)
{
if(n==k)
{
int i;
for(i=0;i<n;i++)
{
result[count++]=a[i];
}
return;
}
int low[n],max[n],lcount=0,rcount=0;
int i=1,mid=a[0];
//以a[0]为界,将数组分成两拨
for(;i<n;i++)
{
if(a[i]<=mid)low[lcount++]=a[i];
else max[rcount++]=a[i];
}
//如果较小的哪一组所含元素个数大于等于K,则递归
if(lcount>=k)
{
getLowest(low,lcount,k);
return;
}
//否则,mid和low数组必为所求,将其保存,在剩下的数组中找k-lcount-1个即可
else
{
result[count++]=mid;
for(i=0;i<lcount;i++)
{
result[count++]=low[i];
}
getLowest(max,rcount,k-lcount-1);
return;
}
}
int main(){
int i,len,k;
srand(time(NULL));
printf("Input the array length:");
scanf("%d",&len);
int a[len];
for(i=0;i<len;i++){
a[i]=rand()/(RAND_MAX+1.0)*100.0+1;
printf("%d ",a[i]);
}
printf("\nInput the number you want to find for minest:");
scanf("%d",&k);
getLowest(a,len,k);
for(i=0;i<k;i++)
printf("%d ",result[i]);
putchar('\n');
}
结果: