分:递归解决较小的问题
治:从子问题构建原问题的解
分治算法的时间:
定理1:方程的解是:
证明用叠缩求和法
定理2:方程的解是
定理3:若,则方程
的解是
证明:使用数学归纳法,这个方程的意义是,若将原问题分解成若干不到原问题100%的若干个子问题加上合并子问题的线性时间,那么算法时间是
最近点问题:输入平面上的点列P,若,
,那么两点之间的欧几里得距离是
,找出一对最近的点
一种显然的方法是遍历所有点对距离,时间是
若先对x坐标排序,那么花费时间是,对于要证明总时间是
,不增加时间界
分解问题如下:在二位坐标系中画一条想象的垂线P,将所有点按照x坐标分成左右两个部分和
,那么距离最近的点对要么在左边,要么在右边,要么一个在左边一个在右边,这就是一个典型的分治问题,由于想要
解,因此只能用线性附加时间计算横跨左右的这种距离。
设,若
对
有改进,那么一定在P左右的
的带状区域中,这就减少了需要考虑的横跨左右的点,平均在带状区域中的点的数量是
,因为想象N个点落在一个单位格子中,那么最均匀的分布是,长和宽都是
个点,从而让两点之间最小值的最大值为
,这就是带状区域的宽,其中的点数量就是
,即
,因此可以用O(N)时间进行蛮力计算,代码如下:
for (i = 0; i < N; i++)
for (j = i + 1; j < NumPointsInStrip; i++)
if (Dist(Pi, Pj) < ans)
ans = Dist(Pi, Pj);
在最坏的情况下,可能所有点都在带状区域中,就不能保证时间了,可以改进到最坏
时间,方法是对y坐标排序,代码如下:
for (i = 0; i < NumPointsInStrip; i++)
for (j = i + 1; j < NumPointsInStrip; j++)
if (Pj and Pi's coordinates differ by more than ans)
break;
else if (Dist(Pi, Pj) < ans)
ans = Dist(Pi, Pj);
内层循环只有常数个节点需要被考虑,因此是线性时间