问题描述

给定n个有序文件,每个文件的记录数分别为w1~wn,请给出一种两两合并的方案,使得总合并次数最少。

注意:
1. 外排序算法是将多个有序文件合并成一个有序文件的过程。
2. 在一次合并的过程中,两个文件中的所有记录都需要先从文件中读入内存,再在内存中排序,最后将排序的结果写入文件中。
3. 假设两个待排序文件记录数分别为n、m,那么将这两个文件合并成一个有序的文件需要进行n+m次读写。

问题转化

n个文件两两合并的过程可以用一棵扩充二叉树来表示。因为扩充二叉树只有度为2或0的节点,没有度为1的节点,这符合两两合并的过程。

在这棵扩充二叉树中:
1. 方形节点(外界点)表示原始的文件,圆形节点(内节点)表示合并过程中的文件;
2. 节点的权值表示文件的记录数
因此,n个文件合并过程的总读写次数为带权外路径长度之和。
要求最小的合并次数即为求最小的带权外路径长度之和。
因此,问题就转化为『如何求扩充二叉树的最小加权路径』。
这个问题可以用哈夫曼算法解决。

哈夫曼算法

思路

若要使得带权外路径长度最小,可以将权值大的节点尽量靠近根节点,这样路径短一些;而权值小的节点可以适当远离根节点,因为权值小,外路径稍微长一点也没事。

伪代码

  1. 用一个优先权队列存储所有的初始节点;
  2. 从队列中选出两个权值最小的节点,将它们的和作为它们的根节点,并放入队列中;
  3. 循环这个过程,直到队列中只有一个节点为止,此时具有最小带权路径的扩充二叉树构造完毕!此时带权外路径长度即为最小的读写次数。

代码实现

/*** 构造二叉树的节点类*/
class TreeNode{int val;TreeNode left;TreeNode right;TreeNode(int val){this.val = val;}
}
/*** 构造哈夫曼树* @param w:所有节点的权值* @return 哈夫曼树的根节点*/
TreeNode hfmTree(int[] w){// 将所有节点存入优先权队列,按照权值递增排序PriorityQueue<TreeNode> queue = new PriorityQueue<>(w.length, new Comparator<TreeNode>(){public int compare(TreeNode t1,TreeNodet2){return t1.val-t2.val;}});for(int i=0; i<w.length; i++){queue.offer(new TreeNode(w[i]));}// 构造哈夫曼树while( queue.size()>1 ){// 弹出最小的两个节点TreeNode node1 = queue.poll();TreeNode node2 = queue.poll();// 构造父节点TreeNode father = new TreeNode(node1+node2);father.left = node1;father.right = node2;// 父节点入队queue.offer( father );}return queue.poll();
}

贪心算法(三)——最佳合并模式相关推荐

  1. 【贪心算法】手办合并

    题目描述 分析 首先要明白5点 想要保证距离最短每个手办必须只朝一个方向(左/右)移动n米(总不可能先左后右这样折返,得不偿失) 每个手办的移动操作可以分解成更细小的按照一米一米的移动操作,比如一个手 ...

  2. 三十六、贪心算法--集合覆盖问题

    一.贪心算法介绍 1.贪心算法(又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择.也就是说,不从整体最优上加以考虑,算法得到的是在某种意义上的局部最优解 2.贪心算法不是对所有问题都 ...

  3. 4.贪心算法 含例题

    文章目录 贪心算法 一.一个基本的贪心算法问题:区间调度问题 二.区间调度的推广:多个资源下的贪心算法 三.最小延迟调度--交换论证 四.最优超高速缓存问题 五.图最短路径问题 六.最小生成树问题 七 ...

  4. 漫画:五分钟学会贪心算法!

    假设一个问题比较复杂,暂时找不到全局最优解,那么我们可以考虑把原问题拆成几个小问题(分而治之思想),分别求每个小问题的最优解,再把这些"局部最优解"叠起来,就"当作&qu ...

  5. python贪心算法几个经典例子_关于贪心算法的一些探讨、经典问题的解决和三种典型的贪心算法算法(哈弗曼,Kruskal,Prim)的Python实现。...

    贪心算法(又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择.也就是说,不从整体最优上加以考虑,他所做出的是在某种意义上的局部最优解. 贪心算法不是对所有问题都能得到整体最优解,关键是 ...

  6. c语言贪心算法合并箭,LeetCode刷题题库:贪心算法

    LeetCode刷题笔记:贪心算法 自大学开始,我便陆陆续续的学习一些 算法和数据结构 方面的内容,同时也开始在一些平台刷题,也会参加一些大大小小的算法竞赛.但是平时刷题缺少目的性.系统性,最终导致算 ...

  7. 贪心算法——洛谷(P1090)[NOIP2004]合并果子

    该题目也属于经典的贪心算法,在这里熟悉C++里优先队列的使用. 需要导入头文件:   #include<queue> 从这个问题可以深挖出神奇的哈夫曼树问题. 因为这题里合并的是二叉树,所 ...

  8. 算法分析与设计-实验三 贪心算法设计

    文章目录 1.最优服务次序问题 2.区间相交问题 3.汽车加油问题 4.活动安排问题:考虑将一系列活动安排在科学会堂.假设有n个活动,每个活动需要花费一个单位时间.如果在时间T[i]或T[i]之前开始 ...

  9. [Leedcode][JAVA][第56题][合并区间][数组][贪心算法]

    [问题描述]56.合并区间 给出一个区间的集合,请合并所有重叠的区间. 示例 1: 输入: [[1,3],[2,6],[8,10],[15,18]] 输出: [[1,6],[8,10],[15,18] ...

最新文章

  1. Redis集群官方推荐方案 Redis-Cluster
  2. 二分类任务:确定一个人是否年收入超过5万美元
  3. guid linux 识别的分区表_Linux系统MBR和GPT分区的区别介绍
  4. 大话中文文本分类之TextRCNN
  5. cad线性标注命令_CAD图纸中怎么进行线性标注
  6. 2020 年开源许可证最新趋势:67% 为宽松许可证
  7. 【单页应用巨坑之History】细数History带给单页应用的噩梦
  8. Plate impulse response spatial interpolation with sub-Nyquist sampling
  9. boost::mp11::mp_replace_if_q相关用法的测试程序
  10. js实现上传图片及时预览
  11. 工作62:显示省略号
  12. 图像入门二之视频操作
  13. 收藏jquery兼容浏览器的ctrl+enter动作代码
  14. 由树莓派折腾中联想到的一个需求---基于Wiki的分布式协同编辑百科学习笔记本
  15. Daily Scrum 12.13
  16. 使用python调用浏览器实现自动转发微博
  17. 完美解决C#中拖动splitContainer分割线时显示虚线问题
  18. Android 外网连接解决方案
  19. ubuntu 各版本
  20. 关于Windows 8 用户使用习惯调查结果

热门文章

  1. 如何选择适合你的兴趣爱好(四),骑行
  2. OpenFire源码学习之七:组与花名册
  3. 深圳原来有这么多互联网公司,你都知道么?(2020最新整理)
  4. Matlab-Loma Prieta 地震分析
  5. 【解决】Uncaught SyntaxError: Unexpected end of JSON input at JSON.parse
  6. 搞钱!如何拿下奖金534万的全国人工智能大赛?
  7. 昆工教务计算机二级,昆明理工大学教务管理系统登录入口、成绩查询网上选课查分...
  8. 2022低压电工操作证考试题库及在线模拟考试
  9. css3改变纯色png图片的颜色
  10. 微信备份显示服务器失败是怎么回事,同步助手/微信备份助手遇到服务器访问异常怎么办?...