#include <iostream>
#include <string>
#include <fstream>
using namespace std;
// 可以尝试先写测试用例...
void TestDiskSort();
/*
输入:一个最多含有n个不重复的正整数(也就是说可能含有少于n个不重复正整数)的文件,
其中每个数都小于等于n,且n=10^7。
输出:得到按从小到大升序排列的包含所有输入的整数的列表。
条件:最多有大约1MB的内存空间可用,但磁盘空间足够。
且要求运行时间在5分钟以下,10秒为最佳结果。
10^7:大约1千万
1M:大约1百万
*/
/*
1.数据划分份数的考虑
2.每一份有多少块的考虑
3.每一块有多少数据的考虑
N份数据并行归并排序
一块数据一起读入内存
考虑份数:2^N 8(16)
每一块大小:1K(1024个数据)
数据的来源:应该是文件
1.读入数据,并分配到8个文件中去
a)数据总个数不超过10^7
2.对8个文件进行内部排序
a)内部排序还需要再划分,归并排序
3.对8个文件进行归并排序
*/
/*
位图方案:
牛逼!
用一个超大字符串将所有的数据都扫进去,然后顺次读取为1的位!
位图方法的抽象:
线性记录每一个数出现的次数。
适用范围:数据量大,且数据范围不太大。
不用位图用数组索引,是一样的道理,而且可以处理数据重复出现的情况
针对此问题,将数据线性划分为16块,分16次进行。。。
*/
/*
因为可能是位图大小的限制,因此用了两趟扫描的方法
第一趟扫描小于Max_length,第二趟扫描Max_length到
Num的
*/
// 一千万
const unsigned MAX_NUM = 10000000;
// 每个小文件的大小,默认为10万
const unsigned MAX_LITTLE_FILE_LENGTH = 100000;
// 小文件的前缀名
const string PRE_FILE_NAME = "c:/test/data";
// 位图索引的最大值
const unsigned MAX_BIT_SIZE = MAX_NUM / 2;
// 随机生成num大小个数,并保存在fileName中, 有重复数据
// 大小从0到Max
void InitNumFile(const char *fileName, unsigned num, unsigned MAX_NUM);
// 无重复数据
void InitNumFile_2(const char *fileName, unsigned num, unsigned MAX_NUM);
// 使用位图排序
void DiskSortUsingBitSet(const char *fileName, char *outFileName);
/*
基于数组、链表的排序
内、外排序
*/
/*
K路归并排序
*/
void DiskSortUsingKMerge(const char *fileName, const char *outFileName);
// 分割fileName,并将文件个数传出了
void DivideFile(const char *fileName, unsigned &fileNum);
// 对文件进行内部排序, 并把排序结果重新写入到文件中
void SortFile(const char *fileName);
// 传入qsort的比较函数
int CompareInt(const void *left, const void * right);
void KMergeSort(const char *fileName, fstream *everyFile, unsigned fileNum);
//void KMergeSort(const char *fileName, FILE **everyFile, unsigned fileNum);
// 传入file和i,生成.txt
// file1.txt
string MakeFileName(string file, unsigned i);
// 找到数组中的最小值,并返回index
void FindMin(int *arr, bo
(10)大数据外存归并排序
最新推荐文章于 2024-06-10 14:47:06 发布