10_外部排序
外排序

外排所需总的时间为: 外排所需总的时间为:
m*tIS + d*tIO + S*u*tmg = 10*tIS + 500*tIO + 4*10000*tmg
示例: 示例:
• 设有一个包含4500个对象的输入文件。现 设有一个包含4500个对象的输入文件。 个对象的输入文件 用一台其内存至多可容纳750个对象 内存至多可容纳 个对象的计 用一台其内存至多可容纳750个对象的计 算机对该文件进行排序。输入文件放在磁 算机对该文件进行排序。 盘上,磁盘每个页块可容纳250个对象 每个页块可容纳 个对象, 盘上,磁盘每个页块可容纳250个对象, 250= 这样全部对象可存储在 4500 / 250=18 个 页块中。输出文件也放在磁盘上,用以存 页块中。输出文件也放在磁盘上, 放归并结果。 放归并结果。
一、外排序的基本过程
• 当对象以文件形式存放于磁盘上的时候,通常 当对象以文件形式存放于磁盘上的时候, 是按物理块存储的。 是按物理块存储的。 • 物理块也叫做页块,是磁盘存取的基本单位。 物理块也叫做页块,是磁盘存取的基本单位。
• 每个页块可以存放几个对象。操作系统按 每个页块可以存放几个对象。 页块对磁盘上的信息进行读写。 页块对磁盘上的信息进行读写。 • 本节所指的磁盘是由若干片磁盘组成的磁 盘组, 盘组,各个盘片安装在同一主轴上高速旋 转。各个盘面上半径相同的磁道构成了柱 各盘面设置一个读写磁头, 面。各盘面设置一个读写磁头,它们装在 同一动臂上, 同一动臂上,可以径向从一个柱面移到另 一个柱面上。 一个柱面上。
硬盘简介 磁盘的主要技术指标 柱面:多个盘片的同一磁道。 柱面:多个盘片的同一磁道。 目前常见的硬盘容量有 6.2GB、10GB、20GB、 、 、 、 40GB、60GB、80GB等等。 、 等等。 、 等等
第11章 外部排序

多路平衡归并的实现
二、胜者树及其使用 4路平衡归并
1 5
2 5
1234567 5 5 9 5 7 29 9
3 9
4
5
6
7
5
7
29
91
71
59
区
输
5
出
7
缓
冲
区
多路平衡归并的实现
二、胜者树及其使用 4路平衡归并
1
9
123
9 12 9
2
3
12
9
4567 16 12 29 9
4
5
6
7
16
12
29
9
输
5
7
29
9
入
16
12
38
22
缓
49
25
57
47
52
84
66
48
冲
78
91
71
59
区
输
5
出
7
缓
9
冲
区
多路平衡归并的实现
•采用胜者树,从 K 个元素中挑选一个最小的元素仅需 log2m × ( n - 1 ) × tmg 即内部归并时间与k无关, K 增大,归并趟数logkm减少 ,读写外存次数减少,外排总时间减少。
b[0]
b[1] b[2]
b[3]
5
7
29
9
输
5
7
29
9
入
文件外部排序与外部搜索

