无序数组求第K大/第K小的数
方法一:quicksort
根据快排思想,从后往前找比基准数小的,交换位置。
从前往后找比基准数大的,交换位置。
最后安放基准数。
保证 l到p 是大数,若 p-l+1==k 那么p就是第K大
若 p-l+1<k 那么从 p+1 到 r 中 找 k-(p-l+1)大的数
若 p-l+1>k 那么从 l 到 p-1中 找第k大的数。
1 #include<iostream> 2 #include<cstdio> 3 #include<string> 4 #include<cstring> 5 #include<cmath> 6 #include<algorithm> 7 using namespace std; 8 int n, k; 9 int a[100010]; 10 int par(int l, int r) 11 { 12 int t = a[l]; 13 while (l < r) 14 { 15 while (l < r &&a[r] <= t) r--; 16 a[l] = a[r]; 17 while (l < r &&a[l] >= t) l++; 18 a[r] = a[l]; 19 } 20 a[l] = t; 21 return l; 22 } 23 int search(int l, int r,int k) 24 { 25 if (l <= r) 26 { 27 int p = par(l, r); 28 if (p - l + 1 == k) return p; 29 else if (p - l + 1 < k) return search(p+1,r,k-(p-l+1)); 30 else return search(l,p-1,k); 31 } 32 } 33 int main() 34 { 35 cin >> n >> k; 36 for (int i = 1; i <= n; i++) 37 cin >> a[i]; 38 cout << a[search(1, n, k)] << endl; 39 40 return 0; 41 }
方法二:最小堆
原本用swap函数的,后来好像swap并不能使两个数交换,以后我一定自己写。(鞠躬表示歉意)
搞了半天搞错了,还是挖坑吧。
1 #include<iostream> 2 #include<cstdio> 3 #include<string> 4 #include<cstring> 5 #include<map> 6 #include<algorithm> 7 #include<cmath> 8 using namespace std; 9 int n, a[11000],b,k; 10 void adjust(int i,int n) 11 { 12 int child = 2 * i; 13 while (child <= n) 14 { 15 if (child + 1 <= n && a[child] < a[child + 1]) 16 child++; 17 if (a[child] < a[i]) 18 break; 19 int t = a[child]; 20 a[child] = a[i]; 21 a[i] = t; 22 i = child; 23 child = 2 * i; 24 } 25 } 26 void dui(int n) 27 { 28 for (int i = n / 2; i >= 1; i--) 29 adjust(i, n); 30 } 31 int main() 32 { 33 cin >> n >> k; 34 for (int i = 1; i <= k; i++) 35 cin >> a[i]; 36 dui(k); 37 for (int i = 1; i <= n - k; i++) 38 { 39 cin >> b; 40 if (b < a[1]) 41 { 42 a[1] = b; 43 adjust(1,k); 44 } 45 } 46 cout << a[1] << endl; 47 return 0; 48 }
No matter how you feel, get up , dress up , show up ,and never give up.