Description
现有一个包含n个整数(1<=n<=900000)的无序序列(保证序列内元素各不相同),输入一个整数k(1<=k<=n),请用较快的方式找出该序列的第k小数并输出。
Input
多组输入。
首先输入一个数据组数T(1<=T<=100)
接下来是T组数据。
每组数据有两行。
第一行先输入两个整数,n和k。
接下来是一行输入n个由空格分开的互不相同的整数num(1<=num<=90000000)。
Output
对于每组数据,输出该组数据中第k小的数num。
Sample
Input
1
6 4
3 2 5 1 4 6
Output
4
第K小的数与第K大的数思路相同,排序时选择快速排序,并将快速排序中的分治法添加一个限制条件进而减少一大半的运算
#include <stdio.h>
#include <stdlib.h>
int partition(int a[],int left,int right)
//将分治法的核心单独设置为一个函数;
{
int x = a[left];
while(left < right)
{
while(left < right&&a[right] >= x) right--;
a[left] = a[right];
while(left < right&&a[left] <= x) left++;
a[right] = a[left];
}
a[left] = x;
return left;//此时这个标准值得下标即为完全排好序后标准值的位置;
}
int find(int a[],int left,int right,int k)
{
int i;
if(left<=right)
{
i = partition(a,left, right);
if(i==k) return a[i]; //这是这个递归函数的结束标志;
if(i>k) //这就是快速排序在分治法中添加的条件;
return (find(a,left,i-1,k));
else return (find(a,i+1,right,k));
}
}
int main()
{
int i,t,k,n,m,a[100002];
while(~scanf("%d",&t))
{
while(t--)
{
scanf("%d%d",&n,&k);
for(i=1; i<=n; i++)
{
scanf("%d",&a[i]);
}
m = find(a,1,n,k);
printf("%d\n",m);
}
}
return 0;
}