选择第k小的元素-O(n)的时间复杂度
实现了一下算法书上的例子, 在线性的时间内完成选择第k个元素。
1 /* 2 3 */ 4 #include <stdio.h> 5 #include <stdlib.h> 6 #include <string.h> 7 #include <math.h> 8 #define MAX 111 9 10 int comp(const void *a, const void *b) 11 { 12 int *aa = (int *)a; 13 int *bb = (int *)b; 14 return *aa - *bb; 15 } 16 17 int selection(int *a, int len, int k) 18 { 19 int count = len / 5; 20 int m[MAX], num = 0; 21 int s1[MAX], s2[MAX]; 22 int num_s1 = 0, num_s2 = 0; 23 24 if (len <= 5) 25 { 26 qsort(a, len, sizeof(int), comp); 27 return a[k - 1]; 28 } 29 for (int i = 0; i < count; i++) 30 { 31 // 5*i to 5*i+4 32 qsort(a + 5 * i, 5, sizeof(int), comp); 33 m[num++] = a[5 * i + 2]; 34 } 35 36 int m_star = selection(m, num, num / 2 + 1); // 特别注意如果是num / 2的话,当num=1时,传递给selection的k为0, 导致a[0 - 1]的bug! 37 38 for (int i = 0; i < count; i++) 39 { 40 if (a[5 * i + 2] < m_star) 41 { 42 s1[num_s1++] = a[5 * i]; 43 s1[num_s1++] = a[5 * i + 1]; 44 s1[num_s1++] = a[5 * i + 2]; 45 46 if (a[5 * i + 3] < m_star) 47 s1[num_s1++] = a[5 * i + 3]; 48 else 49 s2[num_s2++] = a[5 * i + 3]; 50 51 if (a[5 * i + 4] < m_star) 52 s1[num_s1++] = a[5 * i + 4]; 53 else 54 s2[num_s2++] = a[5 * i + 4]; 55 } 56 else if (a[5 * i + 2] == m_star) 57 { 58 s1[num_s1++] = a[5 * i]; 59 s1[num_s1++] = a[5 * i + 1]; 60 s2[num_s2++] = a[5 * i + 3]; 61 s2[num_s2++] = a[5 * i + 4]; 62 } 63 else 64 { 65 s2[num_s2++] = a[5 * i + 3]; 66 s2[num_s2++] = a[5 * i + 4]; 67 s2[num_s2++] = a[5 * i + 2]; 68 69 if (a[5 * i] < m_star) 70 s1[num_s1++] = a[5 * i]; 71 else 72 s2[num_s2++] = a[5 * i]; 73 74 if (a[5 * i + 1] < m_star) 75 s1[num_s1++] = a[5 * i + 1]; 76 else 77 s2[num_s2++] = a[5 * i + 1]; 78 } 79 } 80 81 for (int i = 5 * count; i < len; i++) 82 { 83 if (a[i] < m_star) 84 s1[num_s1++] = a[i]; 85 else 86 s2[num_s2++] = a[i]; 87 } 88 89 if (k == num_s1 + 1) 90 return m_star; 91 else if (k <= num_s1) 92 return selection(s1, num_s1, k); 93 else 94 return selection(s2, num_s2, k - num_s1 - 1); 95 } 96 97 int main() 98 { 99 int a[] = {9, 8, 10, 1, 1, 1, 1, 20, 11, 11}; 100 //int a[] = {19, 20, 15, 9, 10, 11}; 101 printf("%d ", selection(a, sizeof(a) / sizeof(int), 6)); 102 103 }