第15章动态规划(最优二叉搜索树)

  • 15.5 最优二叉搜索树
  • 15.5 练习
    • 15.5-1
    • 15.5-2
    • 15.5-3
    • 15.5-4

说在前面的话:

为什么单独拿出来发?
1.由于排版篇幅问题,放一起太长没人愿意看吧。
2.单纯想增加投稿数量。(毕竟今天都没怎么发过文)

15.5 最优二叉搜索树

最优二叉搜索树的问题的形式可以定义如下:给定一个n个不同关键字的已排序的序列K=<K1,K2,…,Kn>(因此k1<k2…<kn),我们希望用这些关键字构造一棵二叉树搜索树。对每个关键字ki,都有一个概率pi表示其搜索频率。**有些搜索值可能不在K中,因此我们还要有n+1个“伪关键字”d0,d1,d2,…,dn表示不在K中的值。**对每个伪关键字di,也都有一个概率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

如图显示了对于n=5个关键字的集合构造的两颗二叉搜索树。每个关键字ki是一个内部结点,而每个伪关键字di是一个叶结点。每次搜索要么成功(找到关键字ki)要么失败(找到伪关键字di),因此有如下公式:
∑i=1n\displaystyle\sum_{i=1}^{n}i=1∑n​ pi + ∑i=0n\displaystyle\sum_{i=0}^{n}i=0∑n​ qi = 1

由于我们知道每个关键字和伪关键字的搜索概率,因而可以确定在一棵给定的二叉搜索树T中进行一次搜索的期望代价。假定一次搜索的代价等于访问的结点数,即此次搜索找到的结点在T中的深度再加1.那么在T中进行亿次搜索的期望代价为:
E[T中搜索代价] = ∑i=1n\displaystyle\sum_{i=1}^{n}i=1∑n​ (depthT(ki) + 1) * pi + ∑i=0n\displaystyle\sum_{i=0}^{n}i=0∑n​(depthT(di) + 1) * qi
= 1 + ∑i=1n\displaystyle\sum_{i=1}^{n}i=1∑n​ (depthT(ki) ) * pi + ∑i=0n\displaystyle\sum_{i=0}^{n}i=0∑n​(depthT(di) ) * qi
其中depthT表示一个结点在树T中的深度。

对于一个给定的概率集合,我们希望构造一课期望搜索代价最小的二叉搜索树,我们成为最优二叉搜索树上图右边所示的二叉搜索树就是给定概率集合的最优二叉搜索树,其期望代价为2.75。

代码如下:

   public class Program{public static void Main(string[] args){var handle = new OPTIMALBST_Handle();handle.optimal_bst();}}public class OPTIMALBST_Handle{public decimal[] p { get; set; }public decimal[] q { get; set; }public int amount { get; set; }public decimal[,] w { get; set; }public decimal[,] e { get; set; }public int[,] root { get; set; }public OPTIMALBST_Handle(){Console.WriteLine("请输入结点数:\r");amount = Convert.ToInt32(Console.ReadLine());p = new decimal[amount + 1];q = new decimal[amount + 1];w = new decimal[amount + 2, amount + 1];e = new decimal[amount + 2, amount + 1];root = new int[amount + 1, amount + 1];for (var i = 1; i <= amount; i++){Console.WriteLine("关键字k" + i + "的概率为:\r");p[i] = Convert.ToDecimal(Console.ReadLine());}for (var i = 0; i <= amount; i++){Console.WriteLine("伪关键字d" + i + "的概率为:\r");q[i] = Convert.ToDecimal(Console.ReadLine());}}public void optimal_bst(){for (var i = 1; i <= amount + 1; i++){w[i, i - 1] = q[i - 1];e[i, i - 1] = q[i - 1];}for (var l = 1; l <= amount; l++){for (var i = 1; i <= amount - l + 1; i++){var j = i + l - 1;w[i, j] = w[i, j - 1] + p[j] + q[j];e[i, j] = decimal.MaxValue;for (var r = i; r <= j; r++){var temp = e[i, r - 1] + w[i, j] + e[r + 1, j];if (temp < e[i, j]){e[i, j] = temp;root[i, j] = r;}}}}}}

