演算法學習 最優二叉查詢樹(動態規劃)

2021-06-28 04:15:41 字數 3006 閱讀 2734

一、什麼是最優二叉查詢樹

最優二叉查詢樹:

給定n個互異的關鍵字組成的序列k=,且關鍵字有序(k1

圖一顯示了給定上面的概率分布pi、qi,生成的兩個二叉查詢樹的例子。圖二就是在這種情況下一棵最優二叉查詢樹。

概率分布: i

0 1

2 3

4 5

pi 0.15

0.10

0.05

0.10

0.20 qi

0.05

0.10

0.05

0.05

0.05

0.10

已知每個關鍵字以及虛擬鍵被搜尋到的概率,可以計算出乙個給定二叉查詢樹內一次搜尋的期望代價。假設一次搜尋的實際代價為檢查的節點的個數,即所發現的節點的深度加1.計算一次搜尋的期望代價等式為:

建立一棵二叉查詢樹,如果是的上式最小,那麼這棵二叉查詢樹就是最優二叉查詢樹

而且有下式成立:

二、最優二叉查詢樹的最優子結構

最優子結構:

如果一棵最優二叉查詢樹t有一棵包含關鍵字ki,..,kj的子樹t',那麼這可子樹t'對於關鍵字ki,...,kj和虛擬鍵di-1,...dj的子問題也必定是最優的。可以應用剪貼法證明。

根據最優子結構,尋找最優解:

給定關鍵字ki,...,kj,假設kr(i<=r<=j)是包含這些鍵的一棵最優子樹的根。其左子樹包含關鍵字ki,...,kr-1和虛擬鍵di-1,...,dr-1,右子樹包含關鍵字kr+1,...,kj和虛擬鍵dr,...dj。我們檢查所有的候選根kr,就保證可以找到一棵最優二叉查詢樹。

遞迴解:

定義e[i,j]為包含關鍵字ki,...,kj的最優二叉查詢樹的期望代價,最終要計算的是e[1,n]。

當j = i - 1時,此時子樹中只有虛擬鍵,期望搜尋代價為e[i,i - 1] = qi-1.

當j >= i時,需要從ki,...,kj中選擇乙個根kr,然後分別構造其左子樹和右子樹。下面需要計算以kr為根的樹的期望搜尋代價。然後選擇導致最小期望搜尋代價的kr做根。

現在需要考慮的是,當一棵樹成為乙個節點的子樹時,期望搜尋代價怎麼變化?子樹中每個節點深度都增加1.期望搜尋代價增加量為子樹中所有概率的總和。

對一棵關鍵字ki,...,kj的子樹,定義其概率總和為:

因此,以kr為根的子樹的期望搜尋代價為:

因此e[i,j]可以進一步寫為:

這樣推導出最終的遞迴公式為:

三、**實現(c++):

//最優二叉查詢樹  

#include using namespace std;

const int maxval = 9999;

const int n = 5;

//搜尋到根節點和虛擬鍵的概率

double p[n + 1] = ;

double q[n + 1] = ;

int root[n + 1][n + 1];//記錄根節點

double w[n + 2][n + 2];//子樹概率總和

double e[n + 2][n + 2];//子樹期望代價

void optimalbst(double *p,double *q,int n)

//由下到上,由左到右逐步計算

for (int len = 1;len <= n;++len)

} }

} }

//輸出最優二叉查詢樹所有子樹的根

void printroot()

cout << endl;

} cout << endl;

} //列印最優二叉查詢樹的結構

//列印出[i,j]子樹,它是根r的左子樹和右子樹

void printoptimalbst(int i,int j,int r)

if (j < i - 1)

else if (j == i - 1)//遇到虛擬鍵

else

cout << "d" << j << "是" << "k" << r << "的右孩子" << endl;

return;

} else//遇到內部結點

else

cout << "k" << rootchild << "是" << "k" << r << "的右孩子" << endl;

} printoptimalbst(i,rootchild - 1,rootchild);

printoptimalbst(rootchild + 1,j,rootchild);

} int main()

我們將表e、w以及root旋轉45°,便於檢視上述程式的計算過程。上述**核心在於函式optimalbst,其計算順序是從下到上、從左到右。首先是依據概率陣列pi、qi初始化:給最下面的一行賦值。然後是三個for迴圈:從下到上計算表中每一行的值,可以充分利用前面計算出來的結果。如果每當計算e[i][j]的時候都從頭開始計算w[i][j],那麼需要o(j-i)步加法,但是將這些值儲存在表w[1...n+1][0...n]中,就避免這些複雜的計算。

輸出結果:

演算法導論 動態規劃之最優二叉查詢樹

如果我們想寫乙個單詞查詢的軟體的話,我們的目的就是讓查詢的總時間最短,我們首先想到用之前的二叉查詢樹。我們可以用紅黑樹或者其它的平衡二叉樹來保證每個單詞的搜尋時間。但是每個單詞出現的頻率一般不同,因此我們希望把頻率較大的單詞放在離根比較近的地方,頻率較小的放在離葉子較近的地方。而且,我們所要查詢的單...

動態規劃 最優二叉搜尋樹

動態規劃與分治方法類似,都是通過組合子問題來求解原問題。通常用來求解最優化問題,通常按如下4個步驟設計乙個動態規劃演算法 1.刻畫乙個最優解的結構特徵 2.遞迴的定義最優解的值 3.採用自底向上的方法計算最優解的值 4.利用計算出的資訊構造乙個最優解。二叉搜尋樹 optimal binary sea...

最優二叉搜尋樹動態規劃

最優二叉搜尋樹問題是對於有序集s及其訪問概率或權值 q0,p1,q1,p2,q2,p3,q3 在所有表示有序集s的二叉搜尋樹中找出一顆具有最小平均路長的二叉搜尋樹。解決方法 使用動態規劃方法自底向上逐步構造最優二叉搜尋樹。動態規劃的兩個重要要素是 1 最優子結構。2 重疊子問題。1 所謂最優化子結構...