1. 程式人生 > 其它 >最優二叉搜尋樹

最優二叉搜尋樹

最優二叉搜尋樹

  • 背景:語言翻譯,從英語到法語,對於給定的單詞在單詞表裡找到該詞
  • 方法:建立一棵二叉搜尋樹,以英語單詞作為關鍵字構建樹
  • 目標:儘快地找到英語單詞,使總的搜尋時間儘量少
  • 思路:頻繁使用的單詞,如the應儘可能的靠近根;而不經常出現的單詞可以離根遠一點

前提假設:所有元素互異

一些定義:

  • 二叉搜尋樹

    二叉搜尋樹\(T\)是一棵二元樹,它或者為空,或者其每個結點含有一個可以比較大小的資料元素,且有:

    • \(T\)的左子樹的所有元素比根結點中的元素小;
    • \(T\)的右子樹的所有元素比根結點中的元素大;
    • \(T\)的左子樹和右子樹也是二叉搜尋樹。
  • 最優二叉搜尋樹

    給定含有\(n\)

    個關鍵字的已排序的序列\(K=<k_1,k_2,…,k_n>\)(不失一般性,設 \(k_1<k_2<…<k_n\)),對每個關鍵字\(k_i\),都有一個概率\(p_i\)表示其被搜尋的頻率。根據\(k_i\)\(p_i\)構建一個二叉搜尋樹\(T\),每個\(k_i\)對應樹中的一個結點。

    搜尋物件\(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)\(, 則在\)
      T\(中搜索\)x$將失敗,稱為失敗搜尋。
      • 為此引入外部結點\(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]\)

  1. \(i \leq j\)時,從\(k_i , ..., k_j\)中選擇出根結點\(k_r\)。其左子樹包含關鍵字\(k_i , ... , k_{r - 1}\)且是最優二叉搜尋子樹;其右子樹包含關鍵字\(k_{r + 1} , ... , k_j\)且同樣為最優二叉搜尋樹。

  2. 當一棵樹成為另一個結點的子樹時,有以下變化:子樹的每個結點的深度增加\(1\),根據搜尋代價期望值計算公式,子樹對根為\(k_r\)的樹的期望搜尋代價的貢獻是其期望搜尋代價+其所含有結點的概率之和。對於包含關鍵字\(k_i , ... , k_j\)的子樹,所有結點的概率之和為(包含外部結點):\(\omega(i ,j) = \sum_{l = i}^j p_l + \sum_{l= i - 1}^j q_l\)

  3. \(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} \]
  4. 邊界條件

    上述遞推關係式存在\(e[i , i - 1]\)\(e[j + 1 , j]\)的邊界情況。此時子樹不包含實際的關鍵字,而只包含偽關鍵字\(d_{i - 1}\),其期望搜尋代價僅為\(e[i , i - 1] = q_{i - 1}\)

  5. 構造最優二叉搜尋樹

    定義\(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)\)
一個簡單的示例: