C语言实现归并排序 -- 归并排序递归版,归并排序非递归版,外排序,文件归并排序

归并排序算法C++实现(超详细解析!!!!) 归并排序,其实就是一种分治算法 ,那么在了解归并排序之前,我们先来看看什么是分治算法。在算法设计中,我们引入分而治之的策略,称为分治算法,其本质就是将一个大规模的问题分解为若干个规模较小的相同子问题,分而治之。 阅读详情

目录

1. 概念

2. 归并排序递归版本的实现

3. 归并排序非递归版本的实现 

4. 归并排序的特性总结 

5. 外排序及文件归并排序

5.1 外排序介绍

5.2 文件归并排序思路

5.3 文件归并排序的代码实现


1. 概念

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

2. 归并排序递归版本的实现

// 归并排序递归实现
void _MergeSort(int* a, int* tmp, int begin, int end)
{
	if (begin == end) //如果区间只有一个值,直接返回
	{
		return;
	}
	int mid = (begin + end) / 2;
	//[begin, mid - 1],[mid, end]这种分割方式会进入死循环,因为除法本事就会丢数据,当为[偶数,         
    //偶数+1]区间时,分出来的右区间还是[偶数,偶数+1]
	//[begin, mid], [mid+1, end]
	//如果[begin, mid], [mid + 1, end]有序,就可以进行归并了
	//使左右区间有序,进行子问题递归
	_MergeSort(a, tmp, begin, mid);
	_MergeSort(a, tmp, mid + 1, end);

	//归并
	int begin1 = begin, end1 = mid;
	int begin2 = mid + 1, end2 = end;
	int i = begin;
	while (begin1 <= end1 && begin2 <= end2)
	{
		if (a[begin1] < a[begin2])
		{
			tmp[i++] = a[begin1++];
		}
		else
		{
			tmp[i++] = a[begin2++];
		}
	}

	while (begin1 <= end1)
	{
		tmp[i++] = a[begin1++];
	}

	while (begin2 <= end2)
	{
		tmp[i++] = a[begin2++];
	}
    //拷贝时一段一段拷贝,拷贝每一段的[begin, end]区间
	memcpy(a+begin, tmp+begin, (end - begin + 1) * sizeof(int));
}

void MergeSort(int* a, int n)
{
	//左区间和右区间有序,借助一个新的数组,取小的尾插
	int* tmp = (int*)malloc(sizeof(int) * n);
	if (tmp == NULL)
	{
		perror("malloc fail!\n");
		exit(1);
	}

	_MergeSort(a, tmp, 0, n - 1);

	free(tmp);
	tmp = NULL;
}

3. 归并排序非递归版本的实现 

        归并排序的非递归实现,就数组从头开始先一一归并,然后再二二归并,然后再四四归并,依次类推。归并排序非递归版本中出现的问题我已经写在了代码中的注释中,也可以将注释的printf语句取消注释,观察每次非递归模拟递归的区间。

// 归并排序非递归实现
void MergeSortNonR(int* a, int n)
{
	int* tmp = (int*)malloc(sizeof(int) * n);
	if (tmp == NULL)
	{
		perror("malloc fail!\n");
		exit(1);
	}

	//gap是每组归并数据子区间的数据个数
	//11归并,gap == 1
	//则每组归并数据子区间的数据个数为1
	int gap = 1;
	while (gap < n)
	{
		//printf("gap = %d->:", gap);
		for (int i = 0; i < n; i += 2 * gap) //11归并,则到下一组归并时要跳2个gap
		{
			//[begin1, end1],[begin2, end2]
			int begin1 = i, end1 = begin1 + gap - 1; //闭区间的结束位置为[左 + gap - 1]
			int begin2 = end1 + 1, end2 = begin2 + gap - 1;

			//printf("[%d, %d],[%d, %d];", begin1, end1, begin2, end2);
			//存在的越界情况,以10个数据为例
			//打印结果:
			//gap = 1->:[0, 0],[1, 1];[2, 2],[3, 3];[4, 4],[5, 5];[6, 6],[7, 7];[8, 8],[9, 
            //9];
			//gap = 2->: [0, 1] , [2, 3];[4, 5], [6, 7];[8, 9], [10, 11];
			//gap = 4-> : [0, 3] , [4, 7];[8, 11], [12, 15];
			//gap = 8-> : [0, 7] , [8, 15];
			//情况1:gap == 8的区间[8, 15],只有end2越界
			//情况2:gap == 2的区间[10, 11],begin2和end2越界
			//情况3:gap == 4的区间[8, 11],[12, 15] end1,begin2和end2越界
			//上述的情况2和情况3可以合为1种情况(则[begin2,end2]区间不存在),该情况下不需要归并
			//这个判断语句处理的是情况2和情况3,当begin2越界的时候,不用处理,当end1越界的时    
            //候,begin2也越界了,也不用处理
			if (begin2 >= n)
			{
				break;
			}

			if (end2 >= n)
			{
				end2 = n - 1;
			}
			//printf("[%d, %d],[%d, %d];", begin1, end1, begin2, end2);

			int j = begin1;
			while (begin1 <= end1 && begin2 <= end2)
			{
				if (a[begin1] < a[begin2])
				{
					tmp[j++] = a[begin1++];
				}
				else
				{
					tmp[j++] = a[begin2++];
				}
			}

			while (begin1 <= end1)
			{
				tmp[j++] = a[begin1++];
			}

			while (begin2 <= end2)
			{
				tmp[j++] = a[begin2++];
			}
            //写end2 - i + 1,是因为在归并的过程中begin1在改变
			memcpy(a + i, tmp + i, (end2 - i + 1) * sizeof(int)); 
		}
		//printf("\n");
		gap *= 2;
	}
	
	free(tmp);
	tmp = NULL;
}

