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

Apple Pay不能添加卡,不一定是卡的问题,有可能是设备的问题

Apple Pay不能添加卡,不一定是卡的问题,有可能是设备的问题。

wyxtx的博客 3437

RK3588 平台imx334 驱动调试记录

rk3588调试imx334

xiaoning132的专栏 1790

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

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

weixin_64099089的博客 1569

物联网通信中NB-IoT、Cat.1、LTE-M该如何选择?

首先我们要确定我们产品的关键需求,例如:我们的设备是否对数据传输速率有较高的要求,有较高要求我们就需要选择较高传输速率的Cat.1来开发我们的产品。同时关于产品性能方面,我们对功耗、延迟、可靠性也会有所要求,例如我们的产品为移动端产品,不方便布线以及安装电源,那我们就会采用电池供电的方式,所以在选择时可以优先考虑低功耗产品,最终结合其他需求选择出合适的协议。首先,我们需求的产品是不同的,我们需要根据产品需求或项目需求来进行选择,NB-IoT、Cat.1、Cat.M都有属于自己的优势。

a1809032425的博客 1216

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

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

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

Playwright实战:打造绕过全维度前端反爬的无头浏览器爬虫(2026实战版)

Playwright绕过前端反爬的核心是模拟真实:真实的设备指纹、真实的行为轨迹、真实的网络请求;2025年前端反爬的核心检测维度是设备指纹+行为轨迹+网络请求,三者缺一不可;实战中需重点关注WebGL/Canvas指纹模拟、行为随机性、请求头完整性,这是绕过反爬的关键;性能优化需以“不触发反爬”为前提,优先选择浏览器复用、资源拦截,而非无限制并发。

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 2094

Openclaw错误排查及解决方案之:Something went wrong while processing your request. Please try again.

Openclaw错误排查及解决方案之:Something went wrong while processing your request. Please try again.

多媒体编程、网络编程、系统编程、网络安全编程、驱动编程 3788

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

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

weixin_44627813的博客 1724

YOLOv10改进策略【注意力机制篇】| 2024 蒙特卡罗注意力(MCAttn)模块,提高小目标的关注度

本文记录的是基于蒙特卡罗注意力(MCAttn)模块的YOLOv10目标检测改进方法研究。利用提高的跨尺度特征提取能力,使模型能够更好地传递和融合提取的多尺度特征,提高对小目标的关注度。Exploiting Scale-Variant Attention for Segmenting Small Medical Objects使用一种基于随机采样的池化操作来生成尺度无关的注意力图。它从三个不同尺度(3×33×33×3、2×22×22×2和1×11×11×1,即池化张量)中随机选择一个1×11×11×1注意力图

Limiiiing的博客 2187

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

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

Distinguished_z的博客 1094

机器人控制仿真软件:MATLAB Simulink Control System Toolbox_(1).MATLAB基础知识

MATLAB(Matrix Laboratory)是由MathWorks公司开发的一种高性能数值计算和可视化软件。它广泛应用于科学计算、工程设计、信号处理、控制系统设计、图像处理等领域。强大的矩阵运算能力:MATLAB的核心是矩阵运算,能够高效处理大规模的数值数据。丰富的工具箱:MATLAB提供了大量的工具箱,如Control System Toolbox、Simulink、Signal Processing Toolbox等,这些工具箱覆盖了多个应用领域。易于使用的图形界面。

kkchenjj的博客 906

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

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

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

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

KEEP ON KEEPING ON 1293

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

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

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

小梦的博客 2018

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

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

现在为止,我们就已经讲完了初阶数据结构中排序算法的所有内容啦!!!完结撒花!!!但是我们还是需要总结一下排序的内容。数据结构之排序大全(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、付费专栏及课程。

余额充值