15.5 练习

15.5-1

设计伪代码CONSTRUCT-OPTIMAL-BST(root),输入为表root,输出是最优二叉搜索树的结构。例如,对图上图中的root表,应输出
k2为根
k1为k2的左孩子
d0为k1的左孩子
d1为k1的右孩子
k5为k2的右孩子
k4为k5的左孩子
k3为k4的左孩子
d2为k3的左孩子
d3为k3的右孩子
d4为k4的右孩子
d5为k5的右孩子
与图(b)中的最优二叉搜索树对应

直接上代码和输出结果,用的是不递归前序遍历二叉树的思路。
结果和上面是一样的,这里就不贴输出内容了,有兴趣可以自己复制代码试一下。当然这里用递归前序遍历二叉树肯定简单明了多了,用不递归去写纯粹是一时兴起。

        public void Construct_optimal_bst(){var s_left = new Stack();var s_right = new Stack();var l = 1;var r = amount;var parent = -1;while (s_left.Count != 0|| r >= l){while (r >= l){if (parent == -1){Console.WriteLine("k" + root[l, r] + "为根");}else if (root[l, r] >= parent){Console.WriteLine("k" + root[l, r] + "为k" + parent + "的右孩子");}else{Console.WriteLine("k" + root[l, r] + "为k" + parent + "的左孩子");}s_left.Push(l);s_right.Push(r);parent = root[l, r];r = parent - 1;if (r == l - 1){Console.WriteLine("d" + r + "为k" + parent + "的左孩子");}}if (s_left.Count != 0 && s_right.Count != 0){l = (int)s_left.Pop();r = (int)s_right.Pop();parent = root[l, r];l = parent + 1;if (r == l - 1){Console.WriteLine("d" + r + "为k" + parent + "的右孩子");}}}}

15.5-2

若7个关键字的概率如下图所示,求其最优二叉搜索树的结构和代价。

i 0 1 2 3 4 5 6 7
pi / 0.04 0.06 0.08 0.02 0.10 0.12 0.14
qi 0.06 0.06 0.06 0.06 0.05 0.05 0.05 0.05

输入题目里面的元素,直接运行代码就能出结果了。

15.5-3

假设OPTIMAL-BST不维护表w[i,j],而是在第9行利用公式直接计算w(i,j),然后在第11行使用此值。如此改动会对渐近时间复杂性有何影响?
公式为w(i,j) = ∑i=1n\displaystyle\sum_{i=1}^{n}i=1∑n​ pi + ∑i=0n\displaystyle\sum_{i=0}^{n}i=0∑n​ qi
两个总和项都要花费O(n)的时间,因此时间复杂度上升到O(n^3)。

15.5-4

Knuth已经证明,对所有1<=i<=j<=n,存在最优二叉搜索树,其根满足root[i , j-1] <= root[i , j] <= root[i + 1, j]。利用这一特性修改算法OPTIMAL-BST,使得运行时间减少为Θ(n^2)。

非常强的证明,直接简化了我们的递归公式。
后续会直接贴上修改后的代码。

