无序整数数组中找第k大的数

时间:2022-12-30 15:36:40

方法一:基于快排

 1 /*
 2 基于区间快排的第K小算法 ,输出a[k-1]即可,O(n*logn);每次只对后半部分递归便可把复杂度降到O(n) 
 3 主要思路是每次随机在数组中选取一个元素p,利用这个元素将数组分成两部分,比p小的元素在分好的数组左边,p和比p大的元素在数组右边,
 4 根据k值选择在数组左半或者右半部分继续递归执行查找。
 5 */
 6 #include <iostream>
 7 #include <cstring>
 8 #include <vector>
 9 #include <algorithm>
10 using namespace std;
11 
12 void swap(int *p, int *q)
13 {
14     int t;
15     t = *p;
16     *p = *q;
17     *q = t;
18 }
19 
20 int findNumberK(vector<int> &vec, int k, int from, int to)
21 {
22     int roll = vec[from], middle = 0, j = from;//roll是指标杆值 
23     for(int i = from+1 ; i<= to ; i++)
24     {
25         if(vec[i] < roll)
26         {
27             j++;//roll左边每次被换的元素 的下标 
28             swap(&vec[i], &vec[j]);
29             middle++;
30         }
31     }
32     swap(&vec[from], &vec[j]);
33     if(middle == k -1 )
34         return roll;
35     else if (middle < k - 1)
36     {
37         return findNumberK(vec, k - middle - 1, j + 1, to);
38     }
39     else
40         return findNumberK(vec, k, from, j - 1);
41 }
42 
43 int main()
44 {
45     vector<int> vec;
46     int temp, k;
47 
48     cout << "input data(以0结束):" << endl;
49     cin >> temp;
50 
51     while(temp != 0)
52     {
53         vec.push_back(temp);
54         cin >> temp;
55     }
56 
57     cout << "input K: " << endl;
58 
59     cin >> k;
60 
61     int re = findNumberK(vec , k, 0 ,vec.size() - 1);
62 
63     cout << "Test Result: "  << re << endl;
64 
65     sort(vec.begin(), vec.end(), less<int>());
66 
67     cout << "real Result: "  << vec[k-1] << endl;
68     //while(1);
69     return 0;
70 }