当前位置: 首页 > news >正文

【排序算法】——归并排序(递归与非递归)含动图

制作不易,三连支持一下吧!!!

文章目录

  • 前言
  • 一.归并排序递归方法实现
  • 二.归并排序非递归方法实现


前言

这篇博客我们将介绍归并排序的原理和实现过程。


一、归并排序递归方法实现

基本思想:
归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide andConquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。

归并排序核心步骤:

    ​​​​1.分解: 

将所给序列一分为二,直到区间中只有一个元素时停止。这个过程是递归进行的,通过传递区间参数来控制。

    2. 合并:

相邻两个子数组有序之后,就递归合并这两个子数组,将它们合并成一个新的有序子数组

 动图演示如下:

归并时,我们是借助一个临时数组tmp来合并两个有序子数组。 

 代码实现如下:

void _MergeSort(int* a, int begin, int end, int* tmp)
{if (begin >= end)return;int mid = (begin + end) / 2;_MergeSort(a, begin, mid, tmp);_MergeSort(a, mid + 1, end, tmp);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(n * sizeof(int));_MergeSort(a, 0, n - 1, tmp);free(tmp);tmp = NULL;
}

二、归并排序非递归方法实现

同快速排序一样,如果递归深度过深,可能会导致栈溢出,这样的情况下,我们就不能用递归法来实现归并排序。

上篇博客提到:将递归改成非递归的一般方法有两种

一种是直接改循环,如斐波那契数列。

另一种是借助栈或队列,例如快速排序。

这里我们借助栈也无法完成归并排序,因此我们只能选择循环。

代码实现如下:

void MergeSortNonR(int* a, int n)
{int* tmp = (int*)malloc(sizeof(int) * n);if (tmp == NULL){perror("malloc:");return;}int gap = 1;while (gap < n){for (int j = 0; j < n; j +=2*gap){int begin1 = j, end1 = begin1 + gap - 1;int begin2 = end1 + 1, end2 = begin2 + gap - 1;int i = j;if (end1 >= n || begin2 >= n){break;}//处理数组越界的情况if (end2 >= n)end2 = n - 1;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 + j, tmp + j, sizeof(int) * (end2 - j + 1));}gap *= 2;}free(tmp);tmp = NULL;
}

相关文章:

  • 40、Flink 的窗口延迟数据处理(Allowed Lateness)详解
  • 202103青少年软件编程(Python)等级考试试卷(四级)
  • Mac上如何安装低版本chrome浏览器
  • Windows安装VMware(Broadcom)
  • Linux安装zsh并配置oh-my-zsh
  • C++小游戏 合集
  • 【Unity2D:C#Script】制作敌人
  • 数据库(6)——数据类型
  • springboot社区助老志愿服务系统-计算机毕业设计源码96682
  • Golang设计模式(四):观察者模式
  • SpringBoot使用rsa-encrypt-body-spring-boot实现接口加解密
  • Spring Boot+Debezium:解决 MySQL Binlog监听
  • 出书,是「盖你自己的房子」你知道吗?
  • 清华新突破||新研究揭示多智能体协作的秘密武器
  • springboot + Vue前后端项目(第十一记)
  • Angular数据绑定机制
  • ECMAScript 6 学习之路 ( 四 ) String 字符串扩展
  • Effective Java 笔记(一)
  • Python代码面试必读 - Data Structures and Algorithms in Python
  • Python连接Oracle
  • SpiderData 2019年2月23日 DApp数据排行榜
  • text-decoration与color属性
  • 聊聊directory traversal attack
  • 日剧·日综资源集合(建议收藏)
  • 2017年360最后一道编程题
  • C# - 为值类型重定义相等性
  • ​Java基础复习笔记 第16章:网络编程
  • ​如何使用QGIS制作三维建筑
  • ​直流电和交流电有什么区别为什么这个时候又要变成直流电呢?交流转换到直流(整流器)直流变交流(逆变器)​
  • #每日一题合集#牛客JZ23-JZ33
  • #我与Java虚拟机的故事#连载17:我的Java技术水平有了一个本质的提升
  • $().each和$.each的区别
  • (03)光刻——半导体电路的绘制
  • (13)DroneCAN 适配器节点(一)
  • (2)STM32单片机上位机
  • (C语言)fread与fwrite详解
  • (php伪随机数生成)[GWCTF 2019]枯燥的抽奖
  • (Redis使用系列) Springboot 使用Redis+Session实现Session共享 ,简单的单点登录 五
  • (附源码)python旅游推荐系统 毕业设计 250623
  • (附源码)springboot 基于HTML5的个人网页的网站设计与实现 毕业设计 031623
  • (计算机网络)物理层
  • (三)Honghu Cloud云架构一定时调度平台
  • (三分钟了解debug)SLAM研究方向-Debug总结
  • (四)汇编语言——简单程序
  • (一)Thymeleaf用法——Thymeleaf简介
  • (终章)[图像识别]13.OpenCV案例 自定义训练集分类器物体检测
  • (总结)Linux下的暴力密码在线破解工具Hydra详解
  • .naturalWidth 和naturalHeight属性,
  • .net oracle 连接超时_Mysql连接数据库异常汇总【必收藏】
  • .net 简单实现MD5
  • .Net+SQL Server企业应用性能优化笔记4——精确查找瓶颈
  • .net访问oracle数据库性能问题
  • /3GB和/USERVA开关
  • /etc/motd and /etc/issue
  • ::什么意思