4. 归并排序的特性总结 

  • 归并的缺点在于需要O(N)的空间复杂度,归并排序的思考更多的是解决在磁盘中的外排序问题。
  • 时间复杂度:O(N*logN)
  •  空间复杂度:O(N)
  •  稳定性:稳定

5. 外排序及文件归并排序

5.1 外排序介绍

        外排序(External sorting)是针对无法一次性加载到内存的海量数据的排序算法,核心思想是 “分而治之”,将大规模数据拆分为多个可加载到内存的小数据块,在内存中完成排序后,再通过归并操作合并为有序的完整数据。

        与内排序(如快速排序、堆排序,数据全部在内存中处理)不同,外排序的操作对象是外部存储设备(硬盘、磁带等)上的海量数据,其性能瓶颈主要在于减少磁盘 I/O 次数(磁盘读写速度远低于内存操作)。

        外排序的标准流程分为 两个核心阶段:内存排序(分块) 和 多路归并(合并)。

5.2 文件归并排序思路

  1. 原始文件中依次读取 n 个值排序后写入 file1 中。
  2. 原始文件中依次读取 n 个值排序后写入 file 2 中。
  3. file1 和 file2 利用归并排序的思想,依次读取比较,取小的尾插到 mfile 中,则 mfile 归并为一个有序文件。
  4. 将 file1 和 file2 删掉,mfile 重命名为 file1。
  5. 重复上述第 2,3,4步,直到原始文件数据全部读完,最后归并出的有序数据放到 file1 中。

5.3 文件归并排序的代码实现

#define _CRT_SECURE_NO_WARNINGS 1

#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

void Swap(int* p1, int* p2) {
	int tmp = *p1;
	*p1 = *p2;
	*p2 = tmp;
}

// 创建 n 个随机数,写入到文件中
void CreateNDate(int n) {
	srand((unsigned int)time(0));
	const char* file = "data.txt";
	FILE* fin = fopen(file, "w");
	if (fin == NULL) {
		perror("fopen error");
		return;
	}

	for (int i = 0; i < n; ++i) {
		int x = rand() + i;
		fprintf(fin, "%d\n", x);
	}

	fclose(fin);
}

// 归并排序
void _MergeSort(int* a, int* tmp, int begin, int end) {
	if (begin >= end)
		return;

	// 分区间
	int mid = (begin + end) / 2;
	_MergeSort(a, tmp, begin, mid);
	_MergeSort(a, tmp, mid + 1, end);

	int begin1 = begin, end1 = mid;
	int begin2 = mid + 1, end2 = end;
	int i = begin;
	while (begin1 <= end1 && begin2 <= end2) {
		if (a[begin1] < a[begin2])
			tmp[i++] = a[begin1++];
		else
			tmp[i++] = a[begin2++];
	}
	while (begin1 <= end1)
		tmp[i++] = a[begin1++];
	while (begin2 <= end2)
		tmp[i++] = a[begin2++];

	memcpy(a + begin, tmp + begin, (end - begin + 1) * sizeof(int));
}