第十五章 动态规划(最优二叉搜索树)相关推荐

  1. 第十五章 动态规划——最优二叉搜索树

    1.前言: 接着学习动态规划方法,最优二叉查找树问题.二叉查找树参考http://www.cnblogs.com/Anker/archive/2013/01/28/2880581.html.如果在二叉 ...

  2. 动态规划最优二叉搜索树C语言,【算法导论】动态规划之“最优二叉搜索树”...

    详解动态规划之"最优二叉搜索树" 之前两篇分别讲了动态规划的"钢管切割"和"矩阵链乘法",感觉到了这一篇,也可以算是收官之作了.其实根据前两 ...

  3. 动态规划——最优二叉搜索树

     (二叉搜索树即二叉排序树,该题并不是问如何构造最优二叉树,而是如何在二叉搜索树中达成最优搜索效率) 简而言之,这个最优二叉搜索树的每个根节点都大于左子树的任一元素,小于其右子树的任意元素,相当于用根 ...

  4. 最优二叉搜索树java_动态规划-最优二叉搜索树

    算法思想:动态规划 实际问题:最优二叉搜索树 编写语言:Java 问题描述 二叉搜索树的定义: 满足以下任意两个条件的一个,就可称这棵树为二叉搜索树: 它是一棵空树 该树是一颗二叉树,非空,且满足下列 ...

  5. 动态规划最优二叉搜索树C语言,算法 – 动态规划:最优二叉搜索树

    好吧,我希望有人可以向我解释一下.我正在攻读决赛,我无法解决问题. 问题是动态编程;构造最优二叉搜索树(OBST).我理解一般的动态编程和特别是这个问题的概念,但我不明白这个问题的递归形式. 我得到的 ...

  6. c语言动态规划最优二叉搜索树,最优二叉搜索树(动态规划)

    #include #include #include #include #include enum:int { MAXVALUE=999 }; template class BestTree{ pri ...

  7. 动态规划思想——最优二叉搜索树问题(附完整的代码)

    问题: 最优二叉搜索树问题的问题提出是,设S={x1, x2, ..., xn}是一个由n个关键字组成的线性有序集,(a0, b1, a1, ..., bn, an) 为集合S的存取概率分布,表示有序 ...

  8. 【算法设计与分析】动态规划:最优二叉搜索树

    最优二叉搜索树问题的问题提出是,设S={x1, x2, -, xn}是一个由n个关键字组成的线性有序集,(a0, b1, a1, -, bn, an) 为集合S的存取概率分布,表示有序集S的二叉搜索树 ...

  9. 算法:最优二叉搜索树

    算法设计第五次作业part2 1.纸面题:对最优二叉树和矩阵连乘两种算法验证四边形法则,如果符合四边形法则则举几个正例,如果不符合则举几个反例 四边形法则 i<i'j<j'w(i,j)+w ...

最新文章

  1. Webhooks上的一个简单方法:恐吓现在停止
  2. Python正则表达式-2
  3. ELK 6.2.4搭建
  4. mysql主从复制不同步案例_Mysql主从不同步问题处理案例
  5. JAVA进阶教学之(Object类的toString方法)
  6. hortonworks/registry : ClassNotFoundException: com.mysql.jdbc.jdbc2.optional.MysqlDataSource
  7. easyplayerpro 使用说明_H265网页播放器EasyPlayerPro-Win如何通过配置文件实现自动播放等功能?...
  8. tensorflow eager 模式下打印dataset中的数据
  9. Ubuntu18.04关闭docker开机自启动
  10. 传入oracle中的日期类型,Oracle中的日期类型及相关函数
  11. 制版经验分享—使用AD18
  12. 高仿城通网盘php,PHP-php 如何实现同时允许下载的文件个数控制,类似于城通网盘这样的文件下载控制...
  13. 未来人工智能发展趋势
  14. 如何在计算机自动开机时选择用户,电脑如何设置自动开机
  15. BZOJ 2037: [Sdoi2008]Sue的小球
  16. python把两个图片合成一张图
  17. vue echarts 实现速度的那种进度蓄力效果
  18. C语言:L1-009 N个数求和 (20 分)
  19. 火龙果(redpitaya)开发板常用接口C语言开发指南(一)——环境配置(持续更新中)
  20. python成都 培训

热门文章

  1. 利用EndNote向Word插入参考文献出现文本({作者,年份 #980})
  2. Adobe AIR安装错误解决办法
  3. (转载)什么时候用分布调拨,什么时候用直接调拨,这两种方式有什么区别?
  4. uniapp image高度不自适应
  5. 2016年中国电信业发展趋势:管道价值回归与重塑
  6. 照片钢笔淡彩人物肖像效果
  7. Mac数据恢复,怎能不用EasyRecovery
  8. 爱尔兰圣三一大学计算机专业申请,爱尔兰计算机专业申请
  9. elmentUI 表格模板(1)
  10. Phone与Rild连接过程及消息收发