当需要对一个大文件进行排序时,计算机内存可能不够一次性装入所有数据,解决办法是归并。归并的大概做法是将大文件分为若干段,依次读入内存进行排序,排序后再重新写入硬盘。这些排好序的片段成为顺串。然后对这些顺串进行逐躺归并,使归并段逐渐由小变大,最终使整个文件有序。要使用归并就得考虑两个问题,一个是如何生成顺串,一个是如何对顺串进行归并。

置换选择算法

  先考虑如何生成顺串。我们知道,减少顺串的数量可以降低归并的次数,而在文件大小固定的情况下,要减少顺串的数量,就要增大单个顺串的长度。如果使用内部排序生成顺串,那么顺串的大小最多等于可用内存的大小。因此我们使用置换选择排序,可以生成大概两倍于内存大小的顺串。步骤如下:

  (1)首先从输入文件中读取N个数字将数组填满  

  (2)使用数组中现有数据构建一个最小堆

  (3)重复以下步骤直到堆的大小变为0:

    a. 把根结点的数字A(即当前数组中的最小值)输出

    b. 从输入文件中再读出一个数字B,若R比刚输出的数字A 大,则将B放到堆的根节点处,若B不比A大,则将堆的最后一个元素移到根结点,将B放到堆的最后一个位置,并把堆的大小缩减1(即新读入的数据没有进入堆中)

    c. 在根结点处调用Siftdown重新维护堆

  (4)换一个输出文件,重新回到步骤(2)

书上有个铲雪机的例子来类比证明出使归并段长度的期望值为两倍工作区容量,但我觉得类比说明不了什么问题,严谨的证明我又不会,就跳过吧。

败者树

  接下来考虑如何对顺串进行归并。多路归并排序算法在常见数据结构书中都有涉及。从2路到多路(k路),增大k可以减少归并趟数,外存信息读写时间,但k个归并段中选取最小的记录需要比较k-1次,为得到u个记录的一个有序段共需要(u-1)(k-1)次,若归并趟数为s次,那么对n个记录的文件进行外排时,内部归并过程中进行的总的比较次数为s(n-1)(k-1),也即

而(k-1)/logk随k增而增因此内部归并时间随k增长而增长了,抵消了外存读写减少的时间,这样做不行,由此引出了“败者树”的使用。败者树只需进行logk次比较,在内部归并过程中利用败者树将k个归并段中选取最小记录比较的次数降为(logk)次使总比较次数为(logm)(n-1),与k无关。

败者树的具体操作《数据结构》书里有,我就不赘述了。这里说一下败者树和堆的比较。

堆执行一次比较(即调整)时间复杂度也是logn,但是堆调整的时候父节点要分别和两个子节点进行比较,而败者树只需和兄弟节点进行一次比较即可。因为要存储败者信息,败者树占用空间会比堆大。

  

转载于:https://www.cnblogs.com/tonychen-tobeTopCoder/p/5797002.html