直接存取文件 (Direct Access File)
•
•
•
又叫散列文件。利用散列技术组织文件。处理 类似散列法,但它是存储在外存上的。 文件记录的逻辑顺序与物理顺序不一定相同。 通过记录的关键码可直接确定该记录的地址。 使用散列函数把关键码集合映射到地址集合时, 往往会产生地址冲突,处理冲突有两种处理方 式: 按桶散列 可扩充散列
7
•
•
•
在磁带设备上读写一块信息所用时间 tIO = ta + tb 其中,ta 是延迟时间,即读写磁头到达待读写 块开始位臵所需花费的时间,它与当前读写磁 头所在位臵有关。tb是对一个块进行读写所用 时间,它等于数据传输时间加上IBG时间。 磁带设备只能用于处理变化少,只进行顺序存 取的大量数据。
12
2. 选定盘片组后再选定某个柱面,并移动动 臂把磁头移到此柱面上。这是机械动作, 速度较慢。这称为“寻查(seek)”。 3. 选定柱面后,要进一步确定磁道,即确定 由哪个读写磁头读写,由电子线路实现。 4. 确定磁道后,还要确定所要读写数据在磁 盘上的位臵(如在哪一个扇区)。这实际 上就是在等待要读写的扇区转到读写磁头 下面。这是机械动作。这段时间一般称为 旋转延迟(rotational delay)时间。 5. 真正进行读写时间。
经过时间 物理记录
传输完成
停止位臵
IBG 0.3~0.75英寸
IBG 0.3~0.75英寸
6
•
•
如果每个逻辑记录是 80个字符,IRG为 0.75英 寸,则对存储密度为 1600BPI 的磁带,一个 逻辑记录仅占 80/1600 = 0.05英寸。每传输一 个逻辑记录磁带走过 0.05英寸,接着磁带要走 过一个IRG占0.75英寸。结果大部分时间都花 费在走空带上,存储利用率只有1/16。 如果将若干逻辑记录存放于一个块,将IRG变 成IBG,可以提高存储利用率。例如,将50个 有80个字符的逻辑记录放在一个块内,此块的 长度将达到5080/1600 = 2.5英寸,存储利用率 达到0.77。因此在磁带上采用按块读写。
第11章外部排序

外部排序
将两个有序段归并成一个有序段的过程, 将两个有序段归并成一个有序段的过程,若 在内存进行,则很简单,上一章中的merge 在内存进行 , 则很简单 , 上一章中的 过程便可实现此归并。 过程便可实现此归并。 由于我们不可能将两个有序段及归并结果段 同时存放在内存中, 同时存放在内存中,在外部排序中实现两两 归并时,不仅要调用merge过程, 而且要进 过程, 归并时 , 不仅要调用 过程 行外存的读/写 行外存的读 写。
11.2 外部排序的方法
外部排序指的是大文件的排序, 外部排序指的是大文件的排序,即待排序的 记录存储在外存储器上, 记录存储在外存储器上,待排序的文件无法 一次装入内存, 一次装入内存,需要在内存和外部存储器之 间进行多次数据交换, 间进行多次数据交换,以达到排序整个文件 的目的。 的目的。 外部排序最常用的是多路归并排序, 外部排序最常用的是多路归并排序,即将原 文件分解成多个能够一次性装人内存的部分, 文件分解成多个能够一次性装人内存的部分, 分别把每一部分调入内存完成排序。然后, 分别把每一部分调入内存完成排序。然后, 对已经排序的子文件进行归并排序。 对已经排序的子文件进行归并排序。
按字符组(记录 存放 按字符组 记录)存放。 记录 存放。 磁带上相邻两组字符组之间要留一空白区, 磁带上相邻两组字符组之间要留一空白区, 叫做间隙IRG(Inter Record Gap)。通常为 叫做间隙 。 1/4~3/4英寸。 英寸。 英寸 组成块可减少IRG数目,可减少 操作。 数目, 操作。 组成块可减少 数目 可减少I/O操作
分析d和 归并过程”的关系: 分析 和“归并过程”的关系: 若对10个初始归并段进行 路平衡归并, 个初始归并段进行5-路平衡归并 若对 个初始归并段进行 路平衡归并,即 每一趟将5个或 个或5个以下的有序子文件归并成 每一趟将 个或 个以下的有序子文件归并成 一个有序子文件,仅需进行二趟归并, 一个有序子文件,仅需进行二趟归并,外排 时总的读/写次数便减至 写次数便减至2*100+100=300, 时总的读 写次数便减至 路归并减少了200次的读 写。 次的读/写 比2-路归并减少了 路归并减少了 次的读
外部排序技术之多路归并

