在一组随机排列的数中找出第k小的,这个元素称为k-th Order Statistic。能想到的最直观的算法肯定是先把这些数排序然后取第k个,时间复杂度和排序算法相同,可以是Θ(nlgn),但它也有平均情况下时间复杂度是Θ(n)的算法,将快速排序算法稍加修改就可以解决这个问题:
1 /*
2 **Find out the K-th small number of a set of random numbers with O(n)
3 **2011.10.25
4 **By LYLtim
5 */
6
7 #include<stdio.h>
8 #include<stdlib.h>
9 #include<time.h>
10
11 #define LEN 6
12 int a[LEN], k;
13
14 void creat()
15 {
16 register int *pa;
17 srand(time(NULL));
18 for (pa = a; pa < &a[LEN]; )
19 printf("%d ", *pa++ = rand() % LEN);
20 printf("\n");
21 }
22
23 void swap(int *a, int *b)
24 {
25 int t = *a;
26 *a = *b;
27 *b = t;
28 }
29
30 int Find (int left, int right)
31 {
32 if (left >= right) return; //do nothing if array contains fewer than 2 elemants
33 swap(&a[left], &a[(left + right) >> 1]); //move partition elem to left
34 unsigned p, last = left;
35 for (p = left + 1; p <= right; p++) //partiton
36 if (a[p] < a[left])
37 swap(&a[p], &a[++last]);
38 swap(&a[left], &a[last]); //restore partiton elem
39 if (last > k - 1) return Find(left, last - 1);
40 if (last < k - 1) return Find(last + 1, right);
41 return a[last];
42 }
43
44 int main(void)
45 {
46 creat();
47 printf("Inupt k to find out the K-th small number:");
48 scanf("%d", &k);
49 printf("The %dth small number is: %d\n", k, Find(0, LEN - 1));
50 }