标签:分治
利用快速排序的思想,一开始选取中枢元,然后左右调整,接着比对中枢元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
标签:分治
原文地址:http://blog.csdn.net/core__code/article/details/47381377