排序嘉年华———归并排序

文章目录

  • 一.归并是什么?
    • 题目一:合并有序数组
    • 题目二:合并有序链表
  • 二.归并排序
    • 1.递归式归并
    • 2.非递归式的归并排序

一.归并是什么?

相信朋友们应该做过一类题,合并两个有序数组,在链表里也有合并两个单链表的oj题,那我们稍微回顾一下

题目一:合并有序数组

普通思路:
1.定义一个第三方数组,用来临时归并排序
2.分别比较两个数组,小者先放进临时数组中
3.补充未排完的数组
4.将临时数组的值拷贝进返回数组nums1
void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n) {int sum[m+n];int i=0,j=0,count=0;//比较取小尾插while(i<m&&j<n){if(nums1[i]<=nums2[j]){sum[count++]=nums1[i++];}else{sum[count++]=nums2[j++];}}//补充while(i<m){sum[count++]=nums1[i++];}while(j<n){sum[count++]=nums2[j++];}memcpy(nums1,sum,sizeof(int)*(m+n));
}

题目二:合并有序链表

普通思路:
1.定义并维护指针head  tail
2.判断两种特殊情况
3.循环比较尾插
4.若有未链接的连结则直接尾插
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2) {struct ListNode *head=NULL, *tail=NULL;//两种特殊情况if (list1 == NULL)return list2;if (list2 == NULL)return list1;while (list1 && list2) {if (list1->val <= list2->val) {//初始状态判定if (tail == NULL)head = tail = list1;else {tail->next = list1;tail = list1;}if (list1)list1 = list1->next;} else {//初始状态判定if (tail == NULL)head = tail = list2;else {tail->next = list2;tail = list2;}if (list2)list2 = list2->next;}}//补充if(list1) tail->next=list1;else tail->next=list2;return head;
}

二.归并排序

字面意思,归并排序是通过将数据分别归并比较最终成为有序
在这里插入图片描述
建立一个临时数组,然后将数据两两归并放入临时数组,最终将有序数组拷贝回目标数组中

1.递归式归并

  • 首先动态开辟一个临时数组tmp
void Mergesort(int* a, int n)
{int* tmp = (int*)malloc(sizeof(int) * n);if (tmp == NULL){perror("malloc fail");}_Mergesort(a, 0, n - 1, tmp);free(tmp);
}
  • 然后编写子程序_Mergesort
void _Mergesort(int* a, int begin, int end, int* tmp)

四个参数,目标无序数组,目标起始下标,目标结束下标,已开辟的数组

  • 确定递归结束条件,归并的区间<=1时则可视为有序
if (begin >= end)return;
  • 分离出归并区间,取中间下标,递归式分离
//分离[begin1,end1][begin2,end2]int mid = (begin + end) / 2;int begin1 = begin, end1 = mid;int begin2 = mid + 1, end2 = end;_Mergesort(a, begin1, end1, tmp);_Mergesort(a, begin2, end2, tmp);
  • 开始归并,这里的小细节是递归一次拷贝一组,边排边拷贝,不然可能导致数据丢失
//归并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 test()
{int a[11] = { 9,6,7,3,1,5,7,10,0,0,1 };Mergesort(a, 11);for (size_t i = 0; i < 11; i++){printf("%d ", a[i]);}
}

在这里插入图片描述

2.非递归式的归并排序

非递归思路是由分散的每个数据两两归并,然后成倍增加归并个体的数量,如下图
在这里插入图片描述

  • 先将组内数量设置为gap=1
int gap = 1;while (gap < n){//...gap *= 2;}
  • 分理待归并数组
for (size_t i = 0; i < n ;i+=2*gap){//分出两组区域int begin1 = i, end1 = i + gap - 1;int begin2 = i + gap, end2 = i + 2 * gap - 1;//...}
  • 如果是单纯end1或begin2越界出错则直接跳出,如果end2出错那就直接将end2的边界处理为n-1
// 边界的处理if (end1 >= n || begin2 >= n){break;}if (end2 >= n){end2 = n - 1;}
  • 然后开始基本环节归并并拷贝回目标数组
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++];}memcpy(a + i, tmp + i, sizeof(int) * (end2-i+1));
  • 最后释放临时数组
    free(tmp);
    测试一下:
void test()
{int a[11] = { 9,6,7,3,1,5,7,10,0,0,1 };MergeNRsort(a, 11);for (size_t i = 0; i < 11; i++){printf("%d ", a[i]);}
}

在这里插入图片描述
两个完整代码已上传码云:递归和非递归归并排序
在这里插入图片描述
感谢大佬评论和建议

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

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

相关文章

liunx安装redis

安装redis 1.向Xftp7上传Redis压缩包 进行解压&#xff1a;tar -zxvf redis-6.0.8.tar.gz 解压后预编译&#xff1a; cd redis-6.0.8 make 创建文件: mkdir -p /opt/redis 安装到指定目录: make install PREFIX/opt/redis 进入安装文件 bin 目录:cd /opt/redis/bin ./redis-se…

Angular系列教程之依赖注入详解

文章目录 引言依赖注入基础依赖注入的基本概念依赖注入的原理 依赖注入实践依赖注入注意事项 引言 Angular作为一款流行的前端框架&#xff0c;提供了许多优秀的功能和特性&#xff0c;其中之一就是依赖注入&#xff08;Dependency Injection&#xff09;。依赖注入是一种设计…

IP定位技术在网络安全行业的探索

随着互联网的普及和深入生活&#xff0c;网络安全问题日益受到人们的关注。作为网络安全领域的重要技术&#xff0c;IP定位技术正逐渐成为行业研究的热点。本文将深入探讨IP定位技术在网络安全行业的应用和探索。 一、IP定位技术的概述 IP定位技术是通过IP地址来确定设备地理位…

Github 2FA验证的解决方法

当前使用GitHub需要启用 2FA 验证&#xff0c;也就是除了账号密码外还有一个实时码&#xff0c;需要额外输入这个正确的实时码才能开启 2FA 验证和后续登陆。 浏览器插件 这是目前我在使用的方法。在浏览器中添加一个叫做Authenticator的插件&#xff0c;传送地址&#xff1a;…

单表查询 -- MySQL(3)

目录 题目&#xff1a; 创建表&#xff1a; 问题&#xff08;17个&#xff09;&#xff1a; 1、显示所有职工的基本信息。 2、查询所有职工所属部门的部门号&#xff0c;不显示重复的部门号。 3、求出所有职工的人数。 4、列出最高工资和最低工资。 5、列出职工…

5 个被低估的开源项目

文章目录 1.集算器 -数据处理2. Firecamp - 邮递员替代方案3.Keploy——后端 测试4. Hanko - 密钥验证5. Zrok - Ngrok 类固醇 长话短说 本文列出了五个不太受欢迎的优秀项目&#xff0c;您应该尝试一下。&#x1f525; 这些工具旨在改进数据处理、API 开发、后端测试、身份验…

GO——gin中间件和路由

中间件 参考&#xff1a;https://learnku.com/articles/66234 结构 中间件是函数中间件函数被放在调用链上调用链的末尾是路由path对应的函数 执行过程 net/http包调用到gin的serverHTTP 参考&#xff1a;go/pkg/mod/github.com/gin-gonic/ginv1.7.7/gin.go:506 通过path找到…

MacOS系统 安装ZooKeeper 和常见问题解决

安装ZooKeeper 和 常见问题 一、安装和启动二、常见问题和解决2.1 配置文件在哪&#xff1f;2.2 安装路径在哪&#xff1f;2.3 如果不想后台运行zookeeper&#xff0c;用完就关&#xff0c;省资源&#xff0c;可以的&#xff01;2.4 启动时&#xff0c;报错2.4 启动/停止使用 z…

MySQL基础笔记(6)函数

函数&#xff1a;是指一段可以直接被另一段程序调用的程序或者代码~&#xff08;MySQL内置&#xff09; 一.字符串函数 trim不能去除中间的空格~ select concat(jsl,1325): 执行如上的代码&#xff0c;返回字符串"jsl1325"。 select lower(JSL); 执行如上的代码&…

深度学习基础知识整理

自动编码器 Auto-encoders是一种人工神经网络&#xff0c;用于学习未标记数据的有效编码。它由两个部分组成&#xff1a;编码器和解码器。编码器将输入数据转换为一种更紧凑的表示形式&#xff0c;而解码器则将该表示形式转换回原始数据。这种方法可以用于降维&#xff0c;去噪…

