動態規劃最優二叉搜尋樹

2021-08-27 14:17:04 字數 1815 閱讀 8464

前面的optimal-bst還能寫出來,要去construct就不會了,也是理解不夠深刻的原因吧。以下**的construct用了兩種方法,參照了兩位博主,前乙個**風格非常暴力,能看懂以後寫不出來系列。第二種的d的輸出那我沒有看出邏輯,好像是用的輸出的相鄰兩個下標是在同乙個節點上連著?這個的理由我沒想出來(我也不確定該博主**是否正確,但輸出是對的)。

參照 我在看最優二叉搜尋樹的時候遇到一點問題(現在也覺得沒有很透徹理解這個)

e[i][j]的遞迴式我就看了好一會…..首先聯絡最開始提出的英語翻譯成法語,如果搜尋的內容沒有,也就是書上的d0,d1,d2……,做的處理就是在二維陣列e[i][j]中j=i-1,為什麼搜尋的期望是q[i-1]呢,當j=i-1的時候表示的是沒有真實關鍵字,只有虛擬鍵,那深度就是0,再加一,乘以概率最後就是概率了。當i<=j的時候,我開始就沒想通為什麼後面加個w(i,j),w(i,j)是表示的某子樹的概率和,e[i][j]表示的是期望。在演算法裡面,我們是在找root也就是kr,找到root之後,為這棵樹構造乙個最優的左子樹和最優的右子樹,也就是在左邊和右邊都還要再找乙個root,構造成左子樹和右子樹,這個時候子樹的搜尋代價就變了,子樹中的每個節點深度都增加了1(一棵樹變成乙個結點的子樹時深度+1)。結合搜尋的期望的公式,(深度+1)*p+(深度+1)*q那個公式,可以看出最後就是多了乙個概率和。左子樹的e加上右子樹的e加上乙個w就行了。

還有就是寫construct的時候,不知道怎麼從乙個root得到他的左子樹和右子樹是什麼。

printf(「k%d是k%d的左孩子\n」,root[i][root[i][j]-1],root[i][j]);

printf(「k%d是k%d的右孩子\n」, root[root[i][j] + 1][j], root[i][j]);

其實這一點,看遞推公式那裡就能看出來。

#include "stdafx.h"

#include

#define n 5

int root[n+1][n+1]; //樹根

double e[n + 2][n + 2]; //e是當前的搜尋期望

double w[n + 2][n + 2]; //w是每個子樹上的概率和

double p[n+1] = ; //關鍵字的概率

double q[n+1] = ; //虛擬鍵的概率

void optimal_bst(double *p, double *q)

for (l = 1; l <= n; l++) }}

}}/*

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

if (j < i - 1)

return ;

else

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

else //關鍵字

construct_optimal_bst(child,i,child - 1);

construct_optimal_bst(child,child+1,j);}*/

void construct_optiaml_bst(int root[n+1], int i, int j)

if (i == j)

if (i > j)

printf("d%d是k%d的右孩子\n", j, j);

}int main()

動態規劃 最優二叉搜尋樹

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

最優二叉搜尋樹動態規劃

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

動態規劃之最優二叉搜尋樹

在看這張之前,最好看看我寫的 動態規劃詳解 裡面都是講理論基礎,我下面的分析都是在此基礎上進展的。給定乙個由n個互異的關鍵字組成的序列k k1,k2,kn 且關鍵字有序 因此有k1 k2 kn 從這些關鍵字中構造一棵二叉查詢樹。對每個關鍵字ki,一次搜尋為ki的概率是pi。某些搜尋的值可能不在k內,...