寻找最近点对

具体分析见编程之美解法三,借鉴网上的代码,但其有错误,再次修正。
代码如下:

#include <stdio.h>  
#include <algorithm>  
#include <vector>  
#include <math.h>  
#include <stdio.h>  
#include <algorithm>  
#include <vector>  
#include <math.h>  


using namespace std;
class Point 
{  
public:
    Point(int x,int y):x_(x),y_(y){}
    Point():x_(0),y_(0){}
    static bool OrderByY(const Point &left,const Point &right)
    {
        return left.y_ < right.y_;
    }
    static bool OrderByX(const Point &left,const Point &right)
    {
        return left.x_ < right.x_;
    }
public:
    int x_;
    int y_;
};  
double Distance(const Point& left, const Point& right) 
{  
    return (sqrt(pow((double)(left.x_-right.x_),2) + pow((double)(left.y_-right.y_),2)));
}  
//采用分治归并思想求多点之间的最小距离=min(left最小距离,right最小距离,left和right分别对应的最靠近的点的距离)
//left和right分别对应的最靠近的点的距离只可能出现在min_distance * (2*min_distance)的区域内,min_distance为纵座标长度,
//2*min_distance横座标长度,以min_distance为原点。

double NearestPoints(const vector<Point>& points, int start, int end, Point *point1, Point *point2) 
{  
    if(end > start)
    {
        int middle = (start + end) / 2;
        Point point1_l,point2_l,point1_r,point2_r;
        double left_distance = NearestPoints(points,start,middle,&point1_l,&point2_l);//保留左边最小值的座标对
        double right_distance = NearestPoints(points,middle+1,end,&point1_r,&point2_r);//保留右边最小值的座标对
        double min_distance = left_distance > right_distance ? right_distance : left_distance;
        if(left_distance > right_distance)
        {
             *point1 = point1_r;
             *point2 = point2_r;
        }               //暂时保留的是除了中间带状区域的最小距离的座标对
        else
        {
             *point1 = point1_l;
             *point2 = point2_l;
        }
        vector<Point> left_part_points;
        for(int i = start;i <= middle;++i)
        {
            if(points[middle].x_-points[i].x_ <= min_distance)
                left_part_points.push_back(points[i]);
        }
        sort(left_part_points.begin(),left_part_points.end(),Point::OrderByY);
        vector<Point> right_part_points;
        for(int i = middle+1;i <= end;++i)
        {
            if(points[i].x_ - points[middle].x_ <= min_distance)
                right_part_points.push_back(points[i]);
        }
        sort(right_part_points.begin(),right_part_points.end(),Point::OrderByY);
        int distance_y = 0;
        double d = 0;
        for(int i = 0;i < left_part_points.size();++i)
        {
            for(int j = 0;j < right_part_points.size();++j)
            {
                 distance_y= left_part_points[i].y_ > right_part_points[j].y_ ? left_part_points[i].y_ - right_part_points[j].y_ 
                    : right_part_points[j].y_ - left_part_points[i].y_;//使两个点的相对座标要在min_distance之内
                if(distance_y <= min_distance)
                {
                    d = Distance(left_part_points[i],right_part_points[j]);
                    if(d < min_distance)
                    {
                        min_distance = d;
                        *point1 = left_part_points[i];
                        *point2 = right_part_points[j];
                    }
                }
            }
        }
        return min_distance;
    }
    else
        return 0x7FFFFFFF;
}  



int main() 
{  
  std::vector<Point> points;  
  points.push_back(Point(2,3));  
  points.push_back(Point(1,4));  
  points.push_back(Point(3,0));  
  points.push_back(Point(1,5));  
  points.push_back(Point(0,5));  
  sort(points.begin(), points.end(), Point::OrderByX);  
  Point point1;  
  Point point2;  
  NearestPoints(points, 0, points.size() - 1, &point1, &point2);  
  printf("Point1: (%d, %d) <--> Point2: (%d, %d)\n", point1.x_, point1.y_, point2.x_, point2.y_);  
  system("pause");
}  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章