利用快速排序的思想,一开始选取中枢元,然后左右调整,接着比对中枢元p和K的大小,如果 p+1 = k (数组从0开始), 那么a[p] 就是答案,因为在p之前的,肯定都是小于a[p]的, 在p之后的,肯定大于p, 所以 a[p] 就是第 p+1 小。假如 p+1 不等于K, 那么根据大小,进行左右调整。调整过程中,理想状态下,每次都砍掉一半,数组的起始坐标要进行调整。
代码:
// 快速排序法的修改 #include <iostream> #include <ctime> #include <cstdlib> #include <algorithm> #include <cstdio> using namespace std; const int MAX = 100000000; // 1亿个数 int a[MAX]; // arr数组, n 数组个数, k 第几小 int findKMin(int arr[], int n, int k) { if ( n<0 || n>MAX || k<=0 || k>n) return -1; // 假设以arr[0]为交换的中枢值, 进行左右交换 int value = arr[0]; int low = 0; int high = n-1; while(low < high) { while(low < high && arr[high] >= value) high--; arr[low] = arr[high]; while(low < high && arr[low] <= value) low++; arr[high] = arr[low]; } arr[low] = value; // 对 K 进行判断, 左右搜寻的时候,要变更arr的起始位置 if (low+1 == k) return arr[low]; else if (low+1 < k) // 在右边继续搜寻 return findKMin(arr+low+1, n-low-1, k-low-1); else // low > k // 在左边搜寻 return findKMin(arr, low+1, k); } int main(void) { // 产生随机数 srand( (unsigned)time(NULL) ); for(int i=0; i<MAX; ++i) { a[i] = (rand()+1)*(rand()+1) ; //printf("%d ", a[i]); } int k = 5; //int num = findKMin(a, MAX, k); // start at 0 //printf("%d\n", num); // 普通排序搜索 sort(a, a+MAX); printf("%d", a[k-1]); /* for(int i=0; i<k; ++i) { printf("%d ", a[i]); } printf("\n"); */ return 0; }
时间的比对:
数据比较大,产生1亿个随机数的大概时间。
用分治法求解的时间。
普通排序之后定位的时间, 数据随机产生,所以与分治法求解的结果不同。
明显看出两者的时间相差是非常大的,
版权声明:本文为博主原创文章,未经博主允许不得转载。 http://blog.csdn.net/core__code
时间: 2024-10-28 20:12:24