void MergeSort(int* arr, int n) {
	if (n <= 1)
		return;

	int* tmp = (int*)malloc(sizeof(int) * n);
	if (tmp == NULL) {
		perror("malloc failed!\n");
		exit(-1);
	}

	_MergeSort(arr, tmp, 0, n - 1);
}

// 从原始文件 fout 中读取 n 个数据,排序后写入到 file 中。返回值为实际读取的数据个数
int ReadNNumSortToFile(FILE* fout, int* a, int n, const char* file) {
	int x = 0;
	int i = 0;
	while (i < n && fscanf(fout, "%d", &x) != EOF)
		a[i++] = x;

	// 一个数据都没读到返回0,说明本次已经是从文件的末尾读了
	if (i == 0)
		return i;

	// 单文件的内排序使用归并排序
	MergeSort(a, i);

	// 打开待写入排序好的元素的文件
	FILE* fin = fopen(file, "w");
	if (fin == NULL) {
		printf("打开%s文件失败\n", file);
		exit(-1);
	}

	// 写入数据
	for (int j = 0; j < i; ++j)
		fprintf(fin, "%d\n", a[j]);

	fclose(fin);
	return i;
}

void MergeSortedFile(const char* file1, const char* file2, const char* mfile) {
	FILE* fout1 = fopen(file1, "r");
	if (fout1 == NULL) {
		printf("打开%s文件失败\n", file1);
		exit(-1);
	}

	FILE* fout2 = fopen(file2, "r");
	if (fout2 == NULL) {
		printf("打开%s文件失败\n", file2);
		exit(-1);
	}

	FILE* fin = fopen(mfile, "w");
	if (fin == NULL) {
		printf("打开%s文件失败\n", mfile);
		exit(-1);
	}

	int num1, num2;
	// ret1,ret2 表示读取到的个数
	int ret1 = fscanf(fout1, "%d\n", &num1);
	int ret2 = fscanf(fout2, "%d\n", &num2);

	while (ret1 != EOF && ret2 != EOF) {
		if (num1 < num2) {
			fprintf(fin, "%d\n", num1);
			ret1 = fscanf(fout1, "%d\n", &num1);
		} else {
			fprintf(fin, "%d\n", num2);
			ret2 = fscanf(fout2, "%d\n", &num2);
		}
	}

	while (ret1 != EOF) {
		fprintf(fin, "%d\n", num1);
		ret1 = fscanf(fout1, "%d\n", &num1);
	}
	while (ret2 != EOF) {
		fprintf(fin, "%d\n", num2);
		ret2 = fscanf(fout2, "%d\n", &num2);
	}

	fclose(fout1);
	fclose(fout2);
	fclose(fin);
}

// n 表示每个数据块的个数
void MergeSortFile(const char* file, int n) {
	// 打开原始待排序文件 file
	FILE* fout = fopen(file, "r");
	if (fout == NULL) {
		printf("打开%s文件失败\n", file);
		exit(-1);
	}

	int i = 0;
	int x = 0;
	const char* file1 = "file1.txt";
	const char* file2 = "file2.txt";
	const char* mfile = "mfile.txt";

	int* a = (int*)malloc(sizeof(int) * n);
	if (a == NULL) {
		perror("malloc failed!\n");
		exit(-1);
	}

	// 从原始文件中分别读取 n 个数据排序后写入 file1,file2
	ReadNNumSortToFile(fout, a, n, file1);
	ReadNNumSortToFile(fout, a, n, file2);

	while (1) {
		// 将 file1,file2 中的数据归并到 mfile 中
		MergeSortedFile(file1, file2, mfile);

		// 删除 file1,file2
		if (remove(file1) != 0 || remove(file2) != 0) {
			perror("remove file failed!\n");
			exit(-1);
		}

		// 将 mifle 重命名为 file1
		if (rename(mfile, file1) != 0) {
			perror("rename filename failed!\n");
			exit(-1);
		}

		// 读取 n 个数据到 file2,继续归并,没数据则归并结束
		if (ReadNNumSortToFile(fout, a, n, file2) == 0)
			break;
	}

	printf("%s文件成功排序到%s\n", file, file1);
	fclose(fout);
	free(a);
}

int main() {
	CreateNDate(1000000);
	MergeSortFile("data.txt", 100000);

	return 0;
}

        注:不管逻辑上分为多少个数据块,在物理层面,文件IO(每次 4KB)的次数都是不变的,物理层面每次文件IO都有“找磁道,找扇区”的过程,但是如果数据块较大的话,操作系统会做连续预读优化,一次IO会预读多个缓冲区的数据(如 8 个 4KB),从而减少文件IO次数。

