Quick-Select 1亿个数快速求第K小的数 分治法

Quick-Select  1亿个数快速求第K小的数  分治法

利用快速排序的思想,一开始选取中枢元,然后左右调整,接着比对中枢元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

Quick-Select 1亿个数快速求第K小的数 分治法的相关文章

Luogu P1923 求第k小的数

Luogu P1923 求第k小的数 一看这题,静态查询区间第$k$小的数,不就是可持久化线段树(主席树)的模板题吗?!(误) 直接把主席树的板子打上来?: #include<bits/stdc++.h> #define N 200010 #define mid ((l+r)>>1) using namespace std; int n,m,l,r,k,ans,id,siz; int a[N],b[N]; struct segmenttree { int ls,rs,sum,roo

*HDU2852 树状数组(求第K小的数)

KiKi's K-Number Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3864    Accepted Submission(s): 1715 Problem Description For the k-th number, we all should be very familiar with it. Of course,to

二分——无序数组快速查找第K小的数

#1133 : 二分·二分查找之k小数 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 在上一回里我们知道Nettle在玩<艦これ>,Nettle的镇守府有很多船位,但船位再多也是有限的.Nettle通过捞船又出了一艘稀有的船,但是已有的N(1≤N≤1,000,000)个船位都已经有船了.所以Nettle不得不把其中一艘船拆掉来让位给新的船.Nettle思考了很久,决定随机选择一个k,然后拆掉稀有度第k小的船. 已知每一艘船都有自己的稀有度,Nettle现在把所有

soj3102 O(n)求第k小的数

原本觉得挺简单的,开始就一直RE,后来还T..发现是服务器可能出问题了,老化了,时间变慢了,拿以前A掉的代码来都是T. 不过还是有快的方法的. 就是位运算.另外stl里也有现成的函数可以用nth_element(s,s+k-1,s+n); 但是还有一个问题,nth_element()换成自己写的就T..无语了.. 大家快来指点一下啊~~~~ #include<iostream> #include<cstdio> #include<cstring> #include<

普林斯顿公开课 算法3-2:求第k大的数

问题 给定N个元素的数组,求第k大的数. 特例 当k=0时,就是求最大值,当k=N-1时,就是求最小值. 应用 顺序统计 求top N排行榜 基本思想 使用快速排序方法中的分区思想,使得a[k]左侧没有更小的数,右侧没有更大的数 性能 快速选择算法的复杂度是N. 最坏情况下的复杂度是1/2N^2,但是可以通过预先洗牌来防止出现最坏情况 代码 public class QuickSort { // 对区间 [start, end) 进行分区 public static int partition(

O(n)时间复杂度求最小的k个数和第k小的数

//思路:使用快速排序的patition函数来进行处理 时间复杂度为O(n) #include<iostream> #include<cassert> using namespace std; int partition(int *ar, int len, int low, int high) { int temp = ar[low]; while(low < high) { while(low < high && temp < ar[high])

POJ 2761-Feed the dogs(划分树)求区间内第k小的数

Feed the dogs Time Limit: 6000MS   Memory Limit: 65536K Total Submissions: 17679   Accepted: 5561 Description Wind loves pretty dogs very much, and she has n pet dogs. So Jiajia has to feed the dogs every day for Wind. Jiajia loves Wind, but not the

《数据结构与算法分析:C语言描述》读书笔记------练习1.1 求第K大的数

求一组N个数中的第k个最大者,设k=N/2. 1 import java.util.Random; 2 3 4 public class K_Max { 5 6 /** 7 * @param args 8 */ 9 //求第K大的数,保证K大于等于1,小于等于array.length/2哦 10 public static int TopK(int array[],int K) 11 { 12 int topk[] = new int [K]; 13 for(int i = 0; i<topk.

STL--H - Black Box(两个优先队列,求第k小的值)

H - Black Box Time Limit:1000MS     Memory Limit:10000KB     64bit IO Format:%I64d & %I64u Submit Status Description Our Black Box represents a primitive database. It can save an integer array and has a special i variable. At the initial moment Black