0x07算法设计与分析复习(二):算法设计策略-动态规划法4
算法设计策略-动态规划法
分类:
IT文章
•
2024-03-22 18:36:48
参考书籍:算法设计与分析——C++语言描述(第二版)
最优二叉搜索树
问题描述
二叉搜索树运算有很好的平均时间复杂度(。
以上分析均假定二叉搜索树上搜索一个元素的概率是相等的。如果元素集合是固定的,并且已知搜索集合中每个元素的概率,包括不成功的概率,那么可以构造一颗最优二叉搜索树,使其具有最小的平均搜索时间。
设有元素集合)。显然:
最优二叉搜索树问题是指设法构造一颗具有最小平均搜索时间的二叉搜索树。
动态规划法求解
最优子结构
已知递增有序的元素集合的左子树和右子树,它们应当都是最优二叉搜索树。
与二分搜索的二叉判定树类似,每个内结点代表一次成功搜索可能的终止位置,每个外结点表示一次成功搜索可能的终止位置,每个外结点表示一次不成功搜索的终止位置。设
假定
式中,
。
定义
二叉搜索树T的平均搜索代价
从上式可以知道,如果T是最优二叉搜索树,必定要求其左右子树都是二叉搜索树,否则T就不是最优的。这表明,队医最优二叉搜索树问题,最优性原理成立。
设
一般,
式中,分别是左右子树的平均搜索代价。上式建立了原问题最优解和子问题最优解之间的数值关系,建立这一关系是动态规划求解问题时必须的和关键的一步。
构造最优二叉搜索树
设w、c和r是上面定义的3个二维数组,计算此3个量,便可以从中得到最优二叉搜索树。运用动态规划法求解这三个量的递推算法如下:
-
计算主对角线的w、c和r的值
-
计算紧邻主对角线上面的那条对角线的w、c和r的值
-
根据下列公式,计算主对角线以上n-2条斜线的w、c和r的值
最优二叉搜索树算法
一维数组p和q保存成功和不成功搜索的两种概率,n是数组长度,计算结果保存在二维数组w、c和r的值。函数Find计算满足的k值。函数CreateOBST调用Find计算w、c和r。最后根据r的值可以构造所求得的最优二叉搜索树。
//构造最优二叉搜索树
int Find(int i,int j,int **r,float **c)
{
float min=INFTY;
int k;
for(int m = i+1;m<=j;m++){
if((c[i][m-1]+c[m][j])<min){
min=c[i][m-1]+c[m][j];
k=m;
}
}
return k;
}
void CreateOBST(float *p,float *q,float **c,int **r,float **w,int n)
{
for(int i=0;i<=n-1;i++){
//初始化
w[i][i]=q[i];c[i][i]=0.0;r[i][i]=0;
w[i][i+1]=q[i]+q[i+1]+p[i+1];
c[i][i+1]=q[i]+q[i+1]+p[i+1];
r[i][i+1]=i+1;
}
w[n][n]=q[n];c[n][n]=0.0;r[n][n]=0;
for(int m = 2;m<=n;m++){
//计算n-2条对角线元素
for(i=0;i<=n-m;i++){
int j = i+m;
w[i][j]=w[i][j-1]+p[j]+q[j];
int k=Find(i,j,r,c);
c[i][j]=w[i][j]+c[i][k-1]+c[k][j];
r[i][j]=k;
}
}
}
Find函数用于计算k,其计算时间为
利用D.E.Kunth[^1]的结论,计算