最优二叉搜索树问题(Java)
创始人
2024-02-08 15:29:38

最优二叉搜索树问题(Java)

文章目录

  • 最优二叉搜索树问题(Java)
    • 1、前置介绍
    • 2、算法设计思路
      • 2.1 最优二叉搜索树的结构
      • 2.2 一个递归算法
      • 2.3 计算最优二叉搜索树的期望搜索代价
    • 3、代码实现
    • 4、复杂度分析
    • 5、参考资料


在这里插入图片描述


1、前置介绍

S={x1, x2, … , xn} 是有序集, 且x1 < x2 < … < xn, 表示有序集S的二叉搜索树利用二叉树的结点存储有序集中的元素。

它具有下述性质:存储于每个结点中的元素xi大于其左子树中任一结点所存储的元素,小于其右子树中任一结点所存储的元素。 二叉搜索树的叶结点是形如(xi,xi+1)的开区间。在表示S的二叉搜索树中搜索元素x, 返回的结果有以下两种情形:

  • 在二叉搜索树的内结点中找到 x=xi;
  • 在二叉搜索树的叶结点中确定x属于 (xi, xi+1

最优二叉搜索树的形式化定义如下:给定一个n个不同关键字的已排序的序列K={k1, k2, …, kn}(因此k1 < k2 < … < kn),通过这些关键字来构建最优二叉搜索树。对于每个关键字ki作为「实节点」,都有一个概率 pi 与之对应(n个),表示其搜素频率「概率p下标从1开始对于每个关键字」。

但是有些要搜索的值可能不在K序列中, 因此我们还需要使用n+1个「伪关键字」d0, d1, d2, … , dn. 表示不在序列K中的值。d0表示所有小于k1如的值,dn表示所有大于kn的值,对i=l, 2, … , n—1, 伪关键字di 表示所有在ki和ki+1之间的值。对每个伪关键字di, 也都有一个概率 qi 表示对应的搜索频率「概率q下标从0开始对于每个伪关键字」。

下图中,显示了对一个n=5个关键字的集合构造的两棵二叉搜索树。每个关键字ki是一个内部结点, 而每个伪关键字di是一个叶结点。每次搜索要么成功(找到某个关键字ki)要么失败(找到某个伪关键字di),因此有以下公式:

∑i=1npi+∑i=0nqi=1\sum_{i=1}^{n}p_i + \sum_{i=0}^{n}q_i = 1 i=1∑n​pi​+i=0∑n​qi​=1

在这里插入图片描述

对一个n=5的关键字集合及如下的搜索概率,构造的两棵二叉搜索树:

i012345
pi0.150.100.050.100.20
qi0.050.100.050.050.1050.10

搜索代价如下公式②:

E[T中搜索代价]=∑i=1n(depthT(ki)+1)•Pi+∑i=0n(depthT(di)+1)•qi=1+∑i=1ndepthT(ki)•pi+∑i=1ndepthT(di)•qi)E[T中搜索代价] = \sum_{i=1}^{n}(depth_T(k_i) + 1)• P_i + \sum_{i=0}^{n}(depth_T(d_i) + 1)• q_i\\ = 1 + \sum_{i=1}^{n}depth_T(k_i)• p_i + \sum_{i=1}^{n}depth_T(d_i)• q_i) E[T中搜索代价]=i=1∑n​(depthT​(ki​)+1)•Pi​+i=0∑n​(depthT​(di​)+1)•qi​=1+i=1∑n​depthT​(ki​)•pi​+i=1∑n​depthT​(di​)•qi​)

在这里插入图片描述

2、算法设计思路

2.1 最优二叉搜索树的结构

在这里插入图片描述

2.2 一个递归算法

求解包含关键字ki, …,kj的最优二叉搜索树, 其中 i <= 1j <=n 且 j≥i一1j \geq i一1j≥i一1 (当 j = i - 1 时, 子树不包含实际关键字,只包
含伪关键字di-1)。定义e[i,j] 为在包含关键字ki, …,kj的最优二叉搜索树中进行一次搜索的期望代价。最终,我们希望计算出e[1, n]

以下分为两种情况;

  • j=i-1时最简单,因为子树只包含伪关键字di-1,此时的期望搜索代价为e[i, i—1]=qi-1

  • j>=i 时,我们需要从从ki, … ,kj中选择一个根结点kr, 然后构造一棵包含关键字ki, …, kr-1的最优二叉搜索树作为其左子树,以及一棵包含关键字kr+1, …, kj的二叉搜索树作为其右子树。

当一棵子树成为一个结点的子树时,由于每个结点的深度都增加了1, 根据公式②, 这棵子树的期望搜索代价的增加值应为所有概率之和。对于包含关键字ki, … , kj的子树, 所有概率之和为以下公式③:
w(i,j)=∑l=ijpi+∑l=i−1jqiw(i,j) = \sum_{l=i}^{j}p_i + \sum_{l=i-1}^{j}q_i w(i,j)=l=i∑j​pi​+l=i−1∑j​qi​

因此,若ki, … , kj 的最优二叉搜索树的根结点,我们有如下公式④:

w(i,j)=w(i,r−1)+pr+w(r+1,j)w(i,j) = w(i,r-1) + p_r + w(r+1,j) w(i,j)=w(i,r−1)+pr​+w(r+1,j)

因此e[i,j]可重写为:如下公式⑤
e[i,j]=e[i,r−1]+e[r+1,j]+w(i,j)e[i,j] = e[i,r-1] + e[r+1,j] + w(i,j) e[i,j]=e[i,r−1]+e[r+1,j]+w(i,j)

递归公式⑤假定我们知道哪个结点k应该作为根结点。如果选取期望搜索代价最低者
作为根结点,可得最终递归公式⑥:

