#include#include#include
using namespacestd;/*存储点的结构*/typedefstruct{float x,y; //点的x,y坐标
}POINT;/*辅助的点结构*/typedefstruct{int index; //点在X数组中的下标
float x, y; //点的x,y坐标
}A_POINT;/*对点进行递增顺序排序的比较*/
boolcompareX(POINT a, POINT b){return b.x>a.x;
}/*对辅助点进行递增排序的比较*/
boolcompareY(A_POINT a, A_POINT b){return b.y>a.y;
}/*计算两点距离的平方*/
floatdist(POINT a, POINT b){floatdx, dy;
dx= a.x - b.x, dy = a.y -b.y;return (dx*dx+dy*dy);
}/************************************************************************
* 求平面点集最近点对的分治算法
*
* 输入:存放平面点集点的数组X[]、辅助点数组Y[],数组起点下标low与终点下标high
* 输出:最近点对a,b及距离d
**********************************************************************/
void closest(POINT X[], A_POINT Y[], int low, int high, POINT &a, POINT &b, float &d){inti,j,k,m;
POINT al,bl,ar,br;floatdl,dr;if((high-low)==1){ //当n=2时直接计算
a = X[low], b = X[high], d =dist(X[low], X[high]);
}else{if((high-low)==2){ //当n=3时直接计算
dl = dist(X[low], X[low+1]);
dr= dist(X[low], X[low+2]);
d= dist(X[low+1], X[low+2]);if((dl<=dr)&&(dl<=d)){
a= X[low], b = X[low+1], d =dl;
}else{if(dr<=d){
a= X[low], b = X[low+2], d=dr;
}else{
a= X[low+1], b = X[low+2];
}
}
}else{ //当n>3时进行分治
A_POINT *SL = new A_POINT[(high-low)/2+1];
A_POINT*SR = new A_POINT[(high-low)/2];
m= (high-low)/2 + low; //把x数组以m为界划分为两半
j = k = 0;for(i=0; i<=high-low; i++){if(Y[i].index<=m){
SL[j++] = Y[i]; //收集左边子集中的最近点对
}else{
SR[k++] = Y[i]; //收集右边子集中的最近点对
}
}
closest(X,SL,low, m, al, bl, dl);//计算左边子集的最近点对
closest(X,SR,m+1, high, ar, br, dr);//计算右边子集的最近点对
if(dl
a = al, b = bl, d =dl;
}else{
a= ar, b = br, d =dr;
}
POINT*Z = new POINT[high-low+1];
k= 0;for( i=0; i<=high -low; i++){ //收集距离中线距离小于d的元素,保存到数组Z(因Y数组按y坐标递增排序,Z数组也一样)
if(fabs(X[m].x - Y[i].x)
Z[k].x= Y[i].x, Z[k++].y =Y[i].y;
}
}for( i=0; i
dl = dist(Z[i], Z[j]); //计算前后两点的距离
if(dl
a = Z[i], b = Z[j], d =dl;
}
}
}
delete SL;
delete SR;
delete Z;
}
}
}/**********************************************
* 求平面点集最近点对的分治算法
*
* 输入:存放平面点集点的数组X[],点的个数n
* 输出:最近点对a,b及距离d
**********************************************/
void closest_pair(POINT X[], int n, POINT &a, POINT &b, float &d){if(n<2){ //当点集个数小于2时不存在最近点对
d = 0;
}else{
sort(X,X+n, compareX); //对x数组进行递增排序
A_POINT *Y = new A_POINT[n]; //初始化辅助点数组Y
for( int i = 0 ; i < n ;i ++){
Y[i].index=i;
Y[i].x=X[i].x;
Y[i].y=X[i].y;
}
sort(Y,Y+n, compareY); //对y数组进行递增排序
closest(X,Y,0,n-1,a,b,d); //求亲密点对
d = sqrt(d); //将得到的d开平方才是两点间真正的距离
delete Y;
}
}intmain(){intn;
cout<
cin>>n;
cout<
POINT*X = newPOINT[n];for(int i=0; i
cin>>X[i].x>>X[i].y;
}
POINT a,b;floatd;
closest_pair(X,n,a,b,d);if(n>=2){
printf("(%.2f,%.2f) - (%.2f,%.2f) : %.2f\n", a.x, a.y, b.x, b.y, d);
}else{
printf("不存在最近点对!\n");
}
delete X;return 0;
}