1. 程式人生 > >隨機快排查詢第k小元素和隨機化查詢第k小元素

隨機快排查詢第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;