e[i,j]={qi−1j = i - 1mini<=1<=j{e[i,r−1]+e[r+1,j]+w(i,j)}i<=je[i,j] = \begin{cases} q_i-1& \text{j = i - 1}\\ min_{i<=1<=j}\{e[i, r-1] + e[r+1,j]+w(i,j)\}& \text{i<=j} \end{cases}e[i,j]={qi​−1mini<=1<=j​{e[i,r−1]+e[r+1,j]+w(i,j)}​j = i - 1i<=j​

e[i,j]的值给出了最优二叉搜索树的期望搜索代价。

在这里插入图片描述

2.3 计算最优二叉搜索树的期望搜索代价

在这里插入图片描述

伪代码如下:

在这里插入图片描述

根据前文的描述,以及与算法MATRIX-CHAIN-ORDER的相似性,很容易理解此算法。第2-4行的for循环初始化e[i, i —1]和w[i, i —1]的值。第5-14行的for循环利用
递归式⑥和递归式(15. 15)来对所有1≤i≤j≤n1 \leq i \leq j \leq n1≤i≤j≤n计算e[i, j]和w [i, j]。

在第一个循环步中,l= l, 循环对所有i = 1, 2, …, n计算e[i, j]和w[i, i]。第二个循环步中, l = 2, 对所有i = 1, 2, …, n — 1 计算e[i, i+l]和w[i, i+l], 依此类推。第10-14行的内层for循环,逐个尝试下标r, 确定哪个关键字k, 作为根结点可以得到包含关键字ki, …,kj的最优二叉搜索树。这个for循环在找到更好的关键字作为根结点时,会将其下标r保存在root[i, j]中。

下图给出了OPTIMAL-EST输入图1中的关键字分布后计算出的表e[i, j]、w[i, j]和
写root[i, j]。本图中的表进行了旋转,对角线旋转到了水平方向。OPTIMAL-EST按自底向上的顺序逐行计算,在每行中由左至右计算每个表项。

在这里插入图片描述

3、代码实现

动态规划解决最优二叉搜索树

/*** TODO 实现最优二叉树算法*/
public class t4 {public static void main(String[] args) {// TODO p[1, 5]是 5个实节点的概率 p[0]不存在,对应每一个关键字的搜索频率double[] p = {0, 0.15, 0.1, 0.05, 0.1, 0.2};// TODO q[0, 5]是 6个伪节点的概率double[] q = {0.05, 0.1, 0.05, 0.05, 0.05, 0.1};// TODO 一共5个关键字(可以搜索得到的,即实节点)int n = p.length - 1;// TODO root[i][j]记录的是最终得出的[i,j]这个子段里的根节点int[][] root = optimalBinarySearchTree(p, q, n);// TODO root的 length 是 n+2, i 和 j 只需要循环到 nint temp = root.length - 1;// TODO 输出一下这个root矩阵,直接根据这个矩阵也可以画出来最优二叉搜索树//  root矩阵将对角线旋转到水平方向更直观地看到最优二叉搜索树for (int i = 1; i < temp; i++) {for (int j = 1; j < temp; j++) {System.out.print(root[i][j] + "-");}System.out.println();}}private static int[][] optimalBinarySearchTree(double[] p, double[] q, int n) {// TODO e[i][j]表示 i 到 j 这段的代价//  e[1][0]为左边只包含伪节点d0的代价...e[n+1][n]为左边只包含伪节点dn的代价double[][] e = new double[n + 2][n + 2];// TODO i 到 j 这一段的总概率,在加一层根节点时需要用到//  为避免每次计算e[i, j]都重新计算w(i,j)的值,直接将这些值存放在w数组中double[][] w = new double[n + 2][n + 2];// TODO root[i][j]记录的是最终得出的[i,j]这个子段里的根节点int[][] root = new int[n + 2][n + 2];// TODO 初始化for(int i = 1; i < n + 1; i++) {e[i][i - 1] = q[i - 1];w[i][i - 1] = q[i - 1];     // 1 <= i <= n + 1的情况}// TODO :l是 [i, j]区间的长度,相当于一个固定l长度的小节从最左边循环到最右边。//  然后再把l逐渐加大,重复从左到右。//  这样就使得小长度的都先计算过,为大长度的片段分解为左右两个字片段计算时提供了已经计算好的值,这也是动态规划的精髓之一。//  这样做是为了从小到大积累动态规划的能量for (int l = 1; l <= n; l++) {for (int i = 1; i <= n - l + 1; i++) {int j = i + l - 1;// TODO 初始化为最大值,最后才能找出真正最小的,从而找到最优解e[i][j] = Double.MAX_VALUE;// TODO j >= i的情况w[i][j] = w[i][j-1] + p[j] + q[j];// TODO 从 i 到 j 找到最优的根节点(选择以 r 为根节点)for(int r = i; r <= j; r++) {// TODO 加了一层,相当于下面的左子树右子树都加了一布,其实就是最终比没加一层根节点比多了一个w[i][j]double t = e[i][r - 1] + e[r + 1][j] + w[i][j];// TODO 不断的使e[i][j]保持最小,同时记录下使代价最小的位置为最终的最优的根节点if(t < e[i][j]) {e[i][j] = t;root[i][j] = r;}}}}System.out.println("当前最小代价:" + e[1][n]);return root;}
}

4、复杂度分析

与MATRIX-CHAIN-ORDER 一样,OPTIMAL-BST的时间复杂度也是O(n3 )。由于它包含三重for循环,而每层循环的下标最多取n个值, 因此很容易得出其运行时间为O(n3)。

OPTIMAL-EST的循环下标的范围与MATRIX-CHAIN-ORDER不完全一样,但每个方向最多相
差1。因此,与MATRIX-CHAIN -ORDER 一样,OPTIMAL-EST的运行时间为O(n3) (从而得出运行时间为O(n3))。

5、参考资料

  • 算法分析与设计(第四版)
  • 算法导论第三版

相关内容

热门资讯

埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...