C++入门案例——通讯录管理系统 控制台项目

前言 C入门案例——通讯录管理系统 & 控制台项目 目录 前言总体概览实体类设计显示页面和退出系统 添加联系人逻辑拆解相关代码 显示联系人逻辑拆解相关代码 根据名字删除联系人逻辑拆解相关代码 根据名字查找联系人逻辑拆解相关代码 修改联系人逻辑拆解相关代码 清空所有…

鸿蒙ArkTS的起源和简介

theme: lilsnake 1、引言 Mozilla创造了JS&#xff0c;Microsoft创建了TS&#xff0c;Huawei进一步推出了ArkTS。 从最初的基础的逻辑交互能力&#xff0c;到具备类型系统的高效工程开发能力&#xff0c;再到融合声明式UI、多维状态管理等丰富的应用开发能力&#xff0c;共同…

ASP.NET Core列表增删改查

前置要求&#xff1a; 1. vueelement-plus实现前端静态页面 HelloWorld.vue <template><h2>hello界面</h2><div class"tableList"><!-- 搜索框 --><el-row :gutter"20"><el-col :span"8"><!-- 搜…

Linux系统资源分析手段:CPU,内存,磁盘与网络IO的瓶颈定位

前言&#xff1a;性能分析手段的应用场景 用于优化&#xff1a; 在程序编码完成后&#xff0c;我们通常要对自己编写的工具进行功能测试与性能分析。 用于监控&#xff1a; 在观察某个系统的运行情况时&#xff0c;需要观察系统内多个中间件及组件的资源占用情况。 用于测试…

tcpdump常用参数以及wireshark密文解密

tcpdump常用参数以及wireshark密文解密 文章目录 一、tcpdump命令和常用参数二、在wireshark中协议解析 tcpdump常用参数 一、tcpdump命令和常用参数 tcpdump常用命令&#xff1a;tcpdump -i eth0 src host 11.6.224.1 and udp port 161 -s 0 -w 161.pcap &#xff08;161为sn…

C盘满了,我用什么思路清理?

20240115 上周六同事传了一个很大的虚拟机给我&#xff0c;C盘就红了 虽然是飞秋选错了存储文件的路径&#xff0c;但后来忘了&#xff0c;就开始毫无目的删除文件&#xff0c;过程中会有没有权限删除的&#xff0c;这样还是没有改善。 咨询了公司IT技术人员&#xff0c; 告…

利用python将Excel文件拆分为多个CSV

目录 一、准备工作 二、拆分Excel文件为多个CSV 1、读取Excel文件&#xff1a; 2、确定要拆分的列&#xff1a; 3、创建空的字典来存储CSV文件&#xff1a; 4、循环遍历数据并根据类别拆分&#xff1a; 5、打印或返回CSV文件名字典&#xff1a; 6、保存CSV到特定目录&a…

开源的代名词「GitHub 热点速览」

当开发者谈论开源时&#xff0c;通常会想到 GitHub&#xff0c;它不仅仅是一个代码托管平台&#xff0c;更是一个汇聚了全球开发者的社交中心。过去&#xff0c;开发者发布一款软件后&#xff0c;都是在自己的小圈子里默默努力和交流&#xff0c;现在通过 GitHub 平台可以方便地…

day02_计算机常识丶第一个程序丶注释丶关键字丶标识符

计算机常识 计算机如何存储数据 计算机世界中只有二进制。那么在计算机中存储和运算的所有数据都要转为二进制。包括数字、字符、图片、声音、视频等。 进制 进制也就是进位计数制&#xff0c;是人为定义的带进位的计数方法 实例&#xff1a; // 在java 中 可以使用不同…

【机器学习】强化学习 (一)强化学习简介

一、强化学习简介 1.1 问题定义 1.2 马尔可夫决策过程 举例说明马尔可夫决策过程 例1&#xff1a; 例2&#xff1a; 执行动作的策略 强化学习的目标是让智能体通过不断尝试&#xff0c;找到最优的策略&#xff08;policy&#xff09;&#xff0c;即在每个状态下选择什么动作&am…