位图排序、多路归并排序-应对磁盘文件排序
2016-12-13 17:08
351 查看
注意
位图排序的程序效率是最快的,约为14s,而采用上述的多路归并算法的程序运行时间约为25s。时间主要浪费在读写磁盘IO上,且程序中用的库函数qsort也耗费了不少时间。所以,总的来说,采取位图方案是最佳方案。归并排序和快速排序比较:
归并排序的最大特点是,它是一种稳定的排序方法。归并排序一般多用于外排序。
归并排序在内排方面也占有重要地位,因为它是基于比较的时间复杂度为O(N*Log(N))的排序算法中唯一稳定的排序,所以在需要稳定内排序时通常会选择归并排序。
归并排序不要求对序列可以很快地进行随机访问,所以在链表排序的实现中很受欢迎。
二路归并排序:
过程的核心操作是将一维数组中相邻的两个有序表归并为一个有序表多路归并排序:
当数据量大到不适合在内存中排序时,多路归并算法对磁盘文件进行排序。文章详解(http://blog.csdn.net/v_JULY_v/article/details/6451990)
如何给磁盘文件排序
问题描述:
输入:给定一个文件,里面最多含有n个不重复的正整数(也就是说可能含有少于n个不重复正整数),且其中每个数都小于等于n,n=10^7。输出:得到按从小到大升序排列的包含所有输入的整数的列表。
条件:最多有大约1MB的内存空间可用,但磁盘空间足够。且要求运行时间在5分钟以下,10秒为最佳结果。
分析文件大小:
10^7 = 1000,0000 = 10,000,000一个数据=1B,那么大约为10M
归并排序(二路归并排序):
你可能会想到把磁盘文件进行归并排序,但题目要求你只有1MB的内存空间可用,所以,归并排序这个方法不行。位图排序:
用一个20位长的字符串来表示一个所有元素都小于20的简单的非负整数集合?
{1,2,3,5,8,13}:0 1 1 1 0 1 0 0 1 0 0 0 0 1 0 0 0 0 0 0上述集合中各数对应的位置则置1,没有对应的数的位置则置0
适用范围:
针对不重复的数据进行排序位图排序需要空间大小计算
第一次,只处理1—4999999之间的数据,这些数都是小于5000000的,对这些数进行位图排序,只需要约5000000/8=625000Byte,也就是0.625M,排序后输出。第二次,扫描输入文件时,只处理4999999-10000000的数据项,也只需要0.625M(可以使用第一次处理申请的内存)。
因此,总共也只需要0.625M
外排序(快速排序+多路归并排序):
内存中快速排序
由于要求的可用内存为1MB,那么每次可以在内存中对250K的数据进行排序,然后将有序的数写入硬盘。那么10M的数据需要循环40次,最终产生40个有序的文件。
多路归并排序
将每个文件最开始的数读入(由于有序,所以为该文件最小数),存放在一个大小为40的first_data数组中;选择first_data数组中最小的数min_data,及其对应的文件索引index;
将first_data数组中最小的数写入文件result,然后更新数组first_data(根据index读取该文件下一个数代替min_data);
判断是否所有数据都读取完毕,否则返回2。
多路归并程序的流程图:
第一步、Memory Sort。第二步、Merge Sort。
相关文章推荐
- B(B-)树、B+树、字典(trie)树、外部多路归并排序、败者树外部排序
- 数据结构 外部排序 多路归并排序
- 排序4:多路归并排序之预备:胜者树与败者树
- 归并排序+外部排序(多路归并排序)
- 外排序(磁盘排序)之多路归并排序的简单实现 C++
- 外排序(磁盘排序)之多路归并排序的简单实现(转)
- 外排序(磁盘排序)之多路归并排序的简单实现
- 【数据结构】:排序--归并排序
- 程序员必知的8大排序(四)-------归并排序,基数排序(java实现)
- 快速排序和归并排序
- 排序总结:堆排序、快速排序、归并排序、基数排序
- 七大内部排序算法总结(插入排序、希尔排序、冒泡排序、简单选择排序、快速排序、归并排序、堆排序)
- MIT6.006Lec03:插入排序,归并排序,递归树
- 排序算法复习(Java实现):插入,冒泡,选择,Shell,快速排序, 归并排序,堆排序,桶式排序,基数排序
- 经典排序之归并排序
- 希尔排序,基数排序,归并排序
- java排序之归并排序
- 堆排序,快速选择排序,快速选择排序,归并排序的c++实现
- 4.比较排序之归并排序(递归)
- 算法导论1:插入排序和归并排序 2016.1.1