【数据结构】—超级详细的归并排序(含C语言实现)

                                       食用指南:本文在有C基础的情况下食用更佳 

                                       🔥这就不得不推荐此专栏了:C语言

                                       ♈️今日夜电波:斜陽—ヨルシカ

                                                                0:30━━━━━━️💟──────── 3:20
                                                                    🔄   ◀️   ⏸   ▶️    ☰ 

                                      💗关注👍点赞🙌收藏您的每一次鼓励都是对我莫大的支持😍


目录

♉️一、前置知识—什么是归并排序

 ♊️二、归并排序

        归并排序的思想

        归并排序的递归实现

       ♒️归并排序的非递归实现(难点)

♋️三、归并排序的特性总结


♉️一、前置知识—什么是归并排序

        归并排序是一种基于分治思想的排序算法。它将待排序的数组分成两个子数组,对每个子数组进行排序,最后将子数组合并成一个有序的数组。具体来说,归并排序采用递归的方式将数组不断二分,直到每个子数组只有一个元素,然后再将相邻的两个子数组归并成一个有序的数组,然后不断合并,直到最终得到原数组的有序排列,当然你也可以采用非递归的方法,总体的思路都是一样的。与快速排序不同的是,归并排序在每轮排序中都会将数组完全拆分成两个子数组。


 ♊️二、归并排序

        归并排序的思想

        归并排序是基于分治思想的一种排序算法,它可以将一个大问题分解成若干个小问题,再通过合并小问题的解来得到大问题的解。

        具体来说,归并排序的思想如下:

  1. 将待排序的数组划分为两个子数组,对每个子数组进行递归排序;
  2. 将排好序的子数组合并成一个有序的数组。

        这一过程可以不断重复,直到将整个数组划分为单个元素的子数组,然后再将其合并成一个有序数组,排序完成。

        一图理解~ 

        动图了解~ 

 

        归并排序的递归实现

        归并排序的递归实现步骤如下:

  1. 如果数组长度为1,直接返回该数组;
  2. 将数组按中间位置划分成两个子数组,分别对这两个子数组进行递归排序,得到排好序的两个子数组;
  3. 将排好序的两个子数组合并成一个有序数组,具体方法为创建一个辅助数组,同时遍历两个子数组,比较两个子数组中当前位置的元素,将较小的元素放入辅助数组中;
  4. 将辅助数组中的元素复制回原数组中。

        代码实现:

