1. 程式人生 > >線性時間最近點對(一維&二維)

線性時間最近點對(一維&二維)

到現在看著虛擬碼寫不出來遞迴函式,不知道計算過程應該放在哪兒,我覺得是夠菜了,一個一維的求解弄一晚上。

菜的真實,菜的絕望。

#include<stdio.h>
#include<stdlib.h>
#include<math.h>
class pair{
	public:
	double dis;
	int point1,point2;
	
	operator<(const pair &p)
	{
		return dis<p.dis;
	}
};
void Swap(double *a,double *b)
{
	double tep=*a;
	*a=*b;
	*b=tep;
}

int Partition(double *a,int l,int r,double value)
{
	double tep=value;
	int i=l,j=r;
	while(i<j)
	{
		while(a[i]<tep && i<r)	i++;
		while(a[j]>tep && j>l) j--;
		if(i<j)
			Swap(a+i,a+j);
	}
	return j;
}

void quicksort(double *a,int l,int r)
{
	if(l>=r)
		return ;
	int select=rand()%(r-l+1)+l;
	double tep=a[select];
	int j=Partition(a,l,r,tep);
	quicksort(a,l,j);
	quicksort(a,j+1,r);
}

double Select(double *a,int l,int r,int rank)
{
	if(r-l+1<=75)
	{
		quicksort(a,l,r);
		return a[l+rank-1];
	}
	for(int i=0;i<=(r-l-4)/5;i++)
	{
		quicksort(a,l+i*5,l+5*i+4);
		Swap(a+l+5*i+2,a+l+i);
	}
	double mid=Select(a,l,l+(r-l-4)/5,(r-l-4)/10);
	int index=Partition(a,l,r,mid);
	int surplus=index-l+1;
	if(surplus>=rank)
		return Select(a,l,index,rank); 
	else
		return Select(a,index+1,r,surplus-rank);
}

int MAX(double *a,int l,int r)
{
	double m=-1e7;
	int f=0;
	for(int i=l;i<=r;i++)
		if(m<a[i])
			m=a[i],f=i;
	return f;
}

double MIN(double *a,int l,int r)
{
	double m=1e7,f=0;
	for(int i=l;i<=r;i++)
		if(m>a[i])
			m=a[i],f=i;
	return f;
}


pair cloest(double *a,int l,int r)
{
	pair ans={1e7,l,r};
	if(r-l<1)
		return ans;
	double mid=Select(a,l,r,(r-l+1)/2);
	int index=Partition(a,l,r,mid);
	pair dis1=cloest(a,l,index),dis2=cloest(a,index+1,r);
	int Max=MAX(a,l,index);
	int Min=MIN(a,index+1,r);
	double t=a[Min]-a[Max];
	pair tt={t,Max,Min};
	if(dis1.dis<dis2.dis)
	{
		if(dis1.dis<tt.dis)
			ans=dis1;
		else
			ans=tt;
	}
	else
	{
		if(tt.dis<dis2.dis)
			ans=tt;
		else
			ans=dis2;
	}
	return ans;
}

int main()
{
	int n;
	double p[10005];
	pair dis;
	printf("Please input the number of points\n");
	scanf("%d",&n);
	for(int i=0;i<n;i++)
		scanf("%lf",&p[i]);
	dis=cloest(p,0,n-1);
	printf("%.3lf  p1:%d  p2:%d\n",dis.dis,dis.point1,dis.point2);
	return 0;
}

二維的明天補上