C++归并排序 今天我们学习了排序中又快又稳定的算法:归并排序,时间复杂度为 O(nlogn)。代码很简洁,很容易懂。 阅读详情

相关推荐

C++排序算法:归并排序详解

C++排序算法:归并排序详解

小天狼星_布莱克 的博客 3万+

java实现归并排序(详解)

归并排序和快速排序都是基于分而治之的算法思想。 归并排序先将待排序的数组不断拆分,直到拆分到区间里只剩下一个元素的时候。不能再拆分的时候。这个时候我们再想办法合并两个有序的数组,得到长度更长的有序数组。当前合并好的有序数组为下一轮得到更长的有序数组做好了准备。一层一层的合并回去,直到整个数组有序。

古城的博客 2万+

C语言实现归并排序

归并排序是一种分治策略的排序算法。它将一个序列分为两个等长(几乎等长)的子序列,分别对子序列进行排序,然后将排序结果合并起来,得到完全有序的序列。这个过程递归进行,直到整个序列有序。归并排序的时间复杂度为O(nlogn),空间复杂度为O(n)。归并的缺点在于需要O(N)的空间复杂度,归并排序的思考更多的是解决在磁盘中的外排序问题。时间复杂度:O(N*logN)空间复杂度:O(N)稳定性:稳定归并排序的特性总结起来主要有四点:稳定性、时间复杂度、空间复杂度和递归性。首先是稳定性。

qq_74013365的博客 2196

Java归并排序

归并排序(Merge Sort)是应用分治思想的一个典型例子。把一个待排序序列拆分为两个子序列,分别对两个子序列排序,子序列排序时也采用相同的方法,直至拆分后的两个子序列都是有序的,即长度为1的序列天然有序,这时停止拆分,将两个有序的子序列归并为一个更大的有序序列,与之前拆分时的路径相反,不断的归并有序子序列,最终归并为一个序列。这种将两个有序序列归并为一个有序序列的操作称为二路归并。

qq_38875964的博客 4058

项目管理中 PMO 的关键职能解析

在企业数字化转型与战略落地的浪潮中,PMO(Project Management Office,项目管理办公室)逐渐从“项目辅助角色”升级为“组织级战略执行中枢”。然而,多数人对PMO的认知仍停留在“管项目的部门”或“文档审核机器”的层面。本文将打破误解,通过生活化类比(如“中枢神经”“导航系统”)、流程图解(战略对齐循环)、实际案例(制造企业PMO升级),深入解析PMO的五大核心职能:战略对齐、流程标准化、资源管理、绩效监控、知识沉淀。最终揭示PMO的本质——

项目管理的博客 1252

Docker Desktop 在 Windows 上的安装和使用

WSL 指 “”,这是一个在 Windows 10\11 上能够运行原生 Linux 二进制可执行文件(ELF格式)的兼容层。它是由微软与Canonical公司合作开发的,旨在使纯正的Ubuntu、Debian等映像能下载和解压到用户的本地计算机,并且映像内的工具和实用工具能在此子系统上原生运行。这极大地拓展了Windows系统的功能,使用户能够在Windows环境中享受到Linux的强大功能。//Linux容器。

swadian2008的博客 6万+

排序(四)——归并排序 + 外排序

目录1.归并排序递归实现代码2.归并排序非递归代码3.比较快排、归并和堆排序4.归并排序实现外排序我们之前对两个有序数组进行排序就用到了归并的思想,对于两个有序数组,我们分别取他们首元素比较大小,取小的插入到一个新开辟的数组中,归并排序的前提就是要有两个有序序列,而且还要开辟一块新的空间来存放新的有序的数组。那么对于一个无序的数组该如何使用归并排序呢这一整个数组我们可以把它分成左右两个区间来看,一个是 [0,4] ,一个是 [5,9] ,而只要这两个区间有序了,我们就有办法通过控制下标来进行归并排序。怎么使

weixin_64099089的博客 1569

Qt + Robot Interface实现上位机和发那科机器人通信

摘要: 本文详细介绍了FANUC机器人的RobotInterface模块开发流程,包括环境配置、通信连接和上位机开发等内容,并提供了数值寄存器、位置寄存器和当前位置的读写代码等示例。适用于自动化行业有通讯需求的上位机开发人员,保姆教程,超详细版,新手也可以根据示例开发自己的通信程序。

xyhkma的博客 1750

