排序(二) 外部排序

一 定义

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

二 处理过程

(1)按可用内存的大小,把外存上含有n个记录的文件分成若干个长度为L的子文件,把这些子文件依次读入内存,并利用有效的内部排序方法对它们进行排序,再将排序后得到的有序子文件(又称归并段)重新写入外存;

(2)对这些有序子文件逐趟归并,使其逐渐由小到大,直至得到整个有序文件为止。

先从一个例子来看外排序中的归并是如何进行的?
  假设有一个含10000 个记录的文件,首先通过10 次内部排序得到10 个初始归并段R1~R10 ,其中每一段都含1000 个记录。然后对它们作如图10.11 所示的两两归并,直至得到一个有序文件为止 如下图

败者树

归并的方式最容易想到的是两路归并。

将40个文件编号1-40,1和2归并,3和4归并...39和40归并,生成了20个文件,再将这20个文件继续两路归并。

从40个文件变成20个文件,相当于把所有10G的数据从磁盘读出,再写到磁盘上,从20个文件到10个文件,也相当于把10G的数据从磁盘读出,再写到磁盘上。这种磁盘IO操作一共要执行6次。(2^6=64>40)

再来考虑K路归并。所谓K路归并,就是一次比较K路数据,选出最小的。例如当K=10,则是将40个文件分成1-10,11-20,21-30,31-40。对1-10,由于已序,故只要比较出这10个文件的第一个数,看哪个最小,哪个就写到新文件,再进行下一轮的比较。这样,只要2次磁盘IO就可以了。

假设我们将文件分为m份,使用K路归并,则磁盘IO的次数就是log K底m。我们当然是希望这个值越小越好。但是是不是K越大就越好呢?我们来看看算法的时间复杂度。

对于总共s个数据的K路归并,每次需比较K-1次,才能得出结果中的一个数据,s个数据就需要比较(s-1)(K-1)次

对于总共n个数据,分为m份,使用K路归并,总共需要比较 (log K底m) * (n-1)(K-1)= (logm/logK)*(n-1)(K-1) = logm*(n-1)*(K-1)/logK,当K增大时,(K-1)/logK是增大的,也即时间复杂度是上升的。因此要么K不能太大,要么找出一个新的方法,使得每次不用比较K-1次才得出结果中的一个数据。我们选择后者,由此引出了败者树。

败者树实际上是一棵完全二叉树,败者树重构过程如下:

将新进入选择树的结点与其父结点进行比赛:将败者存放在父结点中;而胜者再与上一级的父结点比较。

比较沿着到根结点的路径不断进行,直到ls[1]处。把败者存放在结点ls[1]中,胜者存放在ls[0]中。

相当于每次ls[0]取的都是当前的最大(最小)值,取完一次后,再读入新的数据,进行新一轮的重构,直到数据读完。

原文地址:https://www.cnblogs.com/carrothhh/p/10765755.html

时间: 2024-11-23 08:55:30

排序(二) 外部排序的相关文章

排序之外部排序

有时,待排序的文件很大,计算机内存不能容纳整个文件,这时候对文件就不能使用内部排序了(这里做一下说明,其实所有的排序都是在内存中做的,这里说的内部排序是指待排序的内容在内存中就可以完成,而外部排序是指待排序的内容不能在内存中一下子完成,它需要做内外存的内容交换),外部排序常采用的排序方法也是归并排序,这种归并方法由两个不同的阶段组成: 1.采用适当的内部排序方法对输入文件的每个片段进行排序,将排好序的片段(成为归并段)写到外部存储器中(通常由一个可用的磁盘作为临时缓冲区),这样临时缓冲区中的每个

二维数组里,根据数组字段为条件,进行总体排序(二维排序)

