选择问题(选择数组中第K小的数)
由排序问题可以引申出选择问题,选择问题就是选择并返回数组中第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; }
思想很不错,值得学习。
夜深了,,,
唉,失恋的人就是矫情,写个博客还得装逼一下