<code> 二维空间下的最近点对查找
1 // space_minum.cpp : Defines the entry point for the console application. 2 // 3 #include <iostream> 4 #include <math.h> 5 6 using namespace std; 7 8 float minu=10000000; 9 int fff,bbb; 10 11 void Insertsort(float list[],float X[],int a,int b); 12 void Insertsort(float list[],float X[],int a,int b){ 13 float next,tmp;//插入排序,对xy坐标组按照x坐标排序 14 int j; 15 if(a>b)return; 16 for(int x=a;x<=b;x++){ 17 next=list[x]; 18 tmp=X[x]; 19 for(j=x-1;j>=a&&next<list[j];j--) 20 {list[j+1]=list[j]; 21 X[j+1]=X[j]; 22 } 23 list[j+1]=next; 24 X[j+1]=tmp; 25 } 26 27 } 28 29 float Dis(float x1,float y1,float x2,float y2){ 30 float ans=sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)); 31 return ans; 32 } 33 34 int find_tmp(int mid,int limit,float dis,char updown,float x[]){ 35 int i=mid; 36 if(updown=='f'){//向前搜索 37 for(i;i>=limit&&x[mid]-dis<x[i];i--); 38 return i; 39 } 40 else if(updown=='b'){//向后搜索 41 for(i;i<=limit&&x[mid]+dis>x[i];i++); 42 return i; 43 } 44 45 } 46 47 48 49 50 float seperate(float x[],float y[],int left,int right){ 51 int mid=(left+right)/2; 52 float dis=minu; 53 54 if(right-left==0)return dis; 55 else if(right-left==1) { 56 float t=Dis(x[right],y[right],x[left],y[left]); 57 if(t<minu){minu=t;fff=right;bbb=left;} 58 return t; 59 } 60 else { 61 float ll=seperate(x,y,left,mid); 62 float rr=seperate(x,y,mid,right); 63 if(ll<rr)dis=ll;else dis=rr; 64 if(minu<dis)dis=minu;//修改为在以计算过的点中最小值,而非该划分中的最小值,提高速度 65 66 float t_mid=x[mid];//从划分元拓展dis单位 67 int f,b; 68 f=find_tmp(mid,left,dis,'f',x);//向前向后搜索查找范围内元素 69 b=find_tmp(mid,right,dis,'b',x); 70 71 72 //从mid-f个点依次选出点与b-mid个点计算最小值 73 //注:已经按照x坐标进行排序,当x[b]-x[f]中点>=dis时,f++,b从mid重新开始 74 75 float tmp=0; 76 for(int i=f;i<mid;i++){ 77 for(int j=mid;j<=b;j++){//修改比较条件j<=b&&j-mid<=6,原因已在文档中说明 78 if(x[j]-x[i]<dis) 79 tmp =Dis(x[i],y[i],x[j],y[j]); 80 else break; 81 if(tmp!=0&&tmp<dis){dis=tmp;minu=tmp; 82 //cout<<i<<' '<<fff<<' '; 83 fff=i;bbb=j; 84 } 85 } 86 } 87 88 return dis; 89 90 91 // float t=0;for(int i=f;i<=mid;i++){for(int j=mid;j<=b;j++){ 92 // t =Dis(x[i],y[i],x[j],y[j]);if(t!=0&&t<dis)dis=t;}}return dis; 93 94 } 95 } 96 97 98 99 100 const int max=20; 101 int main(int argc, char* argv[]) 102 { 103 104 float x[max]; 105 float y[max]; 106 cout<<"输入点对数"; 107 int n; 108 cin>>n; 109 cout<<"输入图中点坐标x,y"<<endl; 110 for(int i=0;i<n;i++) 111 cin>>x[i]>>y[i]; 112 //for(i=0;i<n;i++) 113 //cout<<x[i]<<' '<<y[i]; 114 //按照x坐标排序,用于划分 115 Insertsort(x,y,0,n-1); 116 //for(i=0;i<n;i++) 117 //cout<<x[i]<<' '<<y[i]<<'|';cout<<endl; 118 119 cout<<seperate(x,y,0,n-1)<<endl; 120 cout<<'['<<x[fff]<<','<<y[fff]<<']'<<endl; 121 cout<<'['<<x[bbb]<<','<<y[bbb]<<']'<<endl; 122 return 0; 123 }