步驟
(一)先將點集按x座標公升序排列(這裡我用的是快速排序)
(二)選取中點將點集分為左右兩部分,求出左側最近點對的距離與右側最近點對的距離進行比較,
當前最短距離取較小值
(三)可能左側點集中某點與右側中某點的距離比第二步中求出的要短,因此將左側點集中每乙個點分別與右側點比較(只用比較橫座標減該點橫座標小於當前記錄最短距離的點)
(四)怎樣找到左側和右側點集的最近點對呢?重複(二)(三)步,將點集劃分成多個最多隻包含三個點的點集。
下面上**:
using system;
using system.threading;
using system.collections.generic;
using system.linq;
using system.text;
using system.threading.tasks;
namespace findclosestpoints
public
point
(int x,
int y)
public
point
(point p)
}///
/// 點對類,記錄點對座標以及點對距離
/// 點對距離預設為無窮大
///
public
class
doublepoints
public
doublepoints
(point p)
public
doublepoints
(point p1,
point p2)
}///
/// 計算兩點距離
///
///
///
///
public
static
double
getdistance
(point a,
point b)
public
static point[
] points;
public
static
doublepoints closestpoints =
newdoublepoints()
;static
void
main
(string
args)
for(
int i =
0; i < pointsnum /
10; i++
) console.
writeline()
;}quicksort
(points,
0, points.length -1)
; console.
writeline()
; console.
writeline
("排序後的點集:");
//*輸出排序後的點集
for(
int i =
0; i < pointsnum /
10; i++
) console.
writeline()
;}getclosedoublepoints(0
, points.length -1)
; console.
writeline
("最近點對為:"
+getpoint
(closestpoints.p1)
+getpoint
(closestpoints.p2)
+"最短距離為:"
+ closestpoints.distance)
; console.
readkey()
;}public
static
string
getpoint
(point p)
///
/// 用快速排序演算法將點集按x座標從小到大排列
///
///
///
///
public
static
void
quicksort
(point[
] points,
int low,
int high)
int first = low, last = high;
point key =
newpoint
(points[first]);
while
(first < last)
points[first]
=new
point
(points[last]);
while
(first < last && points[first]
.x <= key.x)
points[last]
=new
point
(points[first]);
if(tag)
} points[first]
=new
point
(key)
;quicksort
(points, low, first -1)
;quicksort
(points, first +
1, high);}
public
static
int tag =0;
///
/// 分治法求最小距離
///
///
///
public
static
void
getclosedoublepoints
(int first,
int last)
else
}//當區域中有三個點時,將三個點兩兩配對,分別將點對距離與當前最短距離比較
else
if(last - first ==2)
if(getdistance
(points[first]
, points[last]
)< closestpoints.distance)if(
getdistance
(points[first +1]
, points[last]
)< closestpoints.distance)
}//將左邊區域的點與右邊區域點的距離與當前最短距離比較,
//如果這兩點的距離小於當前距離則將當前最小距離改為這兩點距離,並記錄兩點座標
for(
int i = first; i < last +
1; i++)if
(getdistance
(points[i]
, points[j]
)< closestpoints.distance)}}
}}}}
下面是執行結果:
之前踩過快速排序死迴圈(要在迴圈的時候檢測是否有進行操作)和有兩個點橫座標相同時出錯(要在比較大小時把等於帶上),最後的結果只大致看了一下是那麼回事,要是被找出有什麼漏洞歡迎指正。
分治法求最近點對
1 演算法描述 1.分割 將集合s進行以垂直於x軸的直線l進行平均劃分,並且保證sl和sr中的點數目各為n 2,否則以其他方式劃分s,有可能導致sl和sr中點數目乙個為1,乙個為n 1,不利於演算法效率,要盡量保持樹的平衡性 依次找出這兩部分中的最小點對距離 l和 r,記sl和sr中最小點對距離 m...
分治法求最近點對問題
分治法 1 演算法描述 已知集合s中有n個點,分治法的思想就是將s進行拆分,分為2部分求最近點對。演算法每次 選擇一條垂線l,將s拆分左右兩部分為sl和sr l一般取點集s中所有點的中間點的x座標來劃分,這樣可以保證sl和sr中的點數目各為n 2,否則以其他方式劃分s,有 可能導致sl 和sr中點數...
分治法求最近點對問題
1 演算法描述 已知集合s中有n個點,分治法的思想就是將s進行拆分,分為2部分求最近點對。演算法每次 選擇一條垂線l,將s拆分左右兩部分為sl和sr,l一般取點集s中所有點的中間點的x座標來劃分,這樣可以保證sl和sr中的點數目各為n 2,否則以其他方式劃分s,有 可能導致sl 和sr中點數目乙個為...