1. 程式人生 > 實用技巧 >K-D Tree 學習筆記

K-D Tree 學習筆記

又是一個不需要證明的東西,複雜度基本玄學。
具體來說 K-D Tree 是解決高維問題的一個數據結構(其實一般是二維)。
K-D Tree 本質上是一棵二叉搜尋樹,其的基本思想就是遍歷整個狀態空間加剪枝。
設問題維度是K,其單次查詢的複雜度大概是 \(O(n^{\frac{K-1}{K}})\)

K-D Tree 的建樹方法

我們一般採用每次隨機找一個維度,以這個維度排序,且以這個維度的中位數為根的方法。
這種方法基本上不會被卡。
一般來說我們維度的選擇就是從 1-K 反覆迴圈進行的。

K-D Tree 的查詢方法

這個就具體問題具體分析了,說幾個經典問題吧。

最遠點

找距離一個座標最遠的點。
這個比較簡單,維護每顆子樹裡每一維最大和最小的值,然後一一配對取最大值就可以了。

最近點

這個就比較妙了。
我們依舊維護每顆子樹裡每一維最大和最小的值;
然後對於每一維我們找到理想狀態下距離最近的點,加入答案中。
其實本質上是 A*。
算了,給個程式碼實現吧。

int getmin(int rt, int x, int y, int res = 0) {
    for(register int i = 0; i < 2; ++i) {
	    if(i == 1) x = y;
	    res += max(0, tr[rt].mi[i] - x);
	    res += max(0, x - tr[rt].mx[i]);
	}
    return res; 
}

K遠點

一般來說 K 不會很大。
這個我們可以開個小根堆,初始時堆裡有 K 個元素。
查詢時每次替換最小的那個就可以了。

動態插入

主要利用的是替罪羊的思想。
插入的話我們直接向平衡樹那樣插入就可以了。
維護平衡因子,適時推翻重建以維護平衡。
(暫時沒有寫過)