java最近点对分治算法_分治算法——最近点对问题

#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;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值