1. 程式人生 > 其它 >最優二叉搜尋樹(Optimal Binary Search Tree)

最優二叉搜尋樹(Optimal Binary Search Tree)

問題

最優二叉搜尋樹(Optimal Binary Search Tree,Optimal BST)問題,形式化定義:給定一個n個不同關鍵字的已排序的序列K=<k1, k2, ..., kn>(k1<k2<...<kn),用這些關鍵字構造一棵二叉搜尋樹 —— 對每個關鍵字ki,都有一個概率pi表示其搜尋頻率。對於不在K中的搜尋值構造n+1個”偽關鍵字“d0, d1, d2, ..., dn —— 偽關鍵字di表示所有在ki和ki+1之間的值(i=1,2,...,n-1,d0表示所有小於k1的值,dn表示所有大於kn的值),每個偽關鍵字di對應一個概率qi(搜尋頻率)。 

例如,對一個n=5的關鍵字集合及如下的搜尋頻率,構造二叉搜尋樹。逐點計算的期望搜尋耗費(contribution = (depth + 1) * probability)如右下表,從表中得到k5的搜尋概率最高,根節點是k2

二叉樹搜尋樹的期望耗費:

思路

  • 步驟1:最優二叉搜尋樹的結構,如果一顆最優二叉搜尋樹T有一顆包含關鍵字ki, ..., kj的子樹T',那麼T'必然是包含ki, ..., kj和偽關鍵字di-1, ..., dj的子問題最優解。
  • 步驟2:一個遞迴式,定義w(i, j)是包含關鍵字ki, ..., kj的子樹所有概率之和,e[i, j]為期望耗費,則...

 

 

  • 步驟3:計算最優二叉搜尋樹的期望代價。

實現

def optimal_bst(p,q,n):
    e=[[0 for j in range(n+1)]for i in range(n+2)]
    w=[[0 for j in range(n+1)]for i in range(n+2)]
    root=[[0 for j in range(n+1)]for i in range(n+1)]
    for i in range(n+2):
        e[i][i-1]=q[i-1]
        w[i][i-1]=q[i-1]
    for l in range(1,n+1):
        
for i in range(1,n-l+2): j=i+l-1 e[i][j]=float("inf") w[i][j]=w[i][j-1]+p[j]+q[j] for r in range(i,j+1): t=e[i][r-1]+e[r+1][j]+w[i][j] if t<e[i][j]: e[i][j]=t root[i][j]=r return e,root if __name__=="__main__": p=[0,0.15,0.1,0.05,0.1,0.2] q=[0.05,0.1,0.05,0.05,0.05,0.1] e,root=optimal_bst(p,q,5) for i in range(5+2): for j in range(5+1): print(e[i][j]," ",end='') print() for i in range(5+1): for j in range(5+1): print(root[i][j]," ",end='') print()

時間複雜度:T(n)=O(n3)
空間複雜度:S(n)=O(n2)

程式碼引自:演算法導論程式39--最優二叉搜尋樹(Python)_夜空霓虹的部落格-CSDN部落格_最優二叉搜尋樹python