# Select（快速选择顺序统计量）原理及C++代码实现

SELECT算法利用快排中的partition思想来进行无序数组的快速选择。

``` 1 void InsertionSort(int * const begin, int * const end) {
2     int i, j, key;
3     for (i = 1; i < begin - end; ++i) {
4         key = *(begin + i);
5         for (j = i - 1; j >= 0 && (*(begin + j) > key); --j) {
6             *(begin + j + 1) = *(begin + j);
7         }
8         *(begin + j + 1) = key;
9     }
10 }
11 int Partition(int * const begin, int * const end, int x) {
12     int i = -1;
13     for (int j = 0; j < (end - begin); ++j) {
14         if (*(begin + j) < x) {
15             ++i;
16             swap(*(begin + i), *(begin + j));
17         }
18         else if (*(begin + j) == x && j != (end - begin - 1)) {
19             swap(*(begin + j), *(end - 1));
20             --j;
21         }
22     }
23     ++i;
24     swap(*(begin + i), *(end - 1));
25     return i;
26 }
27
28 //返回第k小的元素,要求输入元素互异，最坏情况下时间复杂度为线性
29 int Select(int * const begin, int * const end, int k) {
30     if (end - begin == 1)
31         return *begin;
32     int n = end - begin;
33     int groupnum = n / 5; //groupnum个组，每组五个数
34     int medium[10000]; //因小于50000个数
35
36     int i, j, t = groupnum;
37     for (i = 0, j = 0; t--; i += 5) {
38         InsertionSort(begin + i, begin + i + 5);
39         medium[j++] = *(begin + i + 2);
40     }
41     if (n > (groupnum * 5)) {
42         InsertionSort(begin + i, end);
43         medium[j++] = *(begin + i + (end - begin - i) / 2);
44     }
45
46     int x = Select(medium, medium + j, (j + 1) / 2);
47     int m = Partition(begin, end, x) + 1;
48     if (m == k)
49         return x;
50     else if (m > k)
51         return Select(begin, begin + m - 1, k);
52     else
53         return Select(begin + m, end, k - m);
54 }```

Select（快速选择顺序统计量）原理及C++代码实现

(0)
(0)