爲什麼在這裏介紹最爲基礎的數據結構“樹”呢?
因爲在最近鄰算法中樹有很重要的作用。首先回顧一下二叉樹:
二叉樹
二叉樹是每個結點最多有兩個子樹的樹結構。通常子樹被稱作“左子樹”和“右子樹”。二叉樹常被用於實現二叉查找樹和二叉堆。一張圖快速理解二叉樹:
二叉樹的搜索和構造就不再這裏介紹了,大家可以參考這篇文章。link
K-D樹
爲什麼在上一節介紹二叉樹?因爲K-D樹是每個節點都爲k維點的二叉樹。是一種對K維空間內的實例點進行存儲,以便對其進行快速的搜索的方法。構造K-D 樹相當於不斷的用垂直與座標軸的超平面將K維空間切分。K-D樹的每個節點對應一個K維超矩形區域。很拗口?來個例子吧
例子
一個二維數據集
- (1)選擇軸的6個數據點2,4,5,7,8,9的中位數7,分爲兩個矩形。(這裏需要看下源代碼,理解下這裏的中位數)
point_list.sort(key=itemgetter(axis))
median = len(point_list) // 2 # choose median
location=point_list[median]
- (2)左矩形以軸4分爲兩個子矩形,右矩形以分爲兩個子矩形。
- (3)遞歸哈劃分,直到完成。
如何構造KD樹?
具體的算法流程如下所是:
輸入: K維空間的數據集
輸出: KD樹
- 構造根節點,根節點對應與包含的K維空間的超矩形區域。以的中位數且分爲兩個矩形區域,
- 重複切分步驟
- 直到兩個子區域沒有且分點爲止。
K-D樹搜索
輸入: KD樹,目標點
輸出: KD樹
- 在KD樹中找到包含目標點的葉節點。從根節點出發,遞歸的向下訪問KD樹。若目標點x維當前的座標小於切分的的座標,則移動到左節點,否則到右節點。
- 以此節點爲當前的最近點。
- 遞歸的向上回退。