递归实现归并排序与测试各类排序的性能

目录

基本思想

代码实现

时空复杂度

测试各排序性能  


基本思想

        将待排序的数组不断二分,直到每个子数组只包含一个元素或为空。然后通过合并操作将这些子数组逐步合并成较大的有序数组,最终得到完全有序的结果:

下面是递归版本的归并排序实现基本思路:

1、分解:将待排序的数组从中间位置切割成两个子数组

  • 找到中间位置 mid = (left + right) / 2
  • 递归地对左半部分进行归并排序:mergeSort(arr, left, mid)
  • 递归地对右半部分进行归并排序:mergeSort(arr, mid+1, right)

2、合并:将两个已经排好序的子数组合并为一个有序数组

  • 创建一个临时空间 temp[] 来存储合并结果
  • 初始化指针 i 指向左半部分起始位置 left,指针 j 指向右半部分起始位置 mid+1
  • 对于 k = left 到 right 的范围
  • 如果 arr[i] <= arr[j],则把 arr[i] 放入 temp[k] 中,并增加 i 和 k 的值
  • 否则把 arr[j] 放入 temp[k] 中,并增加 j 和 k 的值

3、复制:将临时空间 temp[] 中的元素复制回原数组 arr[]

  • 对于 k = left 到 right 的范围,把 temp[k] 复制到 arr[k]

4、重复执行上述步骤,直到每个子数组只包含一个元素或为空

代码实现

//归并排序(递归部分)
void _MergeSort(int* a, int begin, int end, int* tmp)
{
    //当递归至只有一个元素时就返回
	if (begin >= end)
		return;

    //找到中间位置
	int mid = (begin + end) / 2;
	// [begin, mid][mid+1, end]
	_MergeSort(a, begin, mid, tmp);
	_MergeSort(a, mid + 1, end, tmp);

	// [begin, mid][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, sizeof(int) * (end - begin + 1));
}

//归并排序主体函数
void MergeSort(int* a, int n)
{
	int* tmp = (int*)malloc(sizeof(int) * n);
	if (tmp == NULL)
	{
		perror("malloc fail");
		return;
	}

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

	free(tmp);
}

时空复杂度

最坏时间复杂度:O(N*logN)(logN层,递归N次,N*logN)

