详解动态规划之“最优二叉搜索树”

之前两篇分别讲了动态规划的“钢管切割”和“矩阵链乘法”,感觉到了这一篇,也可以算是收官之作了。其实根据前两篇,到这里,也可以进行一些总结的,我们可以找到一些规律性的东西。

所谓动态规划,其实就是解决递归调用中,可能出现重复计算子问题,从而导致耗费大量时间,去做重复劳动的问题。解决思路就是,将重复做过的子问题的结果,先存起来,等之后再需要用到的时候,直接拿过来用,而不需要再去计算。

但是这里还需要注意一些地方:

①要解决的问题,比如“钢管切割”中的长钢管,它的最优化的解,要能够是分解成的子问题的最优化的解的组合。

②如何给出子问题,孙子问题等的最优化解的统一递归调用形式。

③找一个或者几个合适的集合,去保存我们求的子问题的解,或者是划分的方案。比如在钢管切割中,我们使用的一位数组,而到了矩阵链乘法中,我们使用的二维数组。

④采用自顶向下还是自底向上的方案。

一、概述

好,言归正传,来看看最优二叉搜索树。关于二叉搜索树,可以参看之前的两篇文章:二叉树的前中后序非递归遍历实现和二叉搜索树的插入和删除。这里不再赘述。

假如说我们要设计一个程序,来实现英语文本到法语的翻译。我们可以建立一个二叉搜索树,将n个英语残次作为关键字,对应的法语单词作为关联数据。然后我们依次遍历二叉搜索树中每个节点的英文单词,来找到合适的单词进行翻译工作。这里我们肯定是希望这个搜索的时间越少越好,如果只考虑单纯的时间复杂度,我们可以考虑采用红黑树等,来达到搜索时间复杂度为Olg(n)。但是对于英语单词而言,每个单词出现的概率是不一样的,比如"the"等单词。显然的让这类单词越靠近根结点越能减少搜索的时间。而对于某些很少见的单词,则可以让它们远离根结点。

问题来了,假如我们已知n个不同关键字ki以及我们的出现概率p[i],我们如何来组成这样一颗最优二叉搜索树呢?

查找这棵二叉树的结果不外乎是两种,一种是找到了我们想要的key值,另一种是遍历完整棵树都没有找到我们要的key值,我们将这种没有找到key值也安排一些节点di来表示,那么显然di节点都是叶子节点。称di为伪关键字,对应的概率为q[i]。d0代表所有小于k1的值,dn代表所有大于kn的值,其他的di(1<=i<=n-1),代表di值位于ki和ki+1之间。因为一次搜索,要么是搜到di,要么是搜到一个ki,所有有:

然后现在我们可以给出搜索一次会搜索到的节点数的一个期望,因为对于二叉树而言,每多一层,则就会多查找一个节点,所以我们可以对每个节点的深度加1,然后乘以该节点的pi,然后将所有节点的结果求和,就可以求出搜索一棵树会搜索到的节点的一个期望:

最优二叉搜索树的定义就是:对于给定的节点key值概率,使得上述期望值最小的二叉搜索树结构。

二、使用动态规划来处理最优二叉搜索树

那么还是那几步:

①首先将问题分成子问题,看看问题的最优是不是子问题也最优的时候可以达成。

