多維檢索樹KD Tree

2022-05-02 21:06:06 字數 2248 閱讀 7789

k

維檢索樹類似於二叉檢索樹,不同的是,它能同時提供多維度屬性的檢索。

k維(從

0開始計維數)檢索樹的定義:

k維檢索樹是乙個

n層的二叉樹(根節點為第

0層,依次往下為第

1,2..n-1

層),對於樹中第

n層的每個節點,其左子樹所有節點的第

n%k維屬性小於或等於該節點的第

n%k維屬性;其右子樹所有節點的第

n%k維屬性都大於或等於該節點的第

n%k維屬性。通俗的講,就是將整個樹的層數迴圈標記為0到

k-1,在第

0層比較第

0為屬性,在第

1層比較第

1層屬性,依此類推。

假設a-g

代表二維空間的點(由

x,y二維座標標示

),則依次插入

a-g節點到樹中會構成如下所示的樹。

插入a樹為空,

a作為根節點

插入b

與a比較第0

維屬性,進入左子樹,左子樹為空,直接插入

插入c

與a比較第0

維屬性,進入右子樹,右子樹為空,直接插入

插入d

與a比較第0

維屬性,進入左子樹,與

b比較第

1維屬性,進入左子樹…

插入e 與

a比較第

0維屬性,進入左子樹,與

b比較第

1維屬性,進入右子樹…

插入f 與

a比較第

0維屬性,進入右子樹,與

c比較第

1維屬性,進入右子樹…

插入g 與

a比較第

0維屬性,進入左子樹,與

b比較第

1維屬性,進入左子樹,與d

比較第0

維屬性,進入左子樹…

演算法時間複雜度:

查詢:從根節點逐層比較,直到遇到目標或者子樹為空,時間複雜度為

o(logn)

插入:從根節點逐層比較,按照定義的規則直到遇到葉子節點,時間複雜度為

o(logn)

刪除:對於葉子節點,或只有單分支子樹的節點,直接刪除,否則找到右子樹的最左節點或左子樹的最右節點,替換掉被刪節點,演算法複雜度

o(logn)

優化:將樹優化為平衡樹,將樹的節點匯出至

vector

中,並清空樹,將

vector

集合按第一維屬性,分成兩堆,左邊比中間元素小,右邊比中間元素大(

nth-element

),將中間元素插入到樹中,遞迴將左右兩堆的元素插入到左子樹、右子樹(比較時根據層數比較對應的維度值)。優化的時間複雜度為o(

nlogn

)。區間查詢:從根節點起,檢查根節點是否符合條件,如果符合加入至結果集中;如果左子樹跟目標區間有交集,遞迴查詢左子樹;如果右子樹跟目標區間有交集,查詢右子樹。(設定乙個動態區間,初始時與目標區間相同,進入左子樹,則要更新動態區間對應維度的上限;若進入右子樹,則要更新動態區間對應維度的上限;通過判斷動態和目標區間是否有交集可以看出需要進入左右子樹,從而減少查詢空間)。

更詳細的了解參考**:

multidimensional binary search trees used for associative searching

libkdtree++是乙個

c++實現的

kdtree lib

,提供了

insert

、erase

、optimise

、find_exact

、find_within_range

、find_nearest

等介面。

find_with_range(val, range, outputiterator)

不能滿足需求,因只能指定每維屬性在

val[k] – range

到val[k] +

range

的範圍內。因為需要支援任意區間查詢,而

kdtree++

沒有提供

需要的介面,我在

kdtree

的實現中增加了

find_within_range(vmin,

vmax, outputiterator)

介面,同時需要給

region

新增乙個建構函式。

檢索樹 刪除演算法

為了記錄下檢索樹刪除演算法,我來發個部落格開心一下。如何刪除檢索樹中的元素?想要刪除檢索樹中的結點,步驟 找到要刪除結點 刪除結點 if x q data 向左搜尋 else 向右搜尋 if p 未找到 return 0 if p rson p沒有右兒子,用左兒子代替p else 如果p是其父結點的...

k近鄰法中kd tree樹的建立

經過一天努力實現了kd tree樹二維的建立,但是 只適用於二維,這是令人遺憾的地方。在這個過程中學到了不少東西,特別是對vector的一些用法,多了更多的了解。思路 建立樹時,傳遞vector為形參,以第n 2維為變數,對結構體vector排序,找出中位數,奇數找中間,偶數取第 n 2 1個,以它...

離散化 和多維線段樹

分類 練習 2013 05 25 10 07 196人閱讀收藏 舉報 acmc 資料結構 離散化 題目大意 給出 n 個矩形的 左下 和 右上 頂點座標,求面積並 思路 由於座標值為實數,所以不能直接用陣列模擬,要先將所有座標值離散化處理 cpp view plain copy print?incl...