外部排序
原理
1,通过归并排序执行
2,构造初始归并段
分批次将磁盘中的两个块读入内存中,进行内部排序,
然后写回磁盘,合成一个包含两个小块的初始归并段
3,第一趟归并
对两个有序初始归并段执行归并
分别读取两者中较小的块到内存执行排序,然后输出到磁盘
一旦有缓冲区空了就从对应的初始归并段补充数据
最后归并为一个更长的归并段
4,第二趟归并
和第一趟归并思路一样,只是序列更长
时间开销
排序时间等于读写内外存时间和内部排序时间
1,优化:多路归并
可以减少归并趟数,减少读写次数
2,优化,减少初始归并段数量(构建更长的序列)
败者树
原理
多路归并会增加关键字对比的次数,增加内部归并排序时间。
1,先由n个节点进行对比,结果存在树中非叶节点,根节点为冠军,冠军自动退出。
2,由新节点替代冠军在叶节点的位置,重新进行对比,只需和自己这一边的树上对比即可。对比次数减少
应用
根节点记录冠军
非叶节点记录失败者
叶节点对应归并段
第一次构建对比k-1次
此后基于败者树,只需logk次
置换选择排序
通过置换选择排序可以减少初始归并段数量
之前的算法中,受到内存工作区限制,初始归并段较短,数量较多,增加了IO次数
可以直接增加内存,提升初始归并段长度
思路
每次都将内存中的最小元素置换出去。
然后从外存中读取一个元素补充到内存中,然后将内存中最小元素与初始归并段最后一个(最大)元素对比,如果比初始归并段最后一个元素大,就可以继续置换
如果内存中最小元素小于大于初始归并段中最大元素,则标记该元素,然后选择内存中其他元素对比,继续置换
如果内存中所有元素都比初始归并段最后一个元素小,则该归并段在此截止,执行构建第二个归并段。
直到待排序列都归并到初始归并段为止。置换选择排序可以使得初始归并段突破内存大小的限制。
最佳归并树
二路归并
在归并过程中,IO次数等于归并树的带权路径长度
WPL计算,叶子节点的权值乘以路径长度。
构造哈夫曼树即可实现最小带权路径长度,从而减少IO次数
多路归并
对k路归并,要保证构建严格的k叉树,如果节点数量不够,则应该添加权值为0的节点。
从初始归并段中选择权值最小的3个构建归并树,然后将孩子节点加入序列中继续构建归并树。
其实这个也不用记,直接在草稿纸画一下草图,一看缺几个就补上几个,然后构建哈夫曼树