3. 資料測試
如果我們作為中·華·有·為的hr,想要給那些年齡在20到35歲且年薪要求在10k~20k的技術人員傳送面試邀請……這類問題就叫做二維範圍查詢two-dimensional range query
。
如果只有一維的情況,我們可以通過遞迴遍歷預先構造的二叉查詢樹來解決。但是對於二維或者更高維的情況,就需要新的資料結構。
二維查詢樹two-dimensional search tree
具有簡單的性質:奇數層的分支按照第乙個鍵進行,偶數層的分支按照第二個鍵進行;根是任意選取的奇數層。對於k維的情況,同樣的做法依然成立,通過每層的鍵進行。下圖就是一棵2-d樹:
結點的基本項假設是乙個兩個元素的陣列。另外,我們允許重複元的出現,並總把它們放在右分支。
template
<
typename comparable>
class
kdtree};
kdnode *root;
};
2-d樹的插入操作是二叉查詢樹插入操作的簡單擴充套件,沿著樹下行的時候,我們保留當前的層數資訊,如果是奇數層,就對第0個元素進行鍵值比較;是偶數層,就對第1個元素進行鍵值比較。
私有方法和公共介面如下:
//插入的公共介面
void
insert
(const vector
&x)//私有方法, 進行插入
void
insert
(const vector
&x, kdnode *
&t,int level)
很容易就能發現,隨機構造的2-d樹和隨機二叉查詢樹具有同樣的結構化性質:高度平均為 o
(logn
)o(\log n)
o(logn
) ,但是最壞是 o(n
)o(n)
o(n)
。另外,不存在已知的樹旋轉方案保證一棵平衡的2-d樹,基於樹旋轉的方法在2-d樹中行不通。最好的方法是定期重構子樹來保持平衡。而且,也不存在超越懶惰刪除方法的刪除演算法。
2-d樹上可以進行的查詢有幾種:精確的匹配或者基於兩個鍵之一的匹配(部分匹配查詢partial match query
) 。這兩種都是(正交)範圍匹配range query
的特殊情形。
因此我們只完成正交範圍查詢的函式——它將給出第乙個鍵在乙個特頂的值集合之間且第二個鍵在另乙個特定的值集合之間的所有項。範圍查詢通過一次遞迴的樹遍歷就可以完成:
/**
* 列印滿足下列條件的項
* low[0] <= x[0] <= high[0] && low[1] <= x[1] <= high[1]
*/void
printrange
(const vector
&low,
const vector
&high)
const
//列印範圍
void
printrange
(const vector
&low,
const vector
&high,
kdnode *t,
int level)
const
}
如果想找到特定的項,可以讓兩個鍵值的low
都等於high
並且等於要查詢的項的對應鍵值;如果想執行部分匹配查詢,讓這次匹配涉及不到的鍵的值範圍為 −∞→
∞-\infin \to \infin
−∞→∞
,而其餘的範圍,則設定低點和高點等於匹配中涉及到的鍵的值。
#include
using
namespace std;
intmain()
vector<
int>
low(2)
,high(2
);low[0]
=70; low[1]
=2186
; high[0]
=1000
; high[1]
=2200
; t.
printrange
(low, high)
;return0;
}
執行如下:
資料結構與演算法 樹專題
pass 2.1 二叉樹下乙個節點 coding utf 8 class treelinknode def init self,x self.val x self.left none self.right none self.next none class solution def getnext ...
( 資料結構專題 ) 權值線段樹
資料結構專題 權值線段樹 學習權值線段樹,首先要了解線段樹是什麼。如果不會的可以先學習一下。權值線段樹,顧名思義是一棵線段樹。但它和普通線段樹不同 線段樹,每個節點用來維護一段區間的最大值或總和等。權值線段樹,相當於乙個桶,每個節點用來表示乙個區間的數出現的次數。我們可以用它來維護一段區間的數出現的...
線段樹 資料結構專題學習
這兩周是資料結構專題的學習,被專題的題目虐得死去活來 線段樹 簡單的說就是把 1,n 的區間二分,1,1 n 2 左子樹,1 n 2 1,n 右子樹 就這樣一直分下去,直到都是 x,x 這樣的區間。這樣就構成了一顆樹了 有這樣一棵樹,我們就可以在節點中儲存區間的和啊,區間內的最大值啊,最小值等等。這...