数据结构之分治法(最短距离)-(十一)

来源:互联网 发布:c语言编译器安卓手机 编辑:程序博客网 时间:2024/06/07 05:25
package com.lip.datastructure;/** * @author lip * 分治法,所谓分治当然是分而治之,化整为零。 * 分治法分为两部分,1.分(Divide)2.治(Conquer) * 在排序算法中我们用到的二分排序就是分治法最经典的一个例子 * 传统的分治法要运行两次及其以上的递归算法,一般用分治法解决问题的时间复杂度是O(N*lgN) */public class DivideAndConquer{        /*求平面上两个点的最短距离         * 方法一:就是两个for循环求得任意两点间的距离,然后去取得最小值,毫无疑问时间复杂度O(N^2)(N*(N-1)/2)         * 方法二:就是分治法。         * 思路:假设平面上点已经按照x和y的大小顺序排序分布在平面上,有一条y=k的线把平面分为两部分,那么最短距离d存在这三种可能。         *   1.k线的左侧,最小值dleft         *   2.k线的右侧,最小值dright         *   3.一个点p1在k线的左侧,一个点p2在k线的右侧,并且(p1.x-p2.x)<min{dleft,dright}         *   (如果大于那最小值就在最左侧或者右侧了,那么最小值取min{dleft,dright})         */public static void main(String[] args){Point p1=new Point(1, 1);Point p2=new Point(2, 5);Point p3=new Point(2, 2);Point p4=new Point(4, 6);Point p5=new Point(5, 8);Point p6=new Point(6, 6);Point p7=new Point(4, 2);Point p8=new Point(5, 2);Point p9=new Point(7, 4);Point[]points={p1,p2,p3,p4,p5,p6,p7,p8,p9};System.out.println(getMinDistance(points, 0, 8));}/**  * @param start * @param end * @return start,end范围内两个相聚最近的点 */ public static double getMinDistance(Point []points,int start,int end) { //如果只有1个或者两个元素,那么直接计算距离 if(start==end) return Integer.MAX_VALUE; else if(start+1==end) return points[start].toPoint(points[end]); int mid=(end+start)/2; double minLeft=getMinDistance(points, start, mid); double minRight=getMinDistance(points, mid+1, end); double len=minLeft<minRight?minLeft:minRight; double minCenter=Integer.MAX_VALUE; for(int i=start;i<=mid;i++) {      if(points[mid].getX()-points[i].getX()>len)      break;  for(int j=mid+1;j<=end;j++) { if(points[j].getX()-points[mid].getX()>len) break; double temp=points[i].toPoint(points[j]); if(minCenter>temp) minCenter=temp; } }  return getMin(minCenter, minLeft, minRight); } //得到三个值中的最小值 public static double getMin(double a,double b,double c) { if(a<=b&&a<=c) return a; else if(b<=a&&b<=c) return b; else if(c<=a&&c<=b) return c; return -1; }}class Point{private int x;private int y;public int getX(){return x;}public void setX(int x){this.x = x;}public int getY(){return y;}public void setY(int y){this.y = y;}public Point(int x,int y){this.x=x;this.y=y;}/** * @param p * @return 返回到一个点的距离 */public double toPoint(Point p){return  Math.sqrt((p.x-this.x)*(p.x-this.x)+(p.y-this.y)*(p.y-this.y));}}
1 0