外部排序---置换选择+败者树相关推荐

  1. dataStructure_外部排序/多路归并/败者树/最佳归并树

    文章目录 外部排序 时间代价:为什么不用二路归并 概念 归并段 小结:每趟归并需要读写磁盘的次数取决于 内存工作区 严格k叉树 k叉树和k路归并的趟数s与初始归并段数量m的关系 提高外部排序性能 k路 ...

  2. 8-14外部排序-置换选择排序

    效果: 构造更长的初始归并段 初始归并段的数量尽可能的少 以前的办法: 若文件共有n个记录,每个初始归并段只能包含l个记录(用于内部排序的内存工作区WA可容纳l个记录),则初始归并段数量r=n/l 现 ...

  3. 数据结构之外部排序:最佳归并树

    外部排序:最佳归并树 思维导图: 归并树的定义: 例: 最佳归并树(本质是一颗哈夫曼树): 所有的初始归并段一定能构造出一颗完美的哈夫曼树吗? 怎么选择补充虚短的个数? 思维导图: 归并树的定义: 例 ...

  4. 数据结构之外部排序:置换-选择排序

    外部排序:置换-选择排序 置换-选择排序算法思想: 步骤: 通过减少归并段r来减少IO次数 置换-选择排序算法思想: minimax就是FO中的最后一个数据元素的大小 1.将工作区填满 2.从工作区选 ...

  5. 处理大文件排序的方式--外部排序

    引言   一般来说,对一个数组的排序,我们常用冒泡排序.快速排序.堆排序等算法进行排序.这样的数组能够一次性加载到内存中,使用上述的排序算法就能轻而易举进行排序,所以上述的排序算法可以称之为堆内排序. ...

  6. 数据结构(八):排序 | 插入排序 | 希尔排序 | 冒泡排序 | 快速排序 | 简单选择排序 | 堆排序 | 归并排序 | 基数排序 | 外部排序 | 败者树 | 置换-选择排序 | 最佳归并树

    文章目录 第八章 排序 一.排序的基本概念 (一)什么是排序 (二)排序的应用 (三)排序算法的评价指标 (四)排序算法的分类 (五)总结 二.插入排序 (一)算法思想 (二)算法实现 (三)算法效率 ...

  7. 算法整理:外排序篇-置换选择排序最佳归并树

    目录 置换-选择排序 最佳归并树 外部排序分为几个步骤,首先根据内存将待排序文件分段,然后按照分段依次将每个分段的数据读入内存排序,最后将排序后的分段通过归并算法组合在一起.在排序的过程算法对外存的读 ...

  8. 外部排序归并排序 败者树

    一.定义问题 外部排序指的是大文件的排序,即待排序的记录存储在外存储器上,待排序的文件无法一次装入内存,需要在内存和外部存储器之间进行多次数据交换,以达到排序整个文件的目的.外部排序最常用的算法是多路 ...

  9. 胜者树与败者树, 多路平衡归并外部排序

    胜者树与败者树   胜者树和败者树都是完全二叉树,是树形选择排序的一种变型.每个叶子结点相当于一个选手,每个中间结点相当于一场比赛,每一层相当于一轮比赛. 不同的是,胜者树的中间结点记录的是胜者的标号 ...

最新文章

  1. ML 03、机器学习的三要素
  2. git configuration
  3. java纯粹面向对象_Java的面向对象特征
  4. Android Build.VERSION.SDK_INT兼容介绍
  5. .NET Core on K8S学习实践系列文章索引(持续更新)
  6. Visual Studio“15”启动速度提升
  7. 计算几何 -- 旋转坐标系
  8. CentOS8 模块化仓库
  9. C语言性能优化书籍,Android应用性能优化 (埃尔韦) 中文PDF扫描版
  10. 两片关于NAND FLASH的好博客
  11. scala implicit隐式转化与隐式参数
  12. MySQL 安装 [mysql-5.6.37]
  13. 系统集成项目管理工程师知识点总结(错题记录)
  14. ONGene:基于文献检索的肿瘤基因数据库
  15. 虚拟摄像头(拉rtsp流或桌面作为图像源)
  16. ubuntu系统安装好搜狗输入法后只能输入英文,无法输入中文的解决方案
  17. hdwiki上传附件不显示bug解决办法
  18. 2.16([Usaco2005 Nov]Ant Counting)
  19. 基于php+mysql的村镇干部绩效考核系统
  20. mysql grant用法_十六、MySQL授权命令grant的使用方法

热门文章

  1. ie 报错 vuex requires a Promise polyfill in this browser
  2. 小程序中使用threejs
  3. JAVA-最常用的A题语法
  4. 关于 JS 模块化的最佳实践总结
  5. html 8 盒子的background 颜色的面积
  6. cmake + visual studio 配置出错的解决方法
  7. [转]COM对象创建-外部机制
  8. 有趣设计工作室创始人段先洲:UI设计师的名利场
  9. 职场社交是一个真需求吗?
  10. 深度复盘 | 滴滴专车会员项目如何做好设计优化