随机快排查找第k小元素和随机化查找第k小元素

随机化查找第k小元素:不必将所有元素按从大到小或从小到大排序即可找出第k小值

思路:随机从序列中取一值,从第一个值开始,将比起小的放在左面,比起大的放在右面。然后比较k与这个值的位置(数组下角标,我设置成从1开始的)如果k的值比这个值的下角标大,那么取这个值的右半部分(都比这个值小)然后再从其中取以随机值,进行如上操作,直到这个值的下角标与k相等为止。如果k的值比这个值的下角标小,那么取这个值的左半部分(都比这个值小)然后再从其中取以随机值,进行如上操作,直到这个值的下角标与k相等为止。

#include<stdio.h>
#include<time.h>
#include<stdlib.h>
unsigned long long a[50000000];
unsigned long long b[50000000];
void suiji(unsigned long long a[],unsigned long long m,unsigned long long r)
{
    if(m<r)
    {
        
        unsigned long long temp=0,p;
        p=rand()%(r-m+1)+m;
        temp=a[m];
        a[m]=a[p];
        a[p]=temp;
        unsigned long long i=m;
        unsigned long long j=r;
        while(i<j)
        {
            while(a[i]<a[j]&&i<j)
            {
                j--;
            }
            if(i<j)
            {
                temp=a[i];
                a[i]=a[j];
                a[j]=temp;
                i++;
            }
            
            while(a[i]<a[j]&&i<j)
            {
                i++;
            }
            if(i<j)
            {
                temp=a[i];
                a[i]=a[j];
                a[j]=temp;
                j--;
            }
        
        }
        if(i==j)
        {
            suiji(a,m,i-1);
            suiji(a,i+1,r);
        }
    }
}
void chazhao(unsigned long long a[],int l,int r,int k)
{
    int n=l,m=r,p,i,q=0,v=0;
    p=rand()%(r-l+1)+l;    
    for(i=r;i>=l;i--)
    {
        if(a[i]>a[p])
        {
            b[m]=a[i];
            m--;
        }
        else if(a[i]<a[p])
        {
            b[n]=a[i];
            n++;
        } 
        else
        {
            q++;
        }
    } 
    for(i=n;i<=m;i++)
    {
        b[i]=a[p];
        n++;
    }
    for(i=l;i<=r;i++)
    {
        a[i]=b[i];
    }
    if((k>=(n-q))&&k<n)
    {
        printf("随机化查找第k个数是%d\n",a[k]);
    }
    else if(k<(n-q))
    {
        r=n-q-1;
        chazhao(a,l,r,k); 
    }
    else if(n<=k)
    {
       l=n;
        chazhao(a,l,r,k);
    }
}
int main()
{
    int n,i,k;
    printf("请输入数字个数n<=50000000:");
    scanf("%d",&n);
    printf("请输入k:");
    scanf("%d",&k); 
    srand(time(NULL));
    for(i=1;i<=n;i++){//随机生成待排数组
        a[i]=rand();
    }
    clock_t beg,end;//起始时间和结束时间 
    double time;
    beg=clock();
    suiji(a,1,n);
    printf("随机化快排查找第k个元素是%d\n",a[k]); 
    end=clock();
    time=(double)(end- beg)/CLOCKS_PER_SEC;
    printf("随机产生成数进行随机快排查找第k小元素的运行时间:%f s\n",time);
    beg=clock();
    chazhao(a,1,n,k);
    end=clock();
    time=(double)(end- beg)/CLOCKS_PER_SEC;
    printf("随机产生成数进行随机化查找第k小元素的运行时间:%f s\n",time); 
    return 0;

猜你喜欢

转载自blog.csdn.net/yang03_26/article/details/84345548