線性時間最近點對(一維&二維)
阿新 • • 發佈:2018-12-17
到現在看著虛擬碼寫不出來遞迴函式,不知道計算過程應該放在哪兒,我覺得是夠菜了,一個一維的求解弄一晚上。
菜的真實,菜的絕望。
#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; }
二維的明天補上