【数据结构初阶】十一、归并排序(比较排序)的讲解和实现(递归版本 + 非递归版本 -- C语言实现)

归并排序(比较排序)的讲解和实现(递归版本 + 非递归版本 -- C语言实现):常见排序算法的实现(续上期); 对应代码(续上期)

正在努力学C呀!(要学好久呢......) 1571

【推荐100个unity插件】Animator 的替代品?—— Animancer Pro插件的使用介绍

Animancer与Unity Animator对比及使用指南 摘要: 本文对比了Animancer与Unity官方Animator的核心差异,分析了Animancer的优势特点。Animancer采用代码驱动模式,相比Animator的状态机系统更灵活高效,支持实时调试、动态混合和深度逻辑集成。文章详细介绍了Animancer的快速使用方法,包括动画播放、切换和触发机制,并区分了免费版与专业版的功能差异。适合需要高效动画开发、复杂交互逻辑的中小项目,为开发者提供了一种现代化的动画解决方案。

向宇的博客,专注php/web全栈 unity游戏开发,欢迎大家评论纠错 2434

C#实战YOLO26物体检测:从ONNX模型转换到工业级部署全复盘

本文介绍了在C#上位机中集成YOLO26模型实现工业产线零件检测的实战方案。针对工业场景对实时性(单帧推理≤100ms)、轻量化和易部署的需求,选择YOLO26模型相比YOLOv8在推理速度提升30%且模型体积更小。文章详细拆解了从模型转换(PyTorch转ONNX)、C#推理引擎封装到部署优化的全流程,重点解决了ONNX兼容性、坐标偏移、GPU降级等工业落地中的典型问题。通过解耦设计、性能优化和异常处理机制,最终在工控机(i5-8500+GTX1650)上实现60ms的单帧推理速度,为工业检测项目提供了可

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 1325

归并排序(递归实现、非递归实现)、磁盘中的外排序

前言 归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。其中二路归并类似二叉树的后序遍历。归并排序的思考更多的是解决在磁盘中的外排序问题。 主要思路: ■ 先将待排序的序列分割为小的序列,使每个子序列有序。 ■ 将小的子序列合并为更大的子序列,即使子序列段间有序。合并到最后整个序列有序。 过程演示 递归实现归并排序 C语言代码实现 //将已有序的小区间合并为更大的有序区间,其中合并取得是闭区间。 v

weixin_44627813的博客 1724

Android AVB 分析(十三)dm-verity 设备是如何映射的?

在上一篇《Android AVB 分析(十二)嵌入式设备安全中的 dm-verity 简介》介绍 dm-verity 原理的时候,作者提供了一个 dm-verity 演示的例子。本篇我们基于 AOSP 源码 `android-13.0.0_r41` 实际编译生成的 Google Pixel 7 (“panther”) 设备的 system 分区镜像进行 dm-verity 设备验证实战。

洛奇看世界 2438

数据结构与算法 - 归并排序 #递归版本 #非递归版本 #文件归并

1、归并排序(MERGE-SORT) 是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer) (分治可以理解为递归) 的一个非常典型的应用。将有序的子序列进行合并得到完全有序的序列;即先使每个子序列有序,再使得子序列段间有序。 若将两个有序的子序列合并为一个有序的序列,称为二路归并; 2、外排序(External sorting)是能够处理极大数据量的排序算法;通常来说,外排序的数据不能一次性全部装入内存之中,只能放在读写较慢的外存储器之中(eg.硬盘)。外排

Distinguished_z的博客 1094

DeepSeek网页版和DeepSeek Harness

DeepSeek网页版是开箱即用的对话工具,适合快速问答与日常任务;而DeepSeekHarness(dsh)是基于Node.js的开源智能体框架,支持文件操作、命令执行、多工具协同,实现“对话即执行”。二者定位不同:网页版为“大脑”,Harness为“躯体”。前者封闭易用,后者开放可扩展,具备可追溯的执行日志与插件化架构。未来,网页版将聚焦轻量化普及,Harness则致力于构建生态平台。对开发者而言,应将AI作为执行层,守住决策层,深耕垂直领域,并掌握AI工作流设计能力,以构建不可替代的技术优势。

几十年资深高级架构师,技术专家的技术笔记。专注C、Java、Python、微服务、云原生、AI工程化及高并发系统分布式架构实战,分享源码剖析、性能调优与架构治理经验。 902

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

【基础算法】归并排序(C语言)

