(10)大数据外存归并排序

本文深入探讨了大数据环境下如何使用外存归并排序算法,详细解释了该算法的工作原理和实现过程,并结合C++进行了实例演示。通过对磁盘I/O操作的优化,实现了高效的大文件排序解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#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个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值