乱序数组中第k大的数(顺序统计量)

该问题是顺序统计量中十分经典的问题。

使用快排中的分区法,将第k大的数排序。若双向扫描分区加上三点中值法或绝对中值法,可以保证在 O(n) 时间里找出第k大的数。

补充:可以直接使用C++STL中的nth_element函数(一定注意使用形式!!!!)。

 1 /*
 2  * 第k大的数 
 3  */
 4 int part_(int arr[], int p, int r)
 5 {
 6     int b = p;
 7     while (p <= r) {
 8         while (p <= r && arr[p] <= arr[b]) p++;
 9         while (p <= r && arr[r] > arr[b]) r--;
10         if (p < r) 
11             swap(arr[r], arr[p]);
12     }
13     swap(arr[b], arr[r]);
14     return r;
15 }
16 int select(int arr[], int p, int r,int k)
17 {
18     int kp = 0;
19     while (1) {
20         kp = part_(arr, p, r); // 双向扫描分区
21         if (kp == k) return arr[kp];
22         else if (kp > k) r = kp - 1;
23         else p = kp + 1;
24     }
25 }
26 int main()
27 {
28     int ar[10];
29     srand((unsigned)time(nullptr));
30     for (int i = 0; i <= 9; i++)
31         cout << (ar[i] = rand() % (15 - 1 + 1) + 1) << " ";
32     cout << endl;
33     // 打印第k大的数
34     int arr[10];
35     for (int i = 0; i <= 9; i++)
36         arr[i] = ar[i];
37     cout << select(ar, 0, 9, 9) << endl;
38     nth_element(arr, arr + 9, arr + 10); // 包头不包尾,要有尾后迭代器
39     cout <<  arr[9]<< endl;
40     return 0;
41 }

 

posted on 2020-04-18 16:34  Black_x  阅读(310)  评论(0编辑  收藏  举报