Description
给定线性序集中n个元素和一个整数k,1 ≤ k ≤ n,请找出这n个元素中第k小的元素
快速选择的变种。
当position = k 时,array[position]为第k小。
当position < k 时, 第k小在右半部分,即 [position+1,right]。
当position > k 时, 第k小在左半部分,即[left,position-1]。
使用随机化快排,最坏时间复杂度为(n^2),但平均性能很好。
代码如下。
#include <stdio.h>
#include <math.h>
#include <time.h>
#include <malloc.h>
#include <stdlib.h>
//int a[100005];
int random_pos( int left, int right )
{
srand((unsigned)time(NULL));
return rand()%( right - left +1 ) + left;
}
int xth_small( int a[], int k, int left, int right )
{
if(left >= right)
return a[left];
int position = random_pos( left, right );
int key = a[position],i = left, j = right;
while( i < j )
{
while( i < j && a[i] < key )
{
i++;
}
while( i < j && a[j] > key )
{
j--;
}
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
a[i] = key;
// xth_small(k,left,position);
// xth_small(k,position+1, right);
position = i;
/**
printf("%d*\n", position);
for( int kk = left; kk <= right; kk++ )
printf("%d ", a[kk]);
printf("\n");
*/
if(position == k)
{
return key;
}
else if( position < k )
{
return xth_small(a, k, position+1, right);
}
else
{
return xth_small(a, k, left, position-1);
}
}
int main()
{
int n, k;
scanf("%d%d", &n, &k);
int a[n+5];
for( int i = 0; i < n; i++ )
{
scanf("%d", &a[i]);
}
//xth_small(k,0, n-1);
printf("%d\n",xth_small(a,k-1,0,n-1));
/**
for( int k1 = 0; k1 < n; k1++ )
{
printf("%d ", a[k1]);
}
*/
return 0;
}
另外
还有一种算法最坏情况下时间复杂度为O(n)。