void _Mergesort(int* a, int* temp,int begin, int end)
{if (end <= begin)//递归结束条件return;int mid = (begin + end) / 2;//开始二分_Mergesort(a, temp, begin, mid);//左半边_Mergesort(a, temp, mid + 1, end);//右半边//正式的归并操作//分出来的两个数组的下标int begin1 = begin;int end1 = mid;int begin2 = mid + 1;int end2 = end;int index = begin;while(begin1 <= end1 && begin2 <= end2)//归并{if (a[begin1] < a[begin2]){temp[index++] = a[begin1++];}else{temp[index++] = a[begin2++];}}//当其中有一个条件不符合时,跳出循环,但是可能还有数据每遍历完while (begin1 <= end1){temp[index++] = a[begin1++];}while (begin2 <= end2){temp[index++] = a[begin2++];}// 拷贝回原数组memcpy(a + begin, temp + begin, (end - begin + 1) * sizeof(int));//拷贝对应的数据到对应的位置}void Mergesort(int* a, int n)
{int* temp = (int*)malloc(sizeof(int) * n);if (temp == NULL){perror("malloc fail");return;}_Mergesort(a, temp,0,n-1);free(temp);
}

         ♒️归并排序的非递归实现(难点)

        归并排序的非递归实现,也称为迭代实现,采用的是自底向上的方式,

        步骤如下:

  1. 将原数组按照长度为1的子数组进行划分,每个子数组都是有序的;
  2. 将长度为1的有序子数组两两合并,得到长度为2的有序子数组;
  3. 重复以上步骤,直到得到一个完整有序的数组。

         代码实现:

void MergesortNonR(int* a, int n)
{int* temp = (int*)malloc(sizeof(int) * n);if (temp == NULL){perror("malloc fail");return;}//设置一个gap用于从间距为1开始(也就是最开始的归并),对于数组进行归并操作,然后归并完一遍后让gap*2继续归并,以此类推int gap = 1;while (gap < n)//gap停止的条件,实际上gap在n的一半时就已经排好了{for (int i = 0; i < n; i += 2 * gap){//首先分出要归并的数组int begin1 = i, end1 = i + gap - 1;int begin2 = i + gap, end2 = i + 2 * gap - 1;//以下是处理越界的情况,有些时候当数组会越界// 如果第二组不存在,这一组不用归并了if (begin2 >= n){break;}// 如果第二组的右边界越界,修正一下if (end2 >= n){end2 = n - 1;}//以下的操作就是和递归的操作相同的归并操作int index = i;while (begin1 <= end1 && begin2 <= end2){if (a[begin1] < a[begin2]){temp[index++] = a[begin1++];}else{temp[index++] = a[begin2++];}}while (begin1 <= end1){temp[index++] = a[begin1++];}while (begin2 <= end2){temp[index++] = a[begin2++];}// 拷贝回原数组memcpy(a + i, temp + i, (end2 - i + 1) * sizeof(int));}gap *= 2;}free(temp);
}


♋️三、归并排序的特性总结

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


                    感谢你耐心的看到这里ღ( ´・ᴗ・` )比心,如有哪里有错误请踢一脚作者o(╥﹏╥)o! 

                                       

                                                                         给个三连再走嘛~  

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

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

相关文章

1.物联网射频识别

1.RFID概念 RFID是Radio Frequency Identification的缩写&#xff0c;又称无线射频识别&#xff0c;是一种通信技术&#xff0c;可通过无线电讯号识别特定目标并读写相关数据&#xff0c;而无需与被识别物体建立机械或光学接触。 RFID&#xff08;Radio Frequency Identificati…

前端JavaScript入门到精通,javascript核心进阶ES6语法、API、js高级等基础知识和实战 —— Web APIs(二)

思维导图 一、事件监听&#xff08;绑定&#xff09; 1.1 事件监听 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name&q…

学物联网有前途吗?

学物联网有前途吗&#xff1f; 物联网即“万物相连的互联网”&#xff0c;是互联网基础上的延伸和扩展的网络&#xff0c;将各种信息传感设备与互联网结合起来而形成的一个巨大网络&#xff0c;实现在任何时间、任何地点&#xff0c;人、机、物的互联互通。最近很多小伙伴找我&…

这个国庆场景下的创意数据应用,体现了数字经济时代的商业价值

在生成式AI爆火的2023年&#xff0c;数据协作和数据交换的商业价值越来越明显。大模型的训练正需要海量跨领域数据的“投喂”&#xff0c;才能真正创造商业价值涌现的奇迹。而如何在保护数据安全的前提下&#xff0c;有效发挥数据资产的商业价值&#xff0c;成为企业数字化亟需…

钉钉自动打卡

钉钉自动打卡 1.准备2.测试3.修改4.效果 因为一系列原因&#xff0c;本人咸鱼50块钱淘了一个小米note移动4G&#xff0c;系统是MIUI6&#xff0c;因为版本太老了&#xff0c;所以不能设置自动开启应用&#xff0c;所以就用了adb,链接电脑&#xff0c;定时跑程序&#xff0c;按按…

SELinux 介绍

背景 在工作中经常需要在 android 中增加一些东西&#xff0c; 而android有自己的安全限制&#xff0c;如果不懂SELinux&#xff0c;就不好添加。 Control Access Model https://zh.wikipedia.org/wiki/Chmod https://linux.die.net/man/1/chcon DAC DAC and Trojan Horses D…

【SpringBoot项目】SpringBoot+MyBatis+MySQL电脑商城

在b站听了袁老师的开发课&#xff0c;做了一点笔记。 01-项目环境搭建_哔哩哔哩_bilibili 基于springboot框架的电脑商城项目&#xff08;一&#xff09;_springboot商城项目_失重外太空.的博客-CSDN博客 项目环境搭建 1.项目分析 1.项目功能&#xff1a;登录、注册、热销…

linux下CentOS安装mysql-5.7

linux下安装mysql只需要在root用户下安装&#xff0c;普通用户也能使用 1.检查&#xff1a; 通过以下两条命令查看改系统下是否已存在mysql。 ps ajx | grep mysql ps ajx | grep mariadb通过指令如果只显示如下两条信息&#xff0c;则当前系统下不存在MySQL。 就可以直接进…

区块链实验室(27) - 区块链+物联网应用案例

分享最新的区块链物联网应用案例&#xff1a;HPCLS-BC

PHP禁止单个用户多设备同时登陆,限制单个用户在多端重复登录

逻辑简单,主要是3点&#xff1a; 1.登录的时候写入一个最新的登录IP到user表其中一个last_login_ip字段 2.登录成功的时候,转入到index控制器或者index方法之前先进行查询&#xff1a; 1).当前IP 2).数据库字段当前用户存储的last_login_ip里面的IP 3.然后进行判断&#xff0…

虹科方案 | 车辆总线数据记录仪解决方案

全文导读&#xff1a;针对车辆总线的数据记录&#xff0c;虹提出的解决方案是利用CANedge系列的CAN/LIN总线数据记录仪&#xff0c;根据不同的使用场合和传输方式&#xff08;SD卡/WiFi/3G/4G&#xff09;&#xff0c;选择相应的产品轻松记录车辆中的总线数据&#xff0c;助力您…

Redis高可用之持久化、主从复制(附配置实例)

目录 一、Redis高可用1.1 简介1.2 高可用策略 二、Redis 持久化2.1 简介2.2 redis 的 2 种持久化方式2.2.1 RDB持久化2.2.2 AOF持久化 三、Redis主从复制3.1 什么是主从复制&#xff1f;3.2 为什么要用主从复制&#xff1f;3.3 主从复制的特性3.4 主从复制工作原理3.4.1 全量复…

【【萌新的RISCV学习之流水线通路的控制-8】】

萌新的RISCV学习之流水线通路的控制-8 我们在之前学习了整个单周期的模块工作流程 我们按照整体的思路分段 将数据通路划分为5个阶段 IF &#xff1a; 取地址 ID &#xff1a;指令译码和读存储器堆 EX :执行或计算地址 MEM : 数据存储器访问 WB : 写回 单周期数据通路&…

飞书与企业微信的异同

云文档 飞书的云文档会自动用游览器打开&#xff0c;不会直接在PC应用中打开&#xff08;移动端能在应用中打开&#xff09;。 飞书云文档能够插入视频、流程图、问卷等等 聊天消息交互 钉钉也有类似的功能&#xff0c;可以针对消息进行点赞等回复 钉钉的消息回复还有【收到…

5.外部中断

中断初始化配置步骤&#xff1a; IO口初始化配置 开启中断总允许EA 打开某个IO口的中断允许 打开IO口的某一位的中断允许 配置该位的中断触发方式 中断函数&#xff1a; #pragma vector PxINT_VECTOR __interrupt void 函数名(void){}#pragma vector PxINT_VECTOR __int…

【pytest】 标记冒烟用例 @pytest.mark.smoke

1. 使用 pytest.mark.smoke 标记用例 import pytest class Test_Smoke:def test_01(self):assert 112pytest.mark.smokedef test_02(self):assert 121pytest.mark.smokedef test_03(self):assert 1 2 3 2.配置文件pytest.ini [pytest] markers smoke 3. 运行指定标签 运…

网络安全复习大纲wcf

单选10判断10填空30简答25分析25 选择 &#xff08;1&#xff09;计算机网络安全是指利用计算机网络管理控制和技术措施&#xff0c;保证在网络环境中数据的&#xff08; &#xff09;、完整性、网络服务可用性和可审查性受到保护。 A、保密性 B、抗攻击性 C、网络服务管理性 …

Unity之NetCode多人网络游戏联机对战教程(2)--简单实现联机

文章目录 1.添加基本组件2.创建NetworkManager组件3.创建Player4.创建地面5.创建GameManager6.编译运行7. 测试联机后话 1.添加基本组件 NetworkManagerPlayerScene 2.创建NetworkManager组件 创建一个空物体&#xff0c;命名为NetworkManager 选择刚刚创建的NetworkManager…

VS2022 编译protobuf , qt 使用

一、下载源码 protobuf: 同步 https://github.com/protocolbuffers/protobuf (gitee.com) 下载如v3.11.2 版本 二、下载CMake 三、编译 1、在1处选择源码目录下的cmake 目录&#xff1b;在2处选择一处空目录&#xff08;自己随便建&#xff09; 2、点击config&#xff0c;选择…

【面试八股】IP协议八股

IP协议八股 子网掩码的作用为什么IP协议需要分片IP协议什么时候需要分片IP协议是怎么进行分片的那么IP协议是如果进行标识属于同一个分片呢&#xff1f;TCP协议和UDP协议将数据交给IP协议之后&#xff0c;是否需要分片传输&#xff1f; 子网掩码的作用 用来标识网络号和主机号…