编程之美读书笔记2.11—寻找最近点对



思路:首先通过X=M将所有点分为L和R两部分,分别求出两部分的最近点对后,只需考虑CD,x=M-MDis   到y=M+MDis之间的最小点对,如果点对的距离小于MDis,那么在MDis*(2*MDis)的区域内。,最多有8个点。用归并排序法将袋装区域内的点按照Y坐标排序。


<span style="font-family: Arial, Helvetica, sans-serif;">#include <stdio.h></span>
#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 OrderByX(const Point & left,const Point & right){  
		         return     left.x_<right.x_;}
		 static bool OrderByY(const Point & left,const Point & right) { 
		       return     left.y_<right.y_;}

		 int x_;
		 int y_;
};		

float   Distance( const Point& left, const Point& right)   //计算两点距离
{
	     return   sqrt( pow(double(left.x_-right.x_),2)+pow(double(left.y_-right.y_),2)  );
}

int   NearestPoints(const vector<Point> & points , int  start,int end , Point *point1, Point *point2)
{
	if(end>start)
	{
		 int middle=(start+end)/2;
		 int L_Dis=NearestPoints(points,start,middle, point1,point2);
		 int R_Dis=NearestPoints(points,middle+1,end, point1, point2);
		 int Min_Dis=L_Dis<R_Dis ? L_Dis:R_Dis;
       
		 vector<Point> L_Points;      //   left和right之间的点对距离小于min_diantance的点,大于等于不考虑
		 for(int i=start;i<=middle;i++)
		 {
			    if(points[middle].x_-points[i].x_<=Min_Dis)
				      L_Points.push_back(points[i]);
		 }
		 sort(L_Points.begin(),L_Points.end(),Point::OrderByY);

		 vector<Point> R_Points;
		 for(int i=middle+1;i<=end;i++)
		 {
			 if(points[i].x_-points[middle].x_<=Min_Dis)
			            R_Points.push_back(points[i]);
		 }
		 sort(R_Points.begin(),R_Points.end(),Point::OrderByY);

		 int Dis_Y = 0;
		 int point_distance = 0;
		 for(int i=0;i<L_Points.size();i++)      //两点之间距离计算
		 {
			 for(int j=0;j<R_Points.size();j++)
			 {
				  Dis_Y=abs(L_Points[i].y_-R_Points[j].y_);
				 if(Dis_Y<=Min_Dis)
				 {
					 point_distance=Distance(L_Points[i],R_Points[j]);
					 if(point_distance<Min_Dis)
					 {
						 *point1=L_Points[i];
						 *point2=R_Points[j];
						 Min_Dis=point_distance;
				     }
                  }
             }
		 }
        return Min_Dis;
	}
	else
	{
			return    0x7FFFFFFF;
	}
}

int main()
{
	  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(5,0));
	  points.push_back(Point(5,1));
      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_);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值