归并排序是利用分治法进行排序,简单来说是把两个有序数组拼合成一个有序数组(此文默认按升序)我们现在有两个有序数组,要怎么将它合并成一个呢?让begin1和begin2比较,较小的那个移动到创建的新数组中,可以看到现在begin1所指向的值更小,所以将1移到下面数组中,并将现在begin2更小,所以将2移到下面的数组中,并将接下来也一样,直到数据排完为止当其中的一个数组排完后,就可以将另一个数组中剩下的值都移到新数组中现在左边的数组已经排完了,就可以将右边数组的数据都移到新数组中。

KEEP ON KEEPING ON 1293

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

追梦之旅【数据结构篇】——C语言手撕八大经典排序

C语言手撕数据结构八大经典排序~

小梦的博客 2018

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

数据结构之深入探索归并排序

现在为止,我们就已经讲完了初阶数据结构中排序算法的所有内容啦!!!完结撒花!!!但是我们还是需要总结一下排序的内容。数据结构之排序大全(1)-优快云博客数据结构之排序大全(1)-优快云博客数据结构之排序大全(3)-优快云博客数据结构之排序大全(4)-优快云博客数据结构之深入探索快速排序-优快云博客。

pusue_the_sun的博客 996

(排序10)归并排序的外排序应用(文件排序)

学习小结

C/C++工程师 712

一文彻底搞清楚数据结构之快速排序和归并排序的深入优化

本文介绍了快速排序和归并排序的优化方法,重点分析了快速排序性能的关键点及三路划分算法。文章指出快速排序性能取决于每次单趟排序后key对数组的分割情况,并提出当数组中有大量重复数据时,传统方法效率会下降。针对这一问题,详细讲解了三路划分算法的核心思想:将数组分为小于key、等于key和大于key三部分,并给出了相应的代码实现。通过对比hoare、lomuto和三路划分三种单趟排序方法在不同数据情况下的表现,展示了三路划分在处理重复数据时的优势。该优化方法能有效提升快速排序在特定场景下的性能表现。

承于所学,探技术之渊;以代码求政,寻成长之道。 2298

【C语言】八大排序算法

本文详细介绍了数据结构的排序算法,结合动图,基本思想,解析,代码,你也可以手撕算法。

weixin_63449996的博客 2万+

【数据结构入门】排序算法(4)归并排序

归并排序的递归实现、非递归实现、外排序面试题

欢迎来到我的博客,有问题可以联系:luoshuaishuai2001@163.com 957

【数据结构】排序的拓展——快速排序的生态多样性与归并排序沾染文件操作

排序算法的拓展——三路划分快速排序,自省快速排序,文件归并排序和非递归实现归并排序

2502_94043640的博客 466

各种排序的C语言实现(直接插入排序,希尔排序,选择排序,堆排序,冒泡排序,快速排序(递归)(三种方法实现),快速排序(非递归),计数排序)

像一些不太常用的排序方法如:基数排序,快速排序(三路划分),以及外排序等,有需要的老铁可以在评论区说一下,呼声高的后续会补充。这是计数排序,计数排序的优缺点很明显,优点是对较集中的是数据可以快速排序,缺点是无法处理大量不集中的数据。这是快速排序非递归方法,可以有效避免栈溢出,但需要提前实现栈的相关操作。这是选择排序的改良版,一趟可直接找到最小以及最大的两个数。这是快速排序的三种实现方法,同时这是递归版本。这是头文件,大家可以先预览一下。这是归并排序的递归版本。这是向下建堆法的堆排序。这是冒泡排序的改良版。

2501_93289678的博客 52

数据结构与算法⑰(第五章_八大排序)(完整代码+动图+详解+对比)

数据结构与算法⑰(第五章_八大排序)(完整代码+动图+详解+复杂度和稳定性对比+关于排序的选择题)此篇是此专栏最后一篇了,还有些高阶数据结构在后面点再更新。下一篇开始C++。

参考书籍:《C语言程序设计》《数据结构》《C++ Primer》《Effective C++》《STL源码剖析》《现代操作系统》《UNIX环境高级编程》《图解TCP/IP》《图解HTTP》《Linux高性能服务器编程》《剑指Offer》《算法导论》 1944
上一篇: C语言实现多种快速排序 -- hoare 版本,挖坑法版本,前后指针版本,非递归版本,三数取中,小区间优化,三路划分
下一篇: C++入门基础 -- 命名空间,C++中的输入输出,函数的缺省参数,函数重载,引用,inline,nullptr
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值