1 <?php 2 /** 3 * 二维数组根据某个字段排序 4 * 功能:按照用户的年龄倒序排序 5 * @author ruxing.li 6 */ 7 header('Content-Type:text/html;Charset=utf-8'); 8 $arrUsers = array( 9 array( 10 'id' => 1, 11 'name' => '张三', 12 'age' => 25, 13 ), 14 array( 15 'id' => 2, 16 '

算法 排序(二) 选择排序

选择排序(Selection sort)是一种简单直观的排序算法.它的工作原理是每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完. 思想 n个记录的文件的直接选择排序可经过n-1趟直接选择排序得到有序结果: ①初始状态:无序区为R[1..n],有序区为空. ②第1趟排序 在无序区R[1..n]中选出关键字最小的记录R[k],将它与无序区的第1个记录R[1]交换,使R[1..1]和R[2..n]分别变为记录个数增加1个的新有序区和记录个数减

Haoop MapReduce 的Partition和reduce端的二次排序

先贴一张原理图(摘自hadoop权威指南第三版) 实际中看了半天还是不太理解其中的Partition,和reduce端的二次排序,最终根据实验来结果来验证自己的理解 1eg 数据如下 2014010114 标识20140101日的温度为14度,需求为统计每年温度的最最高值 2014010114 2014010216 2014010317 2014010410... Partition 实际是根据map 任务的key,以及reduce任务的数量来决定最终来由那个reduce来处理,默认指定redu

结合手机上网流量业务来说明Hadoop中的二次排序机制,分区机制

本篇博客将结合手机上网流量业务来详细介绍Hadoop的二次排序机制.分区机制,先介绍一下业务场景: 先介绍一下业务场景:统计每个用户的上行流量和,下行流量和,以及总流量和. 本次描述所用数据: 日志格式描述: 日志flowdata.txt中的具体数据: 首先我们先通过mapreduce程序实现上面的业务逻辑: 代码实现: package FlowSum; import java.io.DataInput; import java.io.DataOutput; import java.io.IOE

(转)外部排序

转自:http://www.2cto.com/kf/201307/225189.html 内排序算法我们学了很多,快速排序.冒泡排序等.这些排序的前提是数据量不大,能够全部读进内存里.外排序是指对大数据量进行排序,数据量大到不能全部读进内存里,必须在内存和外存间换进换出进行排序.     最常用的外排序法是归并法.举个例子,对900M的数据进行外排序,但内存只有100M.排序过程: 1.将原数据分组进行排序,每组100M,一共9组. 排序过程是读100M进内存,对这100M进行内排序(用快速排序

Hadoop---mapreduce排序和二次排序以及全排序

自己学习排序和二次排序的知识整理如下. 1.Hadoop的序列化格式介绍:Writable 2.Hadoop的key排序逻辑 3.全排序 4.如何自定义自己的Writable类型 5.如何实现二次排序 1.Hadoop的序列化格式介绍:Writable 要了解和编写MR实现排序必须要知道的第一个知识点就是Writable相关的接口和类,这些是HADOOP自己的序列化格式.更多的可能是要关注他的Subinterfaces:WritableComparable<T>.他是继承Writable和Co

外部排序&amp;多路归并排序

外部排序: 一.定义问题 外部排序指的是大文件的排序,即待排序的记录存储在外存储器上,待排序的文件无法一次装入内存,需要在内存和外部存储器之间进行多次数据交换,以达到排序 整个文件的目的.外部排序最常用的算法是多路归并排序,即将原文件分解成多个能够一次性装入内存的部分,分别把每一部分调入内存完成排序.然后,对已经排 序的子文件进行多路归并排序. 二.处理过程 (1)按可用内存的大小,把外存上含有n个记录的文件分成若干个长度为L的子文件,把这些子文件依次读入内存,并利用有效的内部排序方法对它们进行

外部排序-第11章-《数据结构题集》习题解析-严蔚敏吴伟民版

习题集解析部分 第11章 外部排序 ——<数据结构题集>-严蔚敏.吴伟民版        源码使用说明  链接??? <数据结构-C语言版>(严蔚敏,吴伟民版)课本源码+习题集解析使用说明        课本源码合辑  链接??? <数据结构>课本源码合辑        习题集全解析  链接??? <数据结构题集>习题解析合辑       相关测试数据下载  链接? 数据包       本习题文档的存放目录:数据结构\▼配套习题解析\▼11 外部排序