外部排序技术之多路归并外部排序技术之多路归并重点:败者树的创建调整函数1.外部排序概述外部排序指的是⼤⽂件的排序,即待排序的记录存储在外存储器上,待排序的⽂件⽆法⼀次装⼊内存,需要在内存和外部存储器之间进⾏多次数据交换,以达到排序整个⽂件的⽬的。
外部排序最常⽤的算法是多路归并排序,即将原⽂件分解成多个能够⼀次性装⼈内存的部分,分别把每⼀部分调⼊内存完成排序。
然后,对已经排序的⼦⽂件进⾏归并排序。
2. 多路归并的实现2.1 胜者树胜者进⼊下⼀轮,直⾄决出本次⽐赛的冠军。
决出冠军之后,充分利⽤上⼀次⽐赛的结果,使得更快地挑出亚军、第三名 …… 。
⽰例:我们这⾥以四路归并为例,假设每个归并段已经在输⼊缓冲区如下图。
每路的第⼀个元素为胜利树的叶⼦节点,(5,7)⽐较出5胜出成为其根节点,(29,9)⽐较9胜出成为其根节点,⼀次向上⽣成⼀棵胜利树,然后我们可以得出5为冠军,将第⼀路归并段的元素5放⼊输出缓冲区,然后将第⼀路第⼆个元素放到胜利树中如下:由第⼀次得到的胜利树知,我们这⾥只改变了第1路的叶⼦节点,所有根节点7的右⼦树不⽤再⽐较,(16,7)⽐较7胜出,然后7和右⼦树的胜利者⽐较7胜出得到亚军,只进⾏了2次⽐较。
所以我们知道:决出第⼀名需⽐较: k - 1 次决出第⼆名需⽐较:次决出第三名需⽐较:次 .............2.2 败者树与胜利树相类似,败者树是在双亲节点中记录下刚刚进⾏完的这场⽐赛的败者,让胜者去参加更⾼⼀层的⽐赛。
⽰例:我们这⾥以四路归并为例,假设每个归并段已经在输⼊缓冲区如下图。
每路的第⼀个元素为胜利树的叶⼦节点,(5,7)⽐较出5胜出7失败成为其根节点,(29,9)⽐较9胜出29失败成为其根节点,胜者(5,9)进⾏下次的⽐赛7失败成为其根节点5胜出输出到输出缓冲区。
由第⼀路归并段输出,所有将第⼀路归并段的第⼆个元素加到叶⼦节点如下图:加⼊叶⼦节点16进⾏第⼆次的⽐较,跟胜利树⼀样,由于右⼦树叶⼦节点没有发⽣变化其右⼦树不⽤再继续⽐较。
内部排序和外部排序

