归并、计数排序(画图详解)

news2024/12/23 17:16:53

归并排序:

        基本思想:先递归再回归,在回归的时候进行归并排序

 归并排序:

        适用于两个有序数组,合并成一个数组的时候,也就是先要递归,递归到最后就相当于一个元素,一个元素就是有序的。

        之后回归时再进行两两元素的排序。

代码如下:
 

void PartSort1(int *a,int n)
{
	int* tmp = (int*)malloc(n * sizeof(int));
	if (tmp == NULL)
	{
		perror("malloc:error");
		return;
	}
	int begin = 0;
	int end = n - 1;
	MergeSort(a,tmp,begin,end);
}
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;
	int end1 = mid;
	int begin2 = mid + 1;
	int end2 = end;
	int i = begin1;
	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));//这里一点更要加i,不是加begin也不是加begin1
}

 非递归归并排序:

void MergeSort1(int* a, int n)
{
	int* tmp = (int*)malloc(n * sizeof(int));
	if (tmp == NULL)
	{
		perror("malloc:error");
		return;
	}
	int gap = 1;//表示gap个元素为一组
	while (gap < n)
	{
		for (int i = 0; i < n ; i+=2*gap)
		{
			int begin1 = i;
			int end1 = i + gap - 1;
			int begin2 = i +gap;
			int end2 = i + 2 * gap-1;
			int j = begin1;
            //边界处理
			if (end1 >= n || begin2 >= n)
			{
				break;
			}
			
			if (end2 >= n)
			{
				end2 = n - 1;
			}
			printf("[%d %d] [%d %d]", begin1, end1, begin2, end2);
			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++];
			}
			memcpy(a + i, tmp + i, (end2-i+1) * sizeof(int));
		}
		printf("\n");
		gap *= 2;
	}
}

计数排序:

        如果有排序可以统计小范围数据,并且效率较高,比其他排序效率都要高一点,那肯定是基数排序。

原理:

        要对一组数进行排序,可以统计每个数出现的次数。

此时需要开辟一个新数组(新数组的长度等于原数组最大值 - 最小值),从头开始统计原数组的每个数出现的次数,每出现一次,在新数组的对应下标位置加1。直到原数组统计结束。

再将新数组里的数从头一次放回原数组中。

例如:

代码如下:

        

void Countingsort(int* a, int n)
{
	//找最大值
	int max = a[0];
	for (int i = 0; i < n; i++)
	{
		if (a[i] > max)
		{
			max = a[i];
		}
	}
	int size = max+ 1;
	int* tmp = (int*)calloc(size ,sizeof(int));
	if (tmp == NULL)
	{
		perror("calloc:error");
		return;
	}
	for (int i = 0; i < n; i++)
	{
		tmp[a[i]]++;
	}
	int i = 0;
	for (int j = 0; j < size; j++)
	{
		while (tmp[j] != 0)
		{
			a[i++] = j;
			tmp[j]--;
		}
	}
	free(tmp);
}

但是这样做的话,效率会有点低,导致在遇到大数的时候,得开辟从0~max的大小的空间

但是如果我只有1000~1999的数据,会造成前面空间的浪费。

因此进一步改进:(优化!!)

代码如下:

