方法一:基于快排
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 }