排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存。
我们这里说说八大排序就是内部排序。
当n较大,则应采用时间复杂度为O(nlog2n)的排序方法:快速排序、堆排序或归并排序序。
快速排序:是目前基于比较的内部排序中被认为是最好的方法,当待排序的关键字是随机分布时,快速排序的平均时间最短;基本思想:将一个记录插入到已排序好的有序表中,从而得到一个新,记录数增1的有序表。
即:先将序列的第1个记录看成是一个有序的子序列,然后从第2个记录逐个进行插入,直至整个序列有序为止。
要点:设立哨兵,作为临时存储和判断数组边界之用。
直接插入排序示例:如果碰见一个和插入元素相等的,那么插入元素把想插入的元素放在相等元素的后面。
所以,相等元素的前后顺序没有改变,从原无序序列出去的顺序就是排好序后的顺序,所以插入排序是稳定的。
算法的实现:1.void print(int a[], int n ,int i){2. cout<<i <<":";3.for(int j= 0; j<8; j++){4. cout<<a[j] <<" ";5. }6. cout<<endl;7.}8.9.10.void InsertSort(int a[], int n)11.{12.for(int i= 1; i<n; i++){13.if(a[i] < a[i-1]){ //若第i个元素大于i-1元素,直接插入。
小于的话,移动有序表后插入14.int j= i-1;15.int x = a[i]; //复制为哨兵,即存储待排序元素16. a[i] = a[i-1]; //先后移一个元素17.while(x < a[j]){ //查找在有序表的插入位置18. a[j+1] = a[j];19. j--; //元素后移20. }21. a[j+1] = x; //插入到正确位置22. }23. print(a,n,i); //打印每趟排序的结果24. }25.26.}27.28.int main(){29.int a[8] = {3,1,5,7,2,4,9,6};30. InsertSort(a,8);31. print(a,8,8);32.}效率:时间复杂度:O(n^2).其他的插入排序有二分插入排序,2-路插入排序。
数据结构第十、十一章:排序

14
9.2 交换排序
冒泡排序
排序过程
将第一个记录的关键字与第二个记录的关键字进行比较, 将第一个记录的关键字与第二个记录的关键字进行比较,若 为逆序r[1].key>r[2].key,则交换;然后比较第二个记录与 为逆序 ,则交换; 第三个记录;依次类推,直至第n-1个记录和第 个记录比较 个记录和第n个记录比较 第三个记录;依次类推,直至第 个记录和第 为止——第一趟冒泡排序,结果关键字最大的记录被安置在 第一趟冒泡排序, 为止 第一趟冒泡排序 最后一个记录上 对前n-1个记录进行第二趟冒泡排序,结果使关键字次大的 个记录进行第二趟冒泡排序, 对前 个记录进行第二趟冒泡排序 记录被安置在第n-1个记录位置 记录被安置在第 个记录位置 重复上述过程,直到“ 重复上述过程,直到“在一趟排序过程中没有进行过交换记 录的操作” 录的操作”为止
按待排序记录所在位置
内部排序: 内部排序:待排序记录存放在内存 外部排序: 外部排序:排序过程中需对外存进行访问的排序
稳定排序和不稳定排序 假设Ki=Kj(1≤i≤n,1≤j≤n,i≠j),且在排序前的序列中Ri领先 假设 ( , , ),且在排序前的序列中 领先 ),且在排序前的序列中 于Rj(即i<j)。若在排序后的排序中Ri仍领先于 ,即那些具 ( )。若在排序后的排序中 仍领先于Rj, )。若在排序后的排序中 仍领先于 有相同关键字的记录,经过排序后它们的相对次序仍然保持不变, 有相同关键字的记录,经过排序后它们的相对次序仍然保持不变, 则称这种排序方法是稳定的;反之,若Rj领先于 ,则称所用的 则称这种排序方法是稳定的;反之, 领先于Ri, 领先于 方法是不稳定的。 方法是不稳定的。 按排序依据原则
4
例
外部排序

FI
WA
FO
23
实例:输入文件FI中记录关键字为:51、49、39、46、38、29 、14、61、15、30、1、48、52、3、63、27、4、13、89、 24、46、58、33、76,假定使用的内存可容纳 6 个记录,利 用置换-选择分类法产生初始合并段。 51 38 15 52 4 46 49 39 46 29 14 61 30 1 48 3 63 27 13 89 24 58 33 76 29 38 39 46 49 51 14 61 15 30 1
90 92 97
11
调整败者树的方法
以在b[4]补充15为例
5 4 2 5 2与5比较 4 2 4与2比较
0 6 90 0
1
3 4与3比较
10
1
9 2
20 3
15 6
4
8 5
12 6
调整败者树的方法: 将新补充的结点与其双亲结点比较, 败者留在该双亲结点,胜者继续向上直至树根的双亲
12
建败者树的过程
51 49 39 46 38 29
FI
WA
FO
19
实例:输入文件FI中记录关键字为:51、49、39、46、38、29 、14、61、15、30、1、48、52、3、63、27、4、13、89、 24、46、58、33、76,假定使用的内存可容纳 6 个记录,利 用置换-选择分类法产生初始合并段。 51 38 15 52 4 46 49 39 46 29 14 61 30 1 48 3 63 27 13 89 24 58 33 76 29 51 49 39 46 38 14
[数据结构] (依据:败者树为完全二叉树) 主:b[0.. k] b[0.. k-1]——k个叶结点 ,存放k个输入归并段中当前 参加归并的记录(缓冲区) b[k]——虚拟记录,该关键字取可能的最小值minkey 辅:ls[0.. k-1] ——不含叶结点的败者树 存放最后胜出的编号(ls[0])以及所记录的败者编号 [处理步骤] 建败者树ls[0.. k-1] 重复下列操作直至k路归并完毕
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Run0: {10, 15,…, ∞} Run1: {9, 18,…, ∞} Run2: {20, 22,…, ∞} Run3: {6, 15,…, ∞} Run4: {12, 37,…, ∞} ls[4]
ls[0] 3 ls[1] 1
冠军 (最小对象), 输出段3当前对象
0 ls[2] b0 10 b1 9
创建败者树: 插入b0(10)
3 0
2 ls[3]
4 b4 12
12 37 …
b5 - b3 6
Run3
b0 10 10 b1 9
10 15 …
Run0
b2 20
20 22 …
Run2
21
6 15 …
9 18 …
Run1
败者树-创建
//创建初始失败者树的算法 void CreateLoserTree ( LoserTree &ls) {//已知b[0]到b[k-1]为完全二叉树ls的叶子节点, //其中存有k个关键字;b[k]为辅助节点。 //沿从叶子节点到根节点的k条路径将ls调整为失败者树
败者树
使用“败者树”从 k 个归并段中选最小者,当 k 较大 时 (k 6),选出关键码最小的对象只需比较 log2k
次。
(k 1) log2 m(n 1) log2 k log2 k log2 m(n 1) log2 m(n 1) log2 k
利用败者树,只要内存空间允许, 增大归并路 数 k, 将有效地减少归并树深度, 从而减少读 写磁盘次数 d, 提高外排序的速度。
10 15 …
Run0
2
ls[3]
选中
4
b2 20
20 22 …
Run2
b3 6
Run3
b4 12
12 37 …
6 15 …
9 18 …
Run1
Run4
LoserTree
ls[0] 3
ls[1] 1
ls[2] 0
ls[3] 2
ls[4] 4
13
败者树-调整
自某叶结点b[s]到败者树 根结点ls[0]的调整过程
5 5
5 ls[3]
b5 - b3 6
Run3
5 4 b4 12
12 37 …
b0 10 b1 9
10 15 …
Run0
b2 20
20 22 …
Run2
17
6 15 …
9 18 …
Run1
败者树-创建
3)依次从b[k-1],b[k2],…,b[0]出发调整失败者; 方法:将bi与其父节点指示的 上次比较的失败者相比. ls[2] ls[4] ls[0] 5 ls[1] 5
键码对象时, 最多做 log2k 次 关键码比较。
15
败者树-创建
1)设b[k]为可能的最小值; 2)设初值:ls[i]=k;
ls[0] 5 ls[1] ls[2] ls[4]
初始化败者树
5
5
ls[3]
5
b5 - b3 6
Run3
5 b4 12
12 37 …
b0 10 b1 9
10 15 …
归并趟数s 4 2 1
为了减小d,应该减小s。 s = logkm
减小总读写次数 d的途径:增加归并路数k或减小初始段数m。
tES = m*tIS + d*tIO + s*u*tmg
内部排序所需 总时间 外存读写所需 总时间 内部归并所需 总时间
7
10.2 多路平衡归并排序 k-way Balanced merging
创建败者树: 插入b1(9)
3
2 ls[3]
4 b4 12
12 37 …
b5 - b3 6
Run3
b0 10 b1 9 9
10 15 …
Run0
b2 20
20 22 …
Run2
20
6 15 …
9 18 …
Run1
败者树-创建
3)依次从b[k-1],b[k2],…,b[0]出发调整失败者; 方法:将bi与其父节点指示的 上次比较的失败者相比. ls[2] ls[4] ls[0] 5 3 ls[1] 1
外部排序需要的总时间为:
tES = m*tIS + d*tIO + s*u*tmg
内部排序所需 总时间 外存读写所需 总时间 内部归并所需 总时间
则上例中tES = 10*tIS + 500*tIO + 4*u*tmg
6
因为tIO >> tmg,想要提高外排序的速度,应减少 d. d和归并过程的关系: 归并路数 k 总读写磁盘次数 d 2 500 5 300 10 200
Run0
b2 20
20 22 …
Run2
16
6 15 …
9 18 …
Run1
败者树-创建
3)依次从b[k-1],b[k2],…,b[0]出发调整失败者;
方法:将bi与其父节点指示的 上次比较的失败者相比. ls[2] ls[4] ls[0] 5 ls[1] 5
创建败者树: 插入b4(12)
s(k 1)(n 1) logk m(k 1)(n 1) log2 m (k 1)(n 1) log2 k (k 1) log2 m(n 1) log2 k
随k增长而增长, 增大k,会使得归 并的时间增大
办法:减小k 个对象中选最小的比较次数
9
减小总读写磁盘次数 d的途径1:增加归并路数k
下减少m呢?
减小总读写磁盘次数 d的途径2:减小初始段数m.
25
10.3 置换选择排序
Replacement-Selection Sorting
创建败者树: 插入b2(20)
3
5 ls[3] 2
4 b4 12
12 37 …
b5 - b3 6
Run3
b0 10 b1 9
10 15 …
Run0
b2 20
20 22 …
Run2
19
6 15 …
9 18 …
Run1
败者树-创建
3)依次从b[k-1],b[k2],…,b[0]出发调整失败者; 方法:将bi与其父节点指示的 上次比较的失败者相比. ls[2] ls[4] ls[0] 5 ls[1] 5 1
23
k-merge 算法
归并路数 k 的选择不是越大越好。归并路数 k增大时, 相应需增加输入缓冲区个数。如果可供使用的内存空
间不变,势必要减少每个输入缓冲区的容量,使内外 存交换数据的次数增大。
24
10.3 置换选择排序
归并的趟数:s = logkm m=记录总数n / 内存可容纳的记录数目; 如果减小m,则需要增加内存的使用量。 但是内存的限制是一定的,如何在不增加内存的情况
void k-Merge( LoserTree &ls, External &b ) {//利用败者树将编号从0到k-1的k个输入归并到输出段。 //b[0]到b[k-1]记录k个输入段中当前记录的关键字 for( i =0; i < k; ++i ) input( b[i].key ); //输入 CreateLoserTree(ls); //创建初始败者树 while ( b[ls[0]].key ! = MAXKEY{ q = ls[0]; // q指示当前最小关键字所在段号 output(q); //输出q段中当前记录 input(b[q].key, q); //输入q段中下一个记录 Adjust(ls, q); //调整败者树 } //while }// k-Merge
对于k 路平衡归并,如果有 m 个初始归并段,需要归 并logkm 趟。
s = logkm
6路平衡归并树:36个初始归并段 减小总读写磁盘次数 d的途径1:增加归并路数k
8
10.2 多路平衡归并排序
做内部 k 路归并时,在 k 个对象中选择最小者,需要 顺序比较 k-1 次。 每趟归并 u 个对象需要做(u-1)*(k-1)次比较,s趟归并 总共需要的比较次数为:
b[k].key = MINKEY; //设MINKEY为可能的最小值
for ( i =0; i < k; ++i ) ls[i] = k;//所有中间节点初始化为k
for ( i =k-1; i >=0; --i ) Adjust( ls, i);
}// CreateLoserTree
22
k-merge 算法
败者树-调整
//自某叶结点b[s]到败者树根结点ls[0]的调整算法 void adjust ( LoserTree &ls, int s ) {//从叶结点b[s]开始,依次将当前的b[s]与父结点指示 的失败者进行比较 //将失败者所在归并段的段号记入父节点中。 t = (s + k) / 2; // ls[t] 是b[s]的父节点 while(t > 0) { if (b[s].key > b[ls[t]].key sls[t]; t = t/2; 败者树的高度为 log2k,在每 } 次调整,找下一 个具有最小关 ls[0] = s; }// adjust
1
内容
10.1 外部排序的概念和方法 10.2 多路平衡归并排序
10.3 置换-选择排序
10.4 最佳归并树
2
10.1 外部排序的概念和方法
外排序:基于外部存储设备(或文件)的排序技术就是外
排序。 当待排序的对象数目特别多时,在内存中不能一次处理。 必须把它们以文件的形式存放于外存,排序时再把它们一 部分一部分调入内存进行处理。 在排序过程中必须不断地在内存与外存之间传送数据。 外部存储设备:磁带、磁盘