void Countingsort(int* a, int n)
{
	//找最大值和最小值
	int max = a[0];
	int min = a[0];
	for (int i = 0; i < n; i++)
	{
		if (a[i] > max)
		{
			max = a[i];
		}
		if (a[i] < min)
		{
			min = a[i];
		}
	}
	int size = max - min + 1;
	int* tmp = (int*)calloc(size, sizeof(int));
	if (tmp == NULL)
	{
		perror("calloc:error");
		return;
	}
	//往tmp里面放值
	for (int i = 0; i < n; i++)
	{
		tmp[a[i] - min]++;
	}
	//tmp里面取值
	int i = 0;
	for (int j = 0; j < size; j++)
	{
		while (tmp[j] != 0)
		{
		a[i++] = j+min;
		tmp[j]--;
		}
	}
	free(tmp);
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Unity数据持久化 之 二进制存储法

本文仅作笔记学习和分享&#xff0c;不用做任何商业用途 本文包括但不限于unity官方手册&#xff0c;unity唐老狮等教程知识&#xff0c;如有不足还请斧正​​ 前置知识&#xff1a;1 Byte 8 bit &#xff0c;所以0000 00001 就是一个字节&#xff0c; 该串数字转为十进制代表1…

通过cmd命令的方式转码MP4为webp动图。附带命令解释。

zihao 通过cmd命令的方式转码MP4为webp动图&#xff1a; 均衡大小和z效果的配置&#xff08;直接拷贝后需要改下路径&#xff09;&#xff1a; ffmpeg -i E:\steam\222.mp4 -vcodec libwebp -filter:v fpsfps24 -lossless 0 -compression_level 5 -q:v 35 -loop 1 -preset def…

深入浅出Promise,循序渐进掌握JavaScript异步编程

一. Promise基本用法 Promise 是 JavaScript 中处理异步操作的一种方式。它是一个对象&#xff0c;代表了一个异步操作的最终完成或失败的结果。 Promise 有三种状态&#xff1a; pending &#xff08;进行中&#xff09;、 fulfilled &#xff08;已成功&#xff09; 和 rej…

如何在SQL Server中恢复多个数据库?

一次性恢复多个 SQL数据库吗可以吗&#xff1f; "是的&#xff0c;可以一次性恢复多个 SQL 数据库。通常情况下&#xff0c;只要备份文件的名称与相应的数据库匹配&#xff0c;且没有附加的日期或时间信息&#xff0c;就可以通过有效的 T-SQL 脚本来完成恢复。如果你希望…

虚幻引擎VR游戏开发03| 键位映射

Enhanced input mapping 按键映射 在虚幻引擎&#xff08;Unreal Engine&#xff09;中&#xff0c;Enhanced Input Mapping 是一个用于管理和处理输入&#xff08;例如键盘、鼠标、手柄等&#xff09;的系统。它提供了一种更灵活、更强大的方式来定义和响应用户输入&#xff…

MMO移动同步(1)

多个客户端同时连入游戏 这篇会从以下五个部分讲解&#xff1a; 同步的基本概念 完善角色进入及离开处理 CharacterManager(C/S) EntityManager(C/S) 打包运行Win客户端 同步基本概念 同步&#xff1a;角色信息&#xff0c;位置&#xff0c;状态同步&#xff1b;客户端和…

神仙公司名单(北京篇)

欢迎来到小落科技每日分享频道 大家好&#xff0c;秋招已经火热进行中了&#xff0c;不知道大家准备得怎么样了&#xff1f;特别是咱们25届的小伙伴们&#xff0c;有没有找到心仪的目标&#xff1f; 想必大家最近和我一样&#xff0c;忙着在各种招聘平台上搜罗信息&#xff0c…

如何在 Cursor 中使用驭码CodeRider?

驭码CodeRider 是极狐GitLab 公司自研发布的 AIGC 产品&#xff0c;可以用来进行 AI 编程和 DevOps 流程处理。本文分享如何在 Cursor 中使用驭码CodeRider。 Cursor 是近期比较火爆的一款 AI 代码编辑器&#xff0c;通过将 AI 能力引入软件研发来提升软件研发效率。而驭码Cod…

水凝胶透镜是什么?能用来干啥?

大家好&#xff0c;今天我们来了解一项关于蛋白质驱动的水凝胶透镜的研究——《Toward Tunable Protein‐Driven Hydrogel Lens》发表于《Advanced Science》。我们的眼睛晶状体主要由蛋白质构成&#xff0c;在视觉中起重要作用。但人造光学系统要实现类似功能却不容易。近年来…

【设计文档】数据库设计说明书(Word实际项目案例参考)

一、 总述 &#xff08;一&#xff09; 编写目的 二、 外部设计 &#xff08;一&#xff09; 环境说明 &#xff08;二&#xff09; 指导 三、 物理实现 &#xff08;一&#xff09; 物理结构 &#xff08;二&#xff09; 安全设计 四、 表设计结构 &#xff08;一&am…

【软件文档】软件系统试运行方案、试运行报告(Word项目实际原件)

一、 试运行目的 &#xff08;一&#xff09; 系统功能、性能与稳定性考核 &#xff08;二&#xff09; 系统在各种环境和工况条件下的工作稳定性和可靠性 &#xff08;三&#xff09; 检验系统实际应用效果和应用功能的完善 &#xff08;四&#xff09; 健全系统运行管理体制&…

【数字人】Facevid2vid:用于视频会议的一次性自由视图说话头合成

论文&#xff1a;https://arxiv.org/pdf/2011.15126 github:GitHub - zhanglonghao1992/One-Shot_Free-View_Neural_Talking_Head_Synthesis: Pytorch implementation of paper "One-Shot Free-View Neural Talking-Head Synthesis for Video Conferencing" 一种新颖…

ip地址的管理方法有哪些?是什么

IP地址的管理方法有哪些&#xff1f;随着互联网的快速发展&#xff0c;‌IP地址作为网络设备的唯一标识&#xff0c;‌其管理显得尤为重要。‌有效的IP地址管理不仅可以确保网络的稳定运行&#xff0c;‌还能提高网络资源的利用率。‌本文将深入探讨IP地址的管理方法&#xff0…

网银U盾:财务眼中钉,会计肉中刺!

随着网银U盾的广泛应用&#xff0c;虽然使得财务安全有了大幅提升&#xff0c;但企业财务管理效率却越来越低了。 近期&#xff0c;我们发现&#xff0c;高达85%的企业在采购我们的USB Server时&#xff0c;都是出于网银U盾反复插拔的繁琐、效率低下、管理困难等原因。 想象一…

sqli-labs靶场通关攻略(五十一到六十关)

sqli-labs-master靶场第五十一关 步骤一&#xff0c;尝试输入?sort1 我们发现这关可以报错注入 步骤二&#xff0c;爆库名 ?sort1 and updatexml(1,concat(0x7e,database(),0x7e),1)-- 步骤三&#xff0c;爆表名 ?sort1 and updatexml(1,concat(0x7e,(select group_conc…

CentOS 7 docker 部署遇到内网通,外网不通 问题

CentOS 7 docker 部署遇到内网通&#xff0c;外网不通 问题 [rootlocalhost ~]# systemctl status network ● network.service - LSB: Bring up/down networkingLoaded: loaded (/etc/rc.d/init.d/network; bad; vendor preset: disabled)Active: failed (Result: exit-code) …

多角度解读WMS:探寻仓库管理系统的核心功能

多角度解读 WMS 仓库管理系统 1. 概述 WMS 在数字化工厂中具有举足轻重的地位&#xff0c;它不仅提高了仓储管理的效率与准确性&#xff0c;还能优化整个供应链的管理&#xff0c;支持灵活生产模式&#xff0c;并提供决策支持的关键数据。通过现代前后端技术的架构设计&#xf…

几十块的麦克风能用吗?一文看懂哪个牌子的麦克风好

无论是拍摄短视频、直播还是采访&#xff0c;说一款好的音频设备是非常重要的&#xff0c;它决定了音频质量的高低&#xff0c;如今市面上的麦克风种类也是各式各样的都有&#xff0c;价格上也是参差不齐&#xff0c;有些小伙伴问“几十块的麦克风能用吗”&#xff1f; 我觉得最…

Docker部署项目时的服务端口设置——给容器添加新端口映射

Docker给容器添加新端口映射 1 Docker安装Ubuntu22.042 创建新容器3 给容器添加端口映射3.1 查看运行的容器3.2 查看容器挂载目录3.3 停止容器3.4 停止docker服务3.5 进入容器挂载目录3.6 修改config.v2.json文件3.7 修改hostconfig.json文件3.8 启动docker3.9 启动容器 4 端口…

C语言中volatile与const关键字的深入解析

在C语言编程中&#xff0c;volatile和const是两个非常重要的关键字&#xff0c;它们各自有着独特的用途。本文将深入探讨这两个关键字的工作原理、底层实现机制以及在实际开发中的应用。 volatile关键字 1. 原理与作用 volatile关键字用于告诉编译器&#xff0c;所修饰的变量…