問題
最優二叉搜索樹(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