动态规划--4.最优二叉查找树

1.最优二叉查找树

(1)左孩子<根<右孩子

(2)树内关键字k1...kn(中间节点k1

d0,d1,dn ;d0表示小于k1的所有值, dn表示大于kn的所有值,它们对应的搜索概率是 q0,q1...qn 

如图动态规划--4.最优二叉查找树_第1张图片

(3)每棵树每个节点的期望是 (搜索深度+1)*概率,为什么搜索深度+1不是搜索深度?如果只是搜索深度*概率的话,那么根节点期望岂不是0*概率=0了。

此外每次搜索都有成功和不成功两种(分别对应到ki和di)那么有


2.最优子结构

e[i,j] 表示包含 ki...kj关键字的树的搜索代价,设这几个关键字组成的树以 kr 为根(i<=r<=j) 那么对应的左右子树分别是 ki...kr-1  和 kr+1...kj,它们对应的叶子分别为 di-1...dr-1

和 dr...dj。OK树构造完了,分为两种情况

(1)只有一个叶子组成的子树 j=i-1, 只有di-1, 那么e[i,j] = qi-1 这个子树为1个叶节点 不在划分左右子树 如上图a中的d2

(2)子树还包含关键字 即继续划分左右子树 i<=j。那么e[i ,j]= min{ e[i, r-1] + e[r+1,j] + w(i ,j) } 以kr为根的代价中最小值 r从i到j 

OPTIMAL-BST(p[],q[],n){
let e[1,...n+1,0,...n] and root[1,...n,1,...n] and  w[1,...n+1,0,...n]
//e[1,0]表示只有伪关键字d0的代价,e[n+1,n]表示只有伪关键字dn的代价  
//在w[1,...n+1,0,...n]的下标含义一致

//初始化e[i, i - 1]和 w[i, i - 1]
for i ← 1 to n + 1
   do e[i, i - 1] ← qi-1
      w[i, i - 1] ← qi-1
for l ← 1 to n
   do for i ← 1 to n - l + 1
     do j ← i + l - 1
       e[i, j] ← ∞
       w[i, j] ← w[i, j - 1] + pj + qj
       for r ← i to j
         do t ← e[i, r - 1] + e[r + 1, j] + w[i, j]
           if t < e[i, j]
             then e[i, j] ← t
               root[i, j] ← r
  return e and root
}

3.代码实现  

与矩阵链相乘类似

/**
 * 
 */
package optimal_BST;

/**
 * @author LingLee
 *动态规划 最优二叉查找树 和矩阵链相乘类似 都是三层循环
 */
public class OptimalBST {

	public static void main(String[] args){
		double[] p={0,0.15,0.1,0.05,0.1,0.2};//n=5,5个关键字的搜素概率,p0=0哨兵 概率p1到pn
		double[] q={0.05,0.1,0.05,0.05,0.05,0.1}; //叶子节点有n+1个,概率从q0到qn
		int n=p.length;
		System.out.println("输出根节点的辅助表");
		int[][] root = Optimal_BST(p,q,n-1);
        int temp = root.length-1;
        System.out.println("根:K"+root[1][5]);

        printOptimalBST(root,1,5,root[1][5]);
	}
	
	//计算最优二叉查找树的辅助表
	public static int[][] Optimal_BST(double[] p,double[] q,int n){
		double[][] e=new double[n+2][n+2];//e[i][j]表示包含ki...kj的搜索概率
		double[][] w=new double[n+2][n+2];//w[i][j]表示 ki...kj的概率总和
		int[][] root=new int[n+2][n+2];
		
		//初始化叶子节点的值
		for(int i=1;i<=n+1;i++){//叶子节点一共n+1个是从d0到dn
			e[i][i-1]=q[i-1];
			w[i][i-1]=q[i-1];
		}
		
		for(int l=1;l<=n;l++){//表示从k1到kl有l个关键字参与构造树,1<

动态规划--4.最优二叉查找树_第2张图片



你可能感兴趣的:(数据结构和算法)