- 问题
n个点在公共空间中,求出所有点对的欧几里得距离最小的点对。 - 解析
当2<=n<=3,通过蛮力算法求解;当n>3,对所有的点按照坐标从小到大排序,利用点集在坐标方向的中位数m,在该处做一条垂线,将点集分为n/2和n/2两个子集P1和Pr,对左右两个部分分别求最近点对的距离d,然后进行合并。最近距离不一定存在于两个集合中,可能一个点在P1,一个点在Pr,而这两点间距离小于d。 - 设计
double partition(node p[],int left,int right)
{
//2<=n<=3则暴力求解
if(right - left == 1){
return dis(p[left],p[right]);
}
if(right - left == 2){
double d1 = dis(p[left],p[left+1]);
double d2 = dis(p[left],p[right]);
double d3 = dis(p[left+1],p[right]);
d2 = min(d1,d2);
d3 = min(d2,d3);
return d3;
}
//n>3时,分治法求解
int m = (left + right)/2;
double d1 = partition(p,left,m);
double d2 = partition(p,m+1,right);
double d = min(d1,d2);
int l=left,r=right;
//筛选中间可能距离最小的坐标
while(p[l].x<p[m].x-d && l<=right){
l++;
}
while(p[r].x>p[m].x+d && l<=left){
r–;
}
double d3;
//将筛选后的点以y坐标从小到大排序
sort(p+l,p+r+1,compare2);
for(int i=l;i<r;i++){
for(int j=i+1;j<r;j++){
//筛选中间可能距离最小的坐标
if(p[j].y-p[i].y > d){
break;
}
else{
d3 = dis(p[i],p[j]);
if(d3 < d){
d = d3;
}
}
}
}
} - 分析
暴力求解,时间复杂度为O ( n 2 )
分治法求解,时间复杂度O ( nlogn)
源码
https://github.com/DicHui/DicHui/tree/main
最近对问题
最新推荐文章于 2022-03-24 13:48:40 发布