平面上一堆二维坐标点,找其中两点间的最小距离,这个问题网上一大把n log(n) * log(n)的方法,这些算法的典型例子 http://yzmduncan.iteye.com/blog/1432880 ,原因是在求得中心线两边的最小距离s后,都要对处于中线左右两边s距离以内的点按y坐标排序,这种方法不是n log(n)复杂度(参见维斯在“数据结构与算法分析,c语言版”,中文版p281),要是n log(n)复杂度,要在递归之前就对点按y坐标排序,网上少见这种算法的源码,其中一个似乎有些问题的代码见tge7618291的博客 http://blog.csdn.net/tge7618291/article/details/4753126?reload#comments, 但他在递归中反复利用同样两个事先已经按x, y坐标排好序的p, q数组,这样就不用分配新内存,但是不太好理解,另外,更糟糕的是,他的源代码编译后的程序执行,我发现了一组和最普通的n平方算法标准答案不一样的一组数据点,我留言给作者,但作者似乎已经废弃了他的博客。。。
我按照 算法导论和维斯在“数据结构与算法分析,c语言版”上介绍的思想,实现了n log(n)复杂度算法,即:递归之前按x, y坐标排好序X, Y数组, 作为参数,其后每次递归调用里把Y数组中每个点按在中心线的左右两边分成YL, YR子数组(每个子数组仍然按y坐标排序), 把这两个数组分别传人对左右两边的子递归的函数中,而X数组保持不变,这样就比tge7618291的代码好理解,代码如下
// p280_nearestPtPair.cpp : 定义控制台应用程序的入口点。
<pre name="code" class="cpp">// nearPts_ZHENGLI.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "stdafx.h"
#include <stdlib.h>
//#include <iostream>
//#include <cstdio>
//#include <cstring>
#include <cmath>
#include <stack>
#include <list>
using namespace std;
// 似乎http://blog.csdn.net/lu1012123053/article/details/9825175方法也是n log(n)算法 ,但没细看
// 下面方法部分代码 参考了 http://blog.csdn.net/tge7618291/article/details/4753126?reload#comments
#define min(a,b) (((a) < (b)) ? (a) : (b))
typedef struct _Point {
double x;
double y;
// Point(double a, double b):x(a), y(b) {}
} Point;
typedef struct _PointMap {
Point point;
int index; /* 这个成员的作用见文章后边的解释 */
#define poi_x point.x
#define poi_y point.y
} PointMap;
const double EPS=0.00000000001;
const double MAXDIS=9e300;
static double Dis( PointMap po1, PointMap po2 ) /* 返回距离的平方和 */
{
double xdis = po1.poi_x - po2.poi_x;
double ydis = po1.poi_y - po2.poi_y;
return xdis * xdis + ydis * ydis;
}
//n * n的方法,这个方法算出来的应该是标准答案
double n2MinDis( const PointMap M[], int n )
{
//assert( n >= 1 );
if ( n == 1 )
return 0.0;
int i, j;
pair<Point, Point> pt2;
stack<pair<Point, Point>> stk;
double mindis = MAXDIS, tmp;
for ( i = 0; i < n;