選擇問題(選擇數組中第K小的數)
阿新 • • 發佈:2017-05-15
++i bsp 裝逼 mes tof quick 復雜度 names 返回
由排序問題可以引申出選擇問題,選擇問題就是選擇並返回數組中第k小的數,如果把數組全部排好序,在返回第k小的數,也能正確返回,但是這無疑做了很多無用功,由上篇博客中提到的快速排序,稍稍修改下就可以以較小的時間復雜度返回正確結果。
代碼如下:
#include<iostream> using namespace std; #define Cutoff 3 int A[13] = {81,94,11,96,12,35,17,95,28,58,41,75,15}; void Swap(int &a, int &b) { int c; c = a; a = b; b = c; } void InsetionSort (int A[], int N) //插入排序 { int j, p; int Tmp; for (p = 1; p < N; p++) { Tmp = A[p]; for(j = p; j > 0 && A[j - 1] > Tmp; j--) A[j] = A[j - 1]; A[j] = Tmp; } } int Median (int A[],int Left, int Right) //實現三數中值分割,選取樞紐元 { int Center = (Left + Right ) / 2; if(A[Left] > A[Center]) Swap(A[Left] , A[Center]); if(A[Left] > A[Right]) Swap(A[Left] , A[Right]); if(A[Center] > A[Right]) Swap(A[Center] , A[Right]); /* A[Left] <= A[Center] <= A[Right] */ Swap(A[Center], A[Right - 1]); //把樞紐元放在倒數第二個 return A[Right - 1]; } void Qselete (int A[], int k, int Left, int Right) { int i, j; int Pivot; if(Left + Cutoff <= Right) { Pivot = Median(A,Left,Right); i = Left; j = Right - 1; for( ; ; ) { while(A[++i] < Pivot) { } while(A[--j] > Pivot) { } if(i < j) Swap(A[i], A[j]); else break; } Swap(A[i], A[Right - 1]); // 恢復樞紐元的位置 if(k <= i) Qselete (A, k, Left, i -1); else Qselete (A, k, i + 1, Right); } else InsetionSort (A + Left, Right - Left + 1); } int Quick_Sort (int A[], int k, int N) { Qselete (A, k - 1, 0, N - 1); return A[k - 1]; } int main () { cout << Quick_Sort (A , 3, 13) << endl; return 0; }
思想很不錯,值得學習。
夜深了,,,
唉,失戀的人就是矯情,寫個博客還得裝逼一下
選擇問題(選擇數組中第K小的數)