归并排序

大数据的文件归并排序 试想一个场景,如果一份很大很大的数据需要排序,如果你没有足够的内存放入数据,这样子针对内存的内部排序是无法完成的,所以我们必须依靠磁盘去解决这个问题。 第一 将数据分成若干份(我们这里以10份为例子),每份都接近内存的最大数据量,这样子,将文件上的数据读入内存中,将它排序,结束后我们就可以得到10份有序的文件数据了。 const char* MergeFile(const char* file) { FILE* fout = fopen(file, "r");//传出文件名,打开此文件 if (fout 阅读详情

归并排序的应用场景是当文件太大,没有办法一次行读入内存。则可以考虑归并排序,步骤如下:

1. 先将大文件依次读取,固定长度的数据,然后使用排序算法,将这些数据做内存排序;

2. 将排序好的部分数据存入临时文件中;

3. loop 1~2 直到大文件中的数据,被读完且排序后存入到临时文件中;

4. 读取这N个临时文件,选取最小的做归并排序。

 

归并排序是一种稳定排序方法。

 

程序代码如下,

参考: http://blog.youkuaiyun.com/v_JULY_v/article/details/6451990

但是原文中代码略有错误,如下代码中已经修改过了。

 

void DoSorting(char* file2Sort, char* sortedFile, 
						int number2sort)
{
	this->file2Sort = file2Sort;
	this->sortedFile = sortedFile;
	this->number2sort = number2sort;

	// 文件分块在内存中排序,并且写到临时文件中
	int file_count = MemorySort();
	MergeSort(file_count);

}

int MemorySort()
{
	FILE* fin = fopen(this->file2Sort, "rt");
	int n = 0, file_count = 0; 
	int* array = new int[this->number2sort];

	// 每次读 number2sort 整数 在内存中一次排序,并写入临时文件
	while((n = readData(fin, array, this->number2sort) ) > 0)
	{
		qsort(array, n, sizeof(int), cmp_int); //memory sort quick

		char* fileName = temp_filename(file_count++);
		FILE* tempFile = fopen(fileName, "w");
		printf("write tempal sorted list to file: %s\n", fileName);
		free(fileName);
		writeData(tempFile, array, n);    
        fclose(tempFile); 
	}

	delete [] array;
	fclose(fin);
	return file_count;
}

void writeData(FILE* f, int a[], int n)    
{    
    for(int i = 0; i < n; i++)    
        fprintf(f, "%d ", a[i]);    
}    

int readData(FILE* fin, int* array, int num)
{
	int i = 0;
	while(i < num && (fscanf(fin, "%d", &array[i] )) != EOF)
	{
		i++;
	}
	printf("read %d integer\n", i);
	return i;
}

void MergeSort(int fileCnt)
{
	if(fileCnt <= 0)
	{
		return;
	}

	// 归并临时文件, 同时打开所有文件
	FILE* *fArray = new FILE*[fileCnt];
	for(int i = 0; i < fileCnt; i++)
	{
		char* fileName = temp_filename(i);
		fArray[i] = fopen(fileName, "rt");
		delete fileName;
	}

	int *data = new int[fileCnt];
	bool *hasNext = new bool[fileCnt];
	memset(data, 0, sizeof(int) * fileCnt);
	memset(hasNext, 1, sizeof(bool) * fileCnt);
	for(int i = 0; i < fileCnt; i++)
	{
		if(fscanf(fArray[i], "%d", &data[i]) == EOF)
		{
			hasNext[i] = false;
		}
	}

	FILE* fout = fopen(this->sortedFile, "wt");

	// Merge sort
	while(true)
	{
		// find the min number in all the files 
		// 原文中如下部分有错误, 原文中min=data[0] 当文件0先被读完了,就会发生错误
		int min = INT_MAX;		
		int min_index = -1;
		for(int i = 0; i < fileCnt; i++)
		{
			if(hasNext[i] && min > data[i])
			{
				min = data[i];
				min_index = i;
			}
		}
		if(-1 == min_index)
		{
			break;
		}
		if(fscanf(fArray[min_index], "%d", &data[min_index]) == EOF)
		{
			hasNext[min_index] = false;
		}
		fprintf(fout, "%d ", min);
		printf("%d ", min);
	}

	printf("\n");
	delete [] data;
	delete [] hasNext;
	// close the file and release the memory
	for(int i = 0; i < fileCnt; i++)
	{
		fclose(fArray[i]);
	}
	delete [] fArray;
	fclose(fout);
}


 

归并排序与原地归并排序 归并排序的思想:假设初始序列含有n个记录,则可以看成是n个有序的子序列,每个子序列的长度为1,然后两两归并,得到[n/2]个长度为2或1的有序子序列;再两两归并,如此重复,直至得到一个长度为n的有序序列为止,这种排序方法称为2-路归并排序。其核心操作是将一个一维数组的前后相邻的两个子序列合并为一个有序序列。下图为一个2路归并排序的例子。 阅读详情

相关推荐

S4 codingblock增加客户化字段的一些小问题

今天使用codingblock增加了两个客户化字段后(S4版本),查看常用的几个表 ACDOCA BSEG 等等两个客户化字段安静的出现在表内,以为没有问题了 。结果后来MM那边查看物料凭证时程序直接dump,后来开发查明原因居然是因为财务增加的这两个增强字段的原因。 报错如下图所示: 主要是因为增加了字段后,更新了后台表,但是没有自动更新到视图。就是MSEG表增加了这两个字段,但是呢他对应的视图NSDM_V_MSEG没有增加,导致两边的结构不一致。 所以要解决这个问题,只能在视图NSDM_V_MSEG增

m0_46145967的博客 3919

归并排序详解

摘要:归并排序是我们常用的八大排序中的一种,其排序思路中和快速排序算法一样使用到了递归的思想,同时在归并排序中还用到了一个算法,就是有序数组合并算法。配合递归与有序数组合并算法,归并排序能够高效且稳定的完成排序,归并排序的优点在于其时间复杂度低,稳定性高,但是缺点也是有的,那就是空间复杂度很高。

云杉木屋 2万+

Linux运维踩坑实录:手把手教你修复LVM中PV显示[unknown]的诡异问题

本文详细解析了Linux运维中LVM物理卷(PV)显示[unknown]的故障现象及修复方法。通过分析问题根源、提供标准修复流程和特殊场景处理方案,帮助运维人员快速解决VG容量异常、PV状态丢失等问题,并分享预防措施与最佳实践,确保LVM存储系统的稳定运行。

weixin_26869081的博客 349

常见排序算法之归并排序——归并排序

归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法 (Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序 列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。...

保护小周ღ的博客 2403

私募pp网-私募排行js逆向

在数据采集的学习过程当中,发现了一个有意思的网站,所以记录一下,仅供学习交流,用于其他用途与作者无关。目标:私募基金当中的列表页数据。

zzp28218的博客 1896

STK中的传感器、雷达、发射机、接收机、天线

本文根据STK手册介绍了传感器、雷达、发射机、接收机、天线等对象的基本属性,简略分析了它们的不同之处。

wangyulj的专栏 1万+

归并排序与自然归并排序

1.归并的缺点在于需要O(N)的空间复杂度,归并排序的思考更多的是解决在磁盘中的外排序问题2.时间复杂度:O(N * logN)3.空间复杂度:O(N)4.稳定度:稳定.1.这玩意的思路相比于其它排序其实特别恶心,在生产环境中非常不建议使用,你的项目组成员可能会骂街(除非是这种情况:就比如你的数据结构老师心血来潮让你讲这个,那你也没办法...)2.时间复杂度:遍历了一次:O(n)3.空间复杂度:O(n)

asdssadddd的博客 1145

问题解答:如何不通过修改底层数据库表的方式,给数据库对应的数据结构,增添新的字段?

现在需要将这张表里的内容读取到 ABAP 内表里,并且针对每个行项目,增加一个新的列字段,我随便举个例子,这个列字段名称叫 LENGTH,值为 OBJ_NAME 字段的长度,使用。最笨的办法就是下面这样定义一个新的类型,这个类型的每个字段名称,都来自数据库表 TADIR 的同名字段,在末尾再增添自定义字段 length.其实我们是做 ALV 输出,只需要 ABAP 内表变量的类型,包含 TADIR 数据库表的全部字段,再加上新的 LENGTH 字段即可。这相当于多了一个中间层,没办法直接被 ALV 处理。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 481

归并排序-自底向上的归并排序算法

归并排序 归并排序(Merge Sort)是建立在归并操作上的一种有效,稳定的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。 算法描述 分解: 将原序列分解成length长度的若干子序列 求解子问题: 将相邻的两个子序列调用Merge算法合并成一个有序子序列 合并: 由于整个序列存放在数字a中,排序过程是就地进行的,合并步骤不需要执行

qq_45727976的博客 2990

【局部规划模块轨迹优化算法】EM_planner最大期望滚动优化算法

认知有限,望大家多多包涵,有什么问题也希望能够与大家多交流,共同成长!本文先对EM_planner最大期望滚动优化算法做个简单的介绍,具体内容后续再更,其他模块可以参考去我其他文章提示:以下是本篇文章正文内容。

qq_35635374的博客 760

一文讲透 SAP SD:把报价、订单、交付、开票串成一条可落地的业务闭环

摘要:SAP SD(销售与分销)模块是企业O2C(订单到收款)流程的核心,管理从客户意向到回款的完整链路。该模块围绕销售订单、交付、开票等关键环节,与财务、物料管理等模块深度集成。SD的核心在于主数据管理、单据驱动流程、定价规则引擎和信用风控,通过条件技术实现复杂定价策略,并支持多维度分析。典型应用场景包括多渠道销售企业的价格体系管理、信用控制和物流协同,有效解决销售与交付脱节、财务对账困难等业务痛点。(149字)

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 513

归并排序的一些拓展应用

归并排序的一些拓展问题, 包含小和问题, 逆序对问题, 翻转对问题, 区间和的个数问题.

trong_ 的烂笔头 870

OpenHarmony Stage模型深度解剖:从Ability Kit到沙箱隔离的全链路底层原理

基于微内核架构,提供进程管理、内存管理、IPC通信等基础能力:包含V8引擎、ArkTS运行时、渲染引擎等核心组件:Ability Kit框架,提供应用生命周期管理、组件调度等能力:基于Stage模型的应用程序。

m0_67505153的博客 191

排序算法 归并排序(普通归并排序、自然归并排序)

自然归并排序:对于初始给定的数组,通常存在多个长度大于1的已自然排好序的子数组段.例如,若数组a中元素为{4,8,3,7,1,5,6,2},则自然排好序的子数组段有{4,8},{3,7},{1,5,6},{2}.用一次对数组a的线性扫描就足以找出所有这些排好序的子数组段.然后将相邻的排好序的子数组段两两合并,构成更大的排好序的子数组段({3,4,7,8},{1,2,5,6}).继续合并相邻排好序的子数组段,直至整个数组已排好序。(1)申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列。

qq_36511401的博客 1万+

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

链表的归并排序

链表的归并排序是一种高效、稳定的排序算法,非常适合链表这种数据结构。通过分治思想,将链表不断分割并合并,实现了对链表的排序。

2401_86909484的博客 1173

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

数组排序之归并排序

归并排序(Merge Sort)是数组排序算法中一种常见的算法,其主要思想为经典的“分治思想”。本文将介绍数组排序算法中的归并排序,并介绍其相关应用。

山阴少年 2486

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

归并排序及模板

文章目录归并排序理解归并排序模板 归并排序理解 归并排序的主要操作如下: (1)分解。把初始序列分成长度相同的左、右两个子序列,然后把每个子序列再分成更小的两个子序列,直到子序列只包含一个数。这个过程用递归实现。 (2)求解子问题,对子序列排序。最底层的子序列只包含一个数,其实不用排序。 (3)合并。归并两个有序的子序列,这是归并排序的主要操作。比如下面举例,把a[ ]分成两个子序列,比较后存进b...

ker的博客 2050

归并排序算法、多路归并排序

base case:if(left>=right) return; 归并排序左半边,归并排序右半边,合并 void merge_sort(vector<int> &nums,vector<int> reg,int start,int end){ if(start>=end) return ; int mid=(end-start)/2+start; int start1=start,end1=mid; int start2=mid+

大灰狼吃树皮 4003

C++ 归并排序

归并排序的原理: (1)首先,把一个数组以中间元素为界限分成两组; (2)然后“左边数组”和“右边数组”中的元素分别进行比较; (3)最后合并两个已经排好顺序的数组,我们称之为归并排序。 #include &lt;iostream&gt; #include &lt;stdlib.h&gt; using namespace std; /**************************...

辛旭东小小工作室 1316
上一篇: 迷宫问题 (下) 使用Quene 实现
下一篇: 快速排序 及应用
dannyPolyu
博客等级 码龄14年 4粉丝 19原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值