数据结构--外部排序

一、外部排序
之前介绍的所有排序算法都是内部排序的算法,也就是说需要将所有数据装入内存再进行排序。但实际上会出现需要排序的数据太多无法全部装入内存的情况,这种情况下排序就是外部排序,外部排序的基本思想就是归并排序。
Tips:
归并排序:两个已排好序的数组,比较它们的第一个元素,选择小(或大)的放入目标数组,然后再比较各自的第一个元素,一直重复至一个数组为空,然后将另一个数组剩余元素一一放入目标数组。

1、排序思路
外部排序的基础思想也是归并。
假设所有数据都在一个文件中,这个文件大小恰好是可用内存的两倍,先从文件中读取一半的数据,然后用内部排序算法将其排序,接着将这一半数据存入一个新的文件。然后再从文件中读取剩下的一半的数据,同样在内存中将其排好序,存入一个新的文件中。最后,打开这两个文件,读取各自的第一个数据,比较后存入一个新文件,再读取、比较、存入……最后数据全部存入这个文件中,完成排序。
在第一次读取源数据的时候(即还没开始第一次归并),每次读取都是读取主存能读取的最大数据量,假设为M,然后形成的单个“有序新文件”记为大小为M的“归并段(顺串)”
2、排序方法及时间
A、2-路平衡归并
举例:一个文件含有10000条记录,通过10次内部排序得到10个初始归并段R1...R10,其中每一段都含有1000个记录。然后两两归并:

image.png

由10个初始归并段得到一个有序文件,共进行了4趟归并,每一趟都从m个归并段得到ceil(m/2)个归并段,这种归并方法称为2-路平衡归并。
B、排序时间
外部排序所需总时间 = 内部排序所需时间(m * tIS) + 外存信息读写时间(d * tIO) + 内部归并所需时间(s * utmg)
其中:
M:经过内部排序之后得到的初始归并段个数
tIS:得到一个初始归并段进行内部排序所需时间的平均值
d:总的读/写文件的次数
tIO:进行一次外存读/写时间的平均值
s:归并的趟数
utmg:对u个记录进行内部归并所需时间
上例中:假设每个物理块(外存上信息的读/写以“物理块”为单位进行的)可以容纳200条记录,则每趟归并(一个归并段存储1000条记录)需进行50次“读”和50次“写”,4趟归并假设内部排序时所需进行的读/写使得在外排中共需进行500次读/写。
则所需外排时间为:10tIS + 500tIO + 4 * 10000utmg
由此可见,提高外排的效率应主要减少外存信息读写的次数d。
C、多路平衡归并
若对上例进行5路平衡归并:
image.png

则仅需两趟归并,总的读/写次数减少为2 * 100 + 100 = 300,比2路归并减少了200次的读/写。

二、胜者树和败者树
外部排序最耗时间的是磁盘读写,使用K路合并可以减少读写磁盘的次数,但会增加算法复杂度,使用败者树可以加快合并排序。
胜者树和败者树都是完全二叉树,是树形选择排序的一种变型。每个叶子结点相当于一个选手,每个中间结点相当于一场比赛,每一层相当于一轮比赛。
不同的是,胜者树的中间结点记录的是胜者的标号;而败者树的中间结点记录的败者的标号。
胜者树与败者树可以在log(n)的时间内找到最值。任何一个叶子结点的值改变后,利用中间结点的信息,还是能够快速地找到最值。在k路归并排序中经常用到。
1、胜者树
胜者树的一个优点是,如果一个选手的值改变了,可以很容易地修改这棵胜者树。只需要沿着从该结点到根结点的路径修改这棵二叉树,而不必改变其他比赛的结果。


image.png

上图是胜者树的示例:
b3 PK b4,b3胜b4负,内部结点ls[4]的值为3;
b3 PK b0,b3胜b0负,内部结点ls[2]的值为3;
b1 PK b2,b1胜b2负,内部结点ls[3]的值为1;
b3 PK b1,b3胜b1负,内部结点ls[1]的值为3。
当叶子结点b3的值变为11时,重构的胜者树如下图所示。
b3 PK b4,b3胜b4负,内部结点ls[4]的值为3;
b3 PK b0,b0胜b3负,内部结点ls[2]的值为0;
b1 PK b2,b1胜b2负,内部结点ls[3]的值为1;
b0 PK b1,b1胜b0负,内部结点ls[1]的值为1。


image.png

2、败者树
败者树是胜者树的一种变体。在败者树中,用父结点记录其左右子结点进行比赛的败者,而让胜者参加下一轮的比赛。败者树的根结点记录的是败者,需要加一个结点来记录整个比赛的胜利者。采用败者树可以简化重构的过程。
image.png

上图是一棵败者树,规定数大者败。
b3 PK b4,b3胜b4负,内部结点ls[4]的值为4;
b3 PK b0,b3胜b0负,内部结点ls[2]的值为0;
b1 PK b2,b1胜b2负,内部结点ls[3]的值为2;
b3 PK b1,b3胜b1负,内部结点ls[1]的值为1;

在根结点ls[1]上又加了一个结点ls[0]=3,记录的最后的胜者。
败者树重构过程如下:
将新进入选择树的结点与其父结点进行比赛:将败者存放在父结点中;而胜者再与上一级的父结点比较。
比赛沿着到根结点的路径不断进行,直到ls[1]处。把败者存放在结点ls[1]中,胜者存放在ls[0]中。


image.png

上图为当b3变为13时,败者树的重构图
败者树的重构跟胜者树是不一样的,败者树的重构只需要与其父结点比较。对照败者树原图来看,b3与结点ls[4]的原值比较,ls[4]中存放的原值是结点4,即b3与b4比较,b3负b4胜,则修改ls[4]的值为结点3。同理,以此类推,沿着根结点不断比赛,直至结束。
由上可知,败者树简化了重构。败者树的重构只是与该结点的父结点的记录有关,而胜者树的重构还与该结点的兄弟结点有关。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,509评论 6 504
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,806评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,875评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,441评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,488评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,365评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,190评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,062评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,500评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,706评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,834评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,559评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,167评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,779评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,912评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,958评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,779评论 2 354

推荐阅读更多精彩内容