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