Description
输入n个数,求其中第k小的数。
思路:采用快排求解,代码如下
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
//partition的作用是将小于povit的元素放左边,大于povit的元素放右边
int Partition(int arr[],int left,int right)
{
int i=left,j=right,povit=arr[left];
while(i<j)
{
while(i<j && povit<=arr[j])
j--;
arr[i]=arr[j];
while(i<j && povit>=arr[i])
i++;
arr[j]=arr[i];
}
arr[i]=povit;
//返回划分点i
return i;
}
//对划分函数作出修改,在还未划分前,从arr[left~right]中随机选出一个基准元素
int RandomizedPartition(int arr[],int left,int right)
{
int random_index=rand()%(right-left+1)+left;
int temp;
//将一个随机下标的元素的值和基准的值进行交换
temp=arr[left];
arr[left]=arr[random_index];
arr[random_index]=temp;
return Partition(arr,left,right);
}
//用RandomizedSelect函数找出第k小的数
int RandomizedSelect(int arr[],int left,int right,int k)
{
if(left==right)
return arr[left];
int povit_index=RandomizedPartition(arr,left,right);
int left_elem_num=povit_index-left+1;
if(k<=left_elem_num)
return RandomizedSelect(arr,left,povit_index,k);
else
return RandomizedSelect(arr,povit_index+1,right,k-left_elem_num);
}
int main()
{
srand((unsigned)time(0));
int n,k;
scanf("%d%d",&n,&k);
int arr[n];
int j=0,value;
for(int i=0;i<n;i++)
{
scanf("%d",&value);
arr[j]=value;
j++;
}
printf("%d\n",RandomizedSelect(arr, 0, n-1, k));
return 0;
}