最優二叉搜尋樹
最優二叉搜尋樹
- 背景:語言翻譯,從英語到法語,對於給定的單詞在單詞表裡找到該詞
- 方法:建立一棵二叉搜尋樹,以英語單詞作為關鍵字構建樹
- 目標:儘快地找到英語單詞,使總的搜尋時間儘量少
- 思路:頻繁使用的單詞,如the應儘可能的靠近根;而不經常出現的單詞可以離根遠一點
前提假設:所有元素互異
一些定義:
-
二叉搜尋樹
二叉搜尋樹\(T\)是一棵二元樹,它或者為空,或者其每個結點含有一個可以比較大小的資料元素,且有:
- \(T\)的左子樹的所有元素比根結點中的元素小;
- \(T\)的右子樹的所有元素比根結點中的元素大;
- \(T\)的左子樹和右子樹也是二叉搜尋樹。
-
最優二叉搜尋樹
給定含有\(n\)
搜尋物件\(x\),在\(T\)中可能找到、也可能找不到:
- 若\(x\)等於某個\(k_i\),則一定可以在\(T\)中找到結點\(k_i\),稱為成功搜尋。成功搜尋的情況一共有\(n\)種,分別是\(x\)恰好等於某個\(k_i\)。
- 若\(x<k_1\) 或$ x>k_n$ 或$ k_i<x<k_{i+1} (1\leq i<n)\(, 則在\)
- 為此引入外部結點\(d_0,d_1,...,d_n\),用來表示不在\(K\)中的值,稱為偽關鍵字。
- 偽關鍵字在\(T\)中對應外部結點,共有\(n+1\)個。—擴充套件二叉樹:內結點表示關鍵字\(k_i\),外結點(葉子結點)表示\(d_i\)
- 這裡每個\(d_i\)代表一個區間。\(d_0\)表示所有小於\(k_1\)的值, \(d_n\)表示所有大於\(k_n\)的值,對於\(i=1,…,n-1\),\(d_i\)表示所有在\(k_i\)和\(k_{i+1}\)之間的值。每個\(d_i\)也有一個概率表示搜尋物件x恰好落\(q_i\)入區間\(d_i\)
-
二叉搜尋樹的期望搜尋代價
-
一次搜尋的代價等於從根結點開始訪問結點的數量(包括外部結點)。從根結點開始訪問結點的數量等於結點在\(T\)中的深度\(+ 1\)。記\(depth_T(i)\)為結點\(i\)在\(T\)中的深度。
-
二叉搜尋樹\(T\)的期望代價為:
\[E[search\;cost\;in\;T] = \sum_{i = 1}^{n} (depth_T(k_i) + 1) * p_i + \sum_{i = 0}^{n}(depth_T(d_i) + 1) * q_i\\ = 1 + \sum_{i = 1}^ndepth_T(k_i)*p_i + \sum_{i = 0}^n depth_T(d_i) * q_i \]
-
-
最優二叉搜尋樹
對於給定的關鍵字及其概率集合,期望搜尋代價最小的二叉搜尋樹稱為其最優二叉搜尋樹。
關鍵問題在於確定誰是根:1.樹根不一定是概率最高的關鍵字;2.樹也不一定是最矮的樹;3.該樹的期望搜尋代價必須是最小的。
證明最優二叉搜尋樹的最優子結構:
如果\(T\)是一棵相對於關鍵字\(k_1,…,k_n\)和偽關鍵字\(d_0, …,d_n\)的最優二叉搜尋樹,則\(T\)中一棵包含關鍵字\(k_i,…,k_j\)的子樹\(T'\)必然是相對於關鍵字\(k_i,…,k_j\)(和偽關鍵字\(d_{i-1}, …,d_j\))的最優二叉搜尋子樹。
證明:用剪下-貼上法證明
對關鍵字\(k_i,…,k_j\)和偽關鍵字\(d_{i-1},…,d_j\),如果存在子樹\(T''\),其期望搜尋代價比\(T'\)低,那麼將\(T'\)從\(T\)中刪除,將\(T''\)貼上到相應位置上,則可以得到一棵比\(T\)期望搜尋代價更低的二叉搜尋樹,與\(T\)是最優的假設矛盾。
構造最優二叉搜尋樹
利用最優二叉搜尋樹的最優子結構性來構造最優二叉搜尋樹。
分析: 對給定的關鍵字\(k_i,…,k_j\),若其最優二叉搜尋(子)樹的根結點是\(k_r(i\leq r \leq j)\),則\(k_r\)的左子樹中包含關鍵字\(k_i,…,k_{r-1}\)及偽關鍵字\(d_{i-1} , …,d_{r-1}\),右子樹中將含關鍵字\(k_{i+1},…,k_j\)及偽關鍵字\(d_r,…,d_j\)。
計算過程:求解包含關鍵字\(k_i,...,k_j\)的最優二叉搜尋樹,其中\(i \geq 1 , j \leq n , j \geq i - 1\)。定義\(e[i , j]\)表示包含關鍵字\(k_i , ...,k_j\)的最優二叉搜尋樹的期望搜尋代價,最終解的期望搜尋代價為\(e[1 , n]\)。
-
當\(i \leq j\)時,從\(k_i , ..., k_j\)中選擇出根結點\(k_r\)。其左子樹包含關鍵字\(k_i , ... , k_{r - 1}\)且是最優二叉搜尋子樹;其右子樹包含關鍵字\(k_{r + 1} , ... , k_j\)且同樣為最優二叉搜尋樹。
-
當一棵樹成為另一個結點的子樹時,有以下變化:子樹的每個結點的深度增加\(1\),根據搜尋代價期望值計算公式,子樹對根為\(k_r\)的樹的期望搜尋代價的貢獻是其期望搜尋代價+其所含有結點的概率之和。對於包含關鍵字\(k_i , ... , k_j\)的子樹,所有結點的概率之和為(包含外部結點):\(\omega(i ,j) = \sum_{l = i}^j p_l + \sum_{l= i - 1}^j q_l\) 。
-
若\(k_r\)為包含關鍵字\(k_i , ...,k_j\)的最優二叉搜尋樹的根,則其期望搜尋代價\(e[i , j]\)與左右子樹的期望搜尋代價\(e[i , r - 1]\)和\(e[r + 1 , j]\)的遞推關係式為:
\[e[i , j] = p_r + (e[i , r - 1] + \omega(i , r - 1)) + (e[r + 1 , j] + w(r + 1 , j)) \]其中\(\omega(i , r - 1)\)和\(\omega(r + 1 , j)\)是左右子樹所有結點的概率之和。且有\(\omega(i , j) = \omega(i , r - 1) + p_r + \omega(r + 1 , j)\)
故遞推關係式等價於:\(e[i , j] = e[i , r - 1] + e[r + 1 , j] + w(i , j)\)
總的遞推關係式為:
\[e[i , j] = \begin{cases} q_{i - 1} & j = i - 1\\ min_{i \leq r \leq j} \{e[i , r - 1] + e[r + 1 , j] + w(i , j)\} & i \leq j \end{cases} \] -
邊界條件
上述遞推關係式存在\(e[i , i - 1]\)和\(e[j + 1 , j]\)的邊界情況。此時子樹不包含實際的關鍵字,而只包含偽關鍵字\(d_{i - 1}\),其期望搜尋代價僅為\(e[i , i - 1] = q_{i - 1}\)
-
構造最優二叉搜尋樹
定義\(root[i , j]\),儲存計算\(e[i , j]\)時,使\(e[i, j]\)取得最小值的\(r\),\(k_r\)即為關鍵字\(k_i,…,k_j\)的最優二叉搜尋(子)樹的樹根。在求出\(e[1,n]\)後,利用\(root\)即可構造出最終的最優二叉搜尋樹。
計算最優二叉搜尋樹的期望值
定義三個陣列:
- \(e[1...n + 1 , 0...n]\):用於記錄所有\(e[i , j]\)的值,其中\(e[n + 1 , n]\)表示偽關鍵字\(d_n\)對應的子樹;\(e[1 , 0]\)表示偽關鍵字\(d_0\)對應的子樹
- \(root[1...n]\):用於記錄所有最優二叉搜尋子樹的根節點
- \(\omega[1...n + 1 , 0...n]\):用於儲存子樹的結點的概率之和,且有\(\omega(i , j) = \omega(i , j - 1) + p_j + q _j\),這樣每個\(\omega(i , j)\)的計算時間僅為\(\Theta(1)\)。
虛擬碼:
時間複雜度:\(O(n^3)\)
空間複雜度:\(O(n^2)\)
一個簡單的示例: