最近点问题属于典型的分治法解决办法,通过不断的迭代,将群体点分为 更多的小块。从而将算法复杂度从 O(n*n) 变为 O(n*log(n))算法。
但是在java实现最近点问题时,会涉及到泛型, 队列,比较器,java自带的Collections的自带的快速排序算法实现,具体的代码如下:
package comAlgorithm;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
// 用java数据结构计算 最近点距离,一定要计算出来
// 从这个程序可以看出,对于基本的java的集合使用还是非常的不熟练,需要更多的技巧来进行学习,进行专业加深
public class ShortestDistance {
public static void main(String[] args) {
// TODO Auto-generated method stub
ArrayList<Point> set = new ArrayList<Point>();
set.add(new Point(2,3));
set.add(new Point(4,6));
set.add(new Point(5,4));
set.add(new Point(6,6));
set.add(new Point(4.5,6));
set.add(new Point(6,5.6));
// 对点进行 按照x轴大小的排序,使用接口器ComparableXPoint()
Collections.sort(set, new CompareXPoint());
double distance = find(set);
System.out.println("the distance is" + distance);
}
static double find(ArrayList<Point> set){
double distance;
//最小情况讨论分析
if(set.size() == 2)
{
distance = Point.calculate(set.get(0),set.get(1));
return distance;
}
if(set.size() == 3 )
{
double distance1 = Point.calculate(set.get(0), set.get(1));
double distance2 = Point.calculate(set.get(1), set.get(2));
return min(Point.calculate(set.get(0), set.get(2)),min(distance1,distance2));
}
int mid = set.size()/2;
ArrayList<Point> leftSet = new ArrayList<Point>();
// 这边要小心了 i<mid 而不是 i <=mid
for(int i=0; i<mid; i++)
leftSet.add(set.get(i));
// 构造右边的集合
ArrayList<Point> rightSet = new ArrayList<Point>(); // 注意声明 和 赋值的不同点,什么才是幅值
for(int i=mid; i<set.size(); i++)
rightSet.add(set.get(i));
// 递归计算左集合 和 右集合,然后统计两边的最小的距离
distance = min(find(leftSet),find(rightSet));
// 对于剩下的点进行排序
ArrayList<Point> pleft = new ArrayList<Point>();
ArrayList<Point> pright = new ArrayList<Point>();
for(Point p:leftSet){
if(Math.abs(p.x - set.get(mid).x) <= distance)
pleft.add(p);
}
for(Point p:rightSet){
if(Math.abs(p.x-set.get(mid).x) <= distance )
pright.add(p);
}
// 根据y坐标进行两边的排序
Collections.sort(pleft, new CompareYPoint());
Collections.sort(pright, new CompareYPoint());
int r=0; // 右边小区域的点的集合
for(Point p:pleft){
while(r<pright.size() ){
if(Math.abs(p.y - pright.get(r).y)<distance){
if(Point.calculate(p,pright.get(r))<distance)
{
distance = Point.calculate(p,pright.get(r));
}
}
r++;
}
}
return distance;
}
static double min(double x1, double x2){
return x1<x2? x1:x2;
}
}
class Point{
double x;
double y;
public Point(double x, double y){
this.x = x;
this.y = y;
}
static double calculate(Point p1, Point p2){
return Math.sqrt(Math.pow(p1.x-p2.x, 2)+Math.pow(p1.y-p2.y, 2));
}
}
// 定义一个比较器接口 -- 比较x横向的点 --
class CompareXPoint implements Comparator<Point>{
@Override
public int compare(Point o1, Point o2) {
// TODO Auto-generated method stub
if(o1.x>o2.x)
return 1;
else if(o1.x == o2.x)
return 0;
else
return -1;
}
}
// 比较器接口 -- 纵向使用y进行比较器接口
class CompareYPoint implements Comparator<Point>{
@Override
public int compare(Point o1, Point o2) {
// TODO Auto-generated method stub
if(o1.y>o2.y)
return 1;
else if(o1.y == o2.y)
return 0;
else
return -1;
}
}