可以使用“jianqie -粘贴”法来证明,对于一颗最优二叉搜索树T而言,对于T的一颗子树Ti,假设它包含关键字ki....kj,如果Ti不是最优二叉查找树,那么就意味着存在另一棵包含节点ki...kj的二叉搜索树Tj,使得Tj的搜索期望比Ti的搜索期望低,那么我们可以将Ti从T中“剪切”掉,然后将Tj“粘贴”到原来Ti的位置,这样一来,就发现新生成的树肯定要比原来的树T的搜索期望要低了,这是矛盾的,因为我们原来假设T是一棵最优二叉搜索树。所以可以反证,最优二叉搜索树的子树都是最优二叉搜索树。

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

  1. 算法导论 — 15.5 最优二叉搜索树

    ###笔记 二叉搜索树满足如下性质:假设xxx是二叉搜索树中的一个结点.如果lll是xxx的左子树的一个结点,那么l.key≤x.keyl.key ≤ x.keyl.key≤x.key.如果rrr是x ...

  2. 算法导论-动态规划(钢条切割问题)

    写下文章来记录下自己学习算法导论的笔记 文章目录 写下文章来记录下自己学习算法导论的笔记 动态规划的目的 设计动态规划算法 钢条切割问题 问题描述 刻画问题结构(建立方程) 递归方程建立 带备忘录的自 ...

  3. 二维排样规则算法php,一种实用的二维不规则零件排样算法

    I5JKI5L 您的论文得到相关企业家品评 一种实用的二维不规则零件排样算法 !"#$%&'()*('+!,)-./#0)*/1!+1-&*)23-45.6*3#/0*-/! ...

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

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

  5. 最优二叉搜索树(Optimal BST)-算法导论

    问题描述: 维基百科定义: https://en.wikipedia.org/wiki/Optimal_binary_search_tree In the static optimality prob ...

  6. 算法导论 动态规划钢条切割问题 C语言

    动态规划钢条切割问题 动态规划(dynamic programming)与分治法类似.分治策略将问题划分为互不相交的子问题,递归求解子问题,再将子问题进行组合,求解原问题.动态规划应用于子问题重叠的情 ...

  7. 算法导论-动态规划-钢条切割问题

    文章目录 一.钢条切割定义 二.具体步骤 1.思考 2.代码思考 3.动态规划求解 4.伪代码 三:总结: 一.钢条切割定义 图为价格表 给定一段长度是n的钢条和一个价格表,求切割方案使得收益达到最大 ...

  8. 算法导论-动态规划(dynamic programming)

    动态规划:通过组合子问题的解来解决整个问题. 动态规划的四个步骤: 1)描述最优解的结构: 2)递归定义最优解的值: 3)按自低向上的方式计算最优解的值(首先找到子问题的最优解,解决子问题,最后找到问 ...

  9. 算法导论——动态规划:0-1背包问题(完全解)

    2019独角兽企业重金招聘Python工程师标准>>> package org.loda.dynamic;import org.junit.Test;/*** * @ClassNam ...

  10. 算法导论 c语言,算法导论 之 堆排序[C语言]

    一.算法实现 堆排序算法的时间复杂度为O(nlgn),其算法实现如下: void heap_sort(int *array, int max) { int idx = 0; build_max_hea ...

最新文章

  1. github创建本地库后关联远程库
  2. Android应用开发基础篇(12)-----Socket通信(转载)
  3. 高斯白噪声的Verilog实现
  4. 似然估计中为什么要取对数以GMM为例
  5. ARM Cortex-M0微控制器汇编语言之分支条件的典型用法
  6. python操作mysql数据库 内存占用100_python操作MySQL数据库
  7. 光流 | 稠密光流估计(基于LK光流)(源代码分享)
  8. 用代码,打造创意新世界!【Innovation 2021】网易应用创新开发者大赛正式开赛!
  9. 各种震撼的慢镜头,奇怪的知识又增加了!​
  10. HTML+CSS+JS实现 ❤️爱心文字3D旋转动画特效❤️
  11. Java Web-网页基础-HTML-URL
  12. js数组依据下标删除元素
  13. C/C++[codeup 1925]特殊排序
  14. C语言游戏开发——反弹球
  15. 常用的4款seed磁链搜索工具
  16. 在pycharm中使用pyqt5时clicked().后面connect不自动补全问题解决办法
  17. p17.matplotlib:图中图
  18. 交叉网线制作和用交叉网线tftp
  19. 基于CNN卷积神经网络的商品识别(毕设)
  20. oracle增加分区时报ora14036,增加分区表2009年的分区报ORA-14074错误

热门文章

  1. 体检健康行业CRM客户关系管理系统
  2. 精髓的git stash
  3. SpringCloud Gateway 身份认证
  4. 小森生活手游服务器维护,小森生活无可用游戏服务器解决教程
  5. 计算机3000字论文翻译,计算机翻译论文3000字_计算机翻译毕业论文范文模板.doc...
  6. 怎么把便签里的提醒添加到安卓手机日历?
  7. golang中的json decode丢失精度的问题
  8. 开心农场是怎样炼成的?
  9. (附源码)python旅游推荐系统 毕业设计 250623
  10. 日常练习!加强网络部分!!