空间复杂度:O(N)(归并排序需要额外的空间来存储临时结果和辅助变量。对于每一层递归调用,在合并阶段都需要创建一个与原始输入大小相同的临时数组来存储结果,并在每次迭代结束后释放该内存。因此,在最坏情况下,即所有层级上同时存在(但不重叠)的子问题数量达到最大时,所需额外空间总量达到 O(n) 级别

测试各排序性能  

void TestOP()
{
	srand(time(0));
	const int N = 10000000;
	int* a1 = (int*)malloc(sizeof(int) * N);
	int* a2 = (int*)malloc(sizeof(int) * N);
	int* a3 = (int*)malloc(sizeof(int) * N);
	int* a4 = (int*)malloc(sizeof(int) * N);
	int* a5 = (int*)malloc(sizeof(int) * N);
	int* a6 = (int*)malloc(sizeof(int) * N);
	int* a7 = (int*)malloc(sizeof(int) * N);

	for (int i = 0; i < N; ++i)
	{
		a1[i] = rand();
		a2[i] = a1[i];
		a3[i] = a1[i];
		a4[i] = a1[i];
		a5[i] = a1[i];
		a6[i] = a1[i];
		a7[i] = a1[i];
	}

	int begin1 = clock();
	//InsertSort(a1, N);
	int end1 = clock();

	int begin2 = clock();
	ShellSort(a2, N);
	int end2 = clock();

	int begin3 = clock();
	//SelectSort(a3, N);
	int end3 = clock();

	int begin4 = clock();
	HeapSort(a4, N);
	int end4 = clock();

	int begin5 = clock();
	QuickSort(a5, 0, N - 1);
	int end5 = clock();

	int begin6 = clock();
	MergeSort(a6, N);
	int end6 = clock();

	int begin7 = clock();
	//BubbleSort(a7, N);
	int end7 = clock();

	printf("InsertSort:%d\n", end1 - begin1);
	printf("ShellSort:%d\n", end2 - begin2);
	printf("SelectSort:%d\n", end3 - begin3);
	printf("HeapSort:%d\n", end4 - begin4);
	printf("QuickSort:%d\n", end5 - begin5);
	printf("MergeSort:%d\n", end6 - begin6);
	printf("BubbleSort:%d\n", end7 - begin7);

	free(a1);
	free(a2);
	free(a3);
	free(a4);
	free(a5);
	free(a6);
	free(a7);
}

~over~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/257623.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux(4)-LAMP

L-LinuxA-apache/nginxM-mysqlp-php 搭建LAMP以及使用discuz搭建论坛网站 安装apache yum install httpd -y // 安装service httpd start // 启动Apache通过netstat -tunlp查看apache运行的端口&#xff0c;然后打开虚拟机ip 80端口能看到以下页面 或者 安装Mysql centOS6…

Python Pandas 重复值处理(第12讲)

Python Pandas 重复值处理(第12讲)         🍹博主 侯小啾 感谢您的支持与信赖。☀️ 🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔…

基于JAVA的农村物流配送系统 开源项目

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 系统登录、注册界面2.2 系统功能2.2.1 快递信息管理&#xff1a;2.2.2 位置信息管理&#xff1a;2.2.3 配送人员分配&#xff1a;2.2.4 路线规划&#xff1a;2.2.5 个人中心&#xff1a;2.2.6 退换快递处理&#xff1a;…

yolov5障碍物识别-雪糕筒识别(代码+教程)

简介 这是一个检测交通锥并识别颜色的项目。我使用 yolov5 来训练和检测视锥细胞。此外&#xff0c;我使用 k 均值来确定主色&#xff0c;以对锥体颜色进行分类。目前&#xff0c;支持的颜色为红色、黄色、绿色和蓝色。其他颜色被归类为未知。 数据集和注释 我使用了一个自收…

SpringCloudAliBaba篇之Seata:分布式事务组件理论与实践

1、事务简介 事务(Transaction)是访问并可能更新数据库中各种数据项的一个程序执行单元(unit)。在关系数据库中&#xff0c;一个事务由一组SQL语句组成&#xff0c;事务具有4个属性&#xff1a;原子性、一致性、隔离性、持久性。这四个属性通常称为ACID原则。 原子性(atomici…

开源学习项目推荐

文章目录 koodo-reader凤凰架构学习项目NPS 内网穿透客户端 koodo-reader 项目地址&#xff1a;https://github.com/koodo-reader/koodo-reader 介绍&#xff1a;一个开源的阅读器&#xff0c;阅读pdf也有目录&#xff0c;作为epub阅读器和pdf阅读器看资料挺好 凤凰架构 项…

前端视角看 Docker :在国内的基础配置教程(含国内镜像源)

引言 在国内使用Docker时&#xff0c;直接从Docker Hub拉取镜像可能会遇到网络速度慢的问题。配置国内的镜像加速器可以显著提升拉取速度。本教程将指导您完成安装Docker后的基础配置&#xff0c;特别是设置国内镜像加速器。 1. 安装Docker 确保您已在系统上安装Docker。根…

基于Tkinter制作简易的CAN bootloader上位机

文章目录 1.前言2.测试设备3.上位机3.1 参考资料3.2 上位机主要功能3.3 上位机发送流程 升级测试例程分享 1.前言 之前基于S32K144EVB和Tkinter编写了一个简易的串口bootloader上位机&#xff0c;链接如下&#xff1a; 基于Tkinter制作简易的串口bootloader上位机 (qq.com) …

归一化和标准化(Z-Score)

在处理数据过程中&#xff0c;通常会有不同规格的数据&#xff0c;比如年龄的取值范围是0-130&#xff0c;收入的取值范围是0-100000等等&#xff0c;如果不进行归一化或标准化处理&#xff0c;梯度下降每次走过的相对长度就不一样&#xff0c;就导致某个参数很快就找到了最优解…

如何预防[[MyFile@waifu.club]].wis [[backup@waifu.club]].wis勒索病毒感染您的计算机?

导言&#xff1a; 近期&#xff0c;一种新兴的威胁[[MyFilewaifu.club]].wis [[backupwaifu.club]].wis勒索病毒&#xff0c;引起了广泛关注。这种恶意软件通过其高度复杂的加密算法&#xff0c;威胁着用户和组织的数据安全。本文将深入介绍[[MyFilewaifu.club]].wis [[backup…

Linux软件管理rpm和yum

rpm方式管理 rpm软件包名称: 软件名称 版本号(主版本、次版本、修订号) 操作系统 -----90%的规律 #有依赖关系,不能自动解决依赖关系。 举例&#xff1a;openssh-6.6.1p1-31.el7.x86_64.rpm 数字前面的是名称 数字是版本号&#xff1a;第一位主版本号&#xff0c;第二位次版本…

【ArkTS】路由传参

传参 使用router.pushUrl()&#xff0c;router.push()官方不推荐再使用了。 格式&#xff1a; router.pushUrl({url: 路由地址,params:{参数名&#xff1a;值} )跳转时需要注意路由表中是否包含路由地址。 路由表路径&#xff1a; entry > src > main > resources &g…

使用vite搭建项目时,在启动vite后,浏览器显示页面:找不到localhost的网页

现象 在使用前端工具vite&#xff08;版本5&#xff09;&#xff0c;搭建vue3项目时&#xff0c;启动vite&#xff0c;浏览器显示页面&#xff1a;找不到localhost的网页, 起初怀疑是 未加参数 --host0.0.0.0,导致&#xff0c;后加上该参数后问题依旧 解决 将index.html页面…

Python框架篇(6):FastApi-配置管理

提示: 微信搜索【猿码记】回复 【fastapi】即可获取源码信息~ 在这一篇文章中,对fastapi框架和pydantic进行了升级&#xff0c;然后就是各种不兼容&#xff0c;以后再也不敢轻易升级.... pydantic&#xff1a;从 1.10.11升级到 2.5.2&#xff0c;这里有坑&#xff0c;里面有很多…

GitBook安装及使用——使用 Markdown 创建你自己的博客网站和电子书

目录 前言一、依赖环境二.gitbook安装使用1.安装 gitbook-cli2.安装 gitbook3.Gitbook初始化4.创建你的文章5.修改 SUMMARY.md 和 README.md6.编译生成静态网页7.运行以便在浏览器预览8.运行效果 前言 GitBook是一个命令行工具&#xff0c;用于使用 Markdown 构建漂亮的博客网…

Temu、Shein、OZON测评自养号,IP和指纹浏览器的优缺点分析

随着全球电子商务的飞速发展&#xff0c;跨境电商环境展现出巨大的潜力和机遇。然而&#xff0c;跨境卖家们也面临着更激烈的竞争、更严格的规定和更高的运营成本等挑战。为了在这个环境中脱颖而出&#xff0c;一些卖家尝试使用自动脚本程序进行浏览和下单。然而&#xff0c;这…

双非大数据

双非本秋招上岸总结 个人简介 学历&#xff1a;双非&#xff1b; 专业&#xff1a;软件工程&#xff1b; 求职岗位&#xff1a;大数据开发工程师&#xff1b; 状态&#xff1a;已上岸 翻车经历 学校以Java后端开发为主流&#xff0c;我从大二开始学习Java&#xff0c;直到大四…

Navicat关闭自动检查更新版本教程

Navicat关闭自动检查更新版本教程 首先&#xff0c;点击菜单中的工具菜单&#xff0c;弹出了下拉菜单选中为选项点击选项 首先&#xff0c;点击菜单中的工具菜单&#xff0c;弹出了下拉菜单选中为选项 点击选项 去掉勾选上在启动时自动检查更新选项

【lesson19】MySQL内置函数(2)数学函数和其它函数

文章目录 数学函数函数使用 其它函数函数使用 数学函数 函数使用 其它函数 函数使用 user() 查询当前用户 database()显示当前正在使用的数据库 password()函数&#xff0c;MySQL数据库使用该函数对用户加密 md5(str)对一个字符串进行md5摘要&#xff0c;摘要后得到一个32…

定制 Electron 窗口标题栏

Electron 是一款流行的桌面应用开发框架&#xff0c;基于 Web 技术构建&#xff0c;提供了强大的跨平台能力。在开发过程中&#xff0c;经常需要定制窗口标题栏以创造独特的用户体验。 1. 完全隐藏默认标题栏 有时候&#xff0c;我们希望创建一个自定义的标题栏&#xff0c;完…
最新文章