算法之归并排序
文章目录
- 一、归并排序(递归版)
- 二、归并排序(非递归版)
一、归并排序(递归版)
归并排序思想:将数组划分为两个区间,左区间,右区间 然后对这两个区间内容进行排序 ,这两个区间排好序之后再将其合并为一个有序的区间
这两个区间排好序之后,再将这两个区间合并为一个区间 也就是将这两个区间的数据排序为一个有序的区间
而将数组划分为两个区间之后是如何将这两个区间里的内容排好序的呢 是重复同样的操 作再将这两个区间中的左区间分别又划分为两个区间(左区间,右区间)
,将这两个区间分别排好序之后,
再归为一个区间,也就是左区间有序了,然后再排它的右区间,此时它的右区间右划分为两个区间(左区间,右区间)
对它们分别进行排序 ,而划分下去的左右区间又要执行同样的操作,直到最后区间大小为一时,那么此时就不用排返回,返回时与另一个区间比较进行排序,
最后右区间变为有序的了,最后将这两个大的左右区间归并排序为一个区间,此时这个区间有序 ,由于递归排序回来时,将小区间排好序,最后整个大区间跟着有序了
我上图只是画了整个数组左区间的,右区间可以下去尝试下,右区间也是如此
void _MergeSort(int* a, int left, int right, int* tmp)
{//当区间中只有一个数时就不用再对其进行排序if (left >= right)return;//每次将其区间折半划分为左区间和右区间int mid = (left + right) / 2;//再重复划分,直到它的左右区间只剩下一个数,那么再返回//对其排序_MergeSort(a, left, mid, tmp);_MergeSort(a, mid + 1, right, tmp);//将其小区间排好序后再排它的大区间//小区间有序之后大区间排过来也就是有序的了int begin1 = left, end1 = mid;int begin2 = mid + 1, end2 = right;int begin = left;//将左右区间合并为一个区间while (begin1 <= end1 && begin2 <= end2){if (a[begin1] > a[begin2]){tmp[begin++] = a[begin2++];}else{tmp[begin++] = a[begin1++];}}//两个区间中还剩余数据的那个区间直接尾插到tmp数组后面while (begin1 <= end1){tmp[begin++] = a[begin1++];}while (begin2 <= end2){tmp[begin++] = a[begin2++];}//最后将排好序的区间拷贝回原来的数组memcpy(a + left, tmp+left, sizeof(int)*(right - left + 1));
}void MergeSort(int* a, int n)
{//开一个临时数组用来存放小区间排序后的数据//最后再将排序后的数组拷贝回原数组中int* tmp = (int*)malloc(sizeof(int) * n);if (tmp == NULL){perror("malloc fail\n");return;}//归并排序分两区间进行_MergeSort(a, 0, n - 1, tmp);free(tmp);
}
二、归并排序(非递归版)
思想:将整个数组一个数与一个数比较,然后将它们排序为一个有两个数的区间 得到两个数与两个数之间有序
再将有两个数的区间与另外有两个数的区间进行排序为一个有四个数的区间 得到四个数的区间与四个数的区间有序
再将四个数的有序区间与四个数的有序区间进行排序为一个有8个数的有序区间 得到8个数与8个数之间有序
如此循环下去,直到区间中数据的个数为原数组数据个数时为止
那么区间中的数据个数如何控制,它又是如何变化的,设定一个变量gap来控制,然后当数组里面的数据都两两归并后gap变为原来2倍
gap *= 2
当数组长度不是gap倍数时,要注意控制边界。
那这个边界如何控制?
设前一个区间左端:
begin1,右端:end1
设后一个区间左端为:begin2,右端:end2
如果第一个区间的右端已经超出了数组长度(end1>=n),此时将第一个区间右端下标重定为数组长度-1(end1 =n-1, begin2 = n, end2 = n-1),如果前一个区间右端没有超出,但是第二个区间左端就超出了(重定begin2 = n-1,end2 = n-1,),这样后一个区间就不用再与前一个区间合并了,直接将前一个区间拷到原数组后面,如果后一个区间左端没有超出,但是后一个区间右端超出了数组长度,此时重定end2,end2 = n-1,此时前一个再与后一个合并
** 将tmp中内容拷贝回原数组**

将间隔为gap的小区间归并后的内容整体拷贝回原数组
void MergeSort1(int* a, int n)
{int* tmp = (int*)malloc(sizeof(int) * n);if (tmp == NULL){perror("malloc fail\n");return;}int gap = 1;while (gap < n){//小区间由gap控制,且每次都是前一个区间和后一个区间//归并为一个大的有序区间,所以每次i需要加上gap的2倍,//一次跳过两个区间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;int j = i;//由于两个小区间要合并为一个区间,//然后存放到数组tmp中,合并后数组tmp长度大小//为两个小区间长度大小之和,然后下次在开始合并时,//从合并后的右端下标开始赋值,所以tmp下标起始由i//决定if (end1 >= n){end1 = n - 1;begin2 = n ;end2 = n-1;}else if (begin2 >= n){begin2 = n ;end2 = n-1;}else if(end2 >=n ){end2 = n - 1;}//两个区间中小的数尾插到tmp数组中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++];}}//将间隔为gap小区间合并后的数组tmp里的内容全部拷贝回原数组中memcpy(a, tmp, sizeof(int) * n);gap *= 2;//最后gap变为原来的2倍}free(tmp);
}
将间隔为gap的小区间一段一段的拷贝回原数组
void MergeSort2(int* a, int n)
{int* tmp = (int*)malloc(sizeof(int) * n);if (tmp == NULL){perror("malloc fail\n");return;}int gap = 1;while (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;int j = i;//由于gap使其分区间块化有序,此时前一个区间的右端//或者后一个区间的左端超出数组长度了,那么直接//拷贝到原数组后面if (end1 >= n || begin1 >= n){break;}else if (end2 >= n){end2 = n - 1;}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++];}//每一次区间间隔为gap的两个区间合并后就将其拷贝到//原数组中memcpy(a + i, tmp + i, sizeof(int) * (end2 - i + 1));}gap *= 2;}free(tmp);
}
归并排序将两个有序的区间归并为一个有序的区间
相关文章:
算法之归并排序
文章目录一、归并排序(递归版)二、归并排序(非递归版)一、归并排序(递归版) 归并排序思想:将数组划分为两个区间,左区间,右区间 然后对这两个区间内容进行排序 ÿ…...
Mysql日志系统-mysql serve层
Mysql日志系统-服务层的日志 mysql给我们提供了很多有用的日志有mysql服务层提供的,有innodb引擎层提供的,下表是mysql服务层给我们提供的: 日志类型写入日志的信息二进制日志记录了对MySQL数据库执行更改的所有操作慢查询日志记录所有执行…...
阿里云蔡英华:云智一体,让产业全面迈向智能
4月11日,在2023阿里云峰会上,阿里云智能首席商业官蔡英华表示,算力的飞速发展使数字化成为确定,使智能化成为可能。阿里云将以云计算为基石,以AI为引擎,参与到从数字化迈向智能化的划时代变革中。 基于服务…...
打怪升级之FPGA组成原理(LE部分)
FPGA芯片逻辑单元的原理 不论你使用哪一款FPGA芯片,其核心可编程逻辑单元都是从一段内存种按顺序读取执行并执行的过程。具体来说,FOGA芯片内部包括可编程逻辑块(LAB)、可配置输入输出单元(IOE)、时钟管理模块、嵌入式RAM(BRAN,在Cyclone IV…...
c++的多态
目录 1、多态 1.1多态的构成条件 1.2多态的好处 2、虚函数 2.1虚函数重写 2.2虚函数的默认参数 2.3纯虚函数重写 2.4抽象类 2.5虚析构,纯虚析构重写 3、重载、覆盖(重写)、隐藏(重定义)的对比 编辑 多态是c面向对象三大特性之一 程序调用函数时&#…...
【数据结构与算法】堆的实现(附源码)
目录 一.堆的概念及结构 二.接口实现 A.初始化 Heapinit 销毁 Heapdestroy B.插入 Heappush 向上调整 AdjustUp 1.Heappush 2.AdjustUp C.删除 Heappop 向下调整 AdjustDown D.堆的判空 Heapempty 堆顶数据 Heaptop 堆的大小 Heapsize 三.源码 Heap.h He…...
win10彻底永久关闭自动更新【亲测有效】
一、禁用Windows Update服务 1、同时按下键盘 Win R,打开运行对话框,然后输入命令 services.msc ,点击下方的“确定”打开服务,如下图所示。 2、找到 Windows Update 这一项,并双击打开,如图所示。 3、右击…...
【Unity UPR】造个获取深度法线纹理的轮子
描边需要深度法线纹理的加持,效果才能达到最好,但URP下很多版本不支持直接获取_CameraNormalsTexture,而我本人也尝试了一下在12.1.7下偷懒直接拿SSAO里的Depth Normal图, 虽然也能实现吧,但是需要打开SSAO的同时&…...
用 Python解析HTML页面
用 Python 解析 HTML 页面 在网络爬取的过程中,我们通常需要对所爬取的页面进行解析,从中提取我们需要的数据。网页的结构通常是由 HTML 标签所组成的,通过对这些标签的解析,可以得到网页中所包含的有用信息。在 Python 中&#…...
python logging 详解
python logging 详解1. 导入logging模块2. 配置日志记录器3. 记录日志消息4. 自定义日志记录器5. 日志轮换6. 日志过滤器7. 日志异常跟踪8. 日志输出到控制台和文件9. 使用配置文件10. 使用第三方库11. format格式详解12. 总结Python的logging模块提供了灵活的日志记录功能&…...
( “树” 之 DFS) 687. 最长同值路径 ——【Leetcode每日一题】
687. 最长同值路径 给定一个二叉树的 root ,返回 最长的路径的长度 ,这个路径中的 每个节点具有相同值 。 这条路径可以经过也可以不经过根节点。 两个节点之间的路径长度 由它们之间的边数表示。 示例 1: 输入:root [5,4,5,1,1,5] 输出&…...
Elasticsearch解决不能修改索引、字段问题解决方案
问题1: 由于es索引不能删除,不能修改,在不影响原数据的情况下,并且生产服务不停机的情况下,怎么修改索引,并保留原索引内的数据? 基于kibanna的dev Tools执行参数,淘汰postman&…...
面试官在线改简历 | 只有6秒!程序员简历这样写才能抓住科技公司大佬的眼球
其实每一份简历 每一个瑞库特 可能也就平均花6秒钟的时间看一看 来进行一个快速的筛选 一份好的简历到底应该长什么样 同时呢在我们写简历的过程当中 应该避免什么样子的错误和误区 那我们今天呢来聊聊这个简历的事 大家知道 每次到了招聘高分期啊这些大的公司 像谷歌Facebook…...
IM即时通讯-7-如何设计通知提醒
本文大纲 本文从为什么做通知提醒, 以及如何设计通知提醒, 以及如何衡量通知提醒三方面解释了如何设计通知提醒。 对于重点的如何设计通知提醒, 通过拆分前台和后台, 前台采用自建或者二方通道, 后台采用厂商信令通道…...
赛狐ERP | 亚马逊选品方法与策略详解:如何挑选最优质的产品?
亚马逊作为全球电商巨头,其产品种类之丰富也是无人能及。然而,在如此繁杂的商品体系下,如何选品成为了摆在商家面前的一道难题。本文将从亚马逊选品的目标、方法、策略三个方面进行详细介绍。 一、选品的目标 在进行选择之前,必…...
【GCU体验】基于PyTorch + GCU跑通ResNet50模型并测试GCU性能
一、环境 地址:启智社区:https://openi.pcl.ac.cn/ 二、计算卡介绍 云燧T20是基于邃思2.0芯片打造的面向数据中心的第二代人工智能训练加速卡,具有模型覆盖面广、性能强、软件生态开放等特点,可支持多种人工智能训练场景。同时具备灵活的可…...
【机器视觉------标定篇(二)】三点成圆算法(求相机旋转中心)
应用场景 机器视觉项目应用中,相机安装在机器人上,并且需要定位产品返回坐标偏差以及角度偏差。 与九点标定配合使用,实现精准角度补偿。 算法输入 不共线的三点坐标 A(X₁,Y₁) ,B(X₂,Y₂&…...
AUTOSAR E2E详细介绍
E2E概述 E2E(End-To-End)是AUTOSAR为功能安全ISO26262提出的一个安全模块。这里的端(End)并不是指ECU与ECU之间,而是指通信ECU上的SW-C与SW-C之间。 在车载网络中,信息交换通常是从一个ECU发送信号,另一个ECU接收信号。对E2E而言,通常是从源SW-C生成信号,经过RTE(R…...
Dream 主题使用手册 - 基础篇
Dream 主题基于 Halo 博客系统开发,本文将介绍本主题一些功能的使用,文档将持续更新。 一、安装 & 更新 1.1 安装包安装 & 更新 进入主题 Release 界面:https://github.com/nineya/halo-theme-dream/releases 下载主题压缩包 halo…...
WSL下的Kafka开发容器:Docker搭建、API、整合
背景介绍 Kafka是一个分布式流处理平台,可以处理大规模数据流并支持实时数据流的处理。 本文介绍了如何在WSL下使用Docker搭建Kafka容器,并使用Python的kafka-python库和FastAPI框架实现了一个简单的API。同时,还将该服务整合到一个整体的d…...
uniapp 对接腾讯云IM群组成员管理(增删改查)
UniApp 实战:腾讯云IM群组成员管理(增删改查) 一、前言 在社交类App开发中,群组成员管理是核心功能之一。本文将基于UniApp框架,结合腾讯云IM SDK,详细讲解如何实现群组成员的增删改查全流程。 权限校验…...
conda相比python好处
Conda 作为 Python 的环境和包管理工具,相比原生 Python 生态(如 pip 虚拟环境)有许多独特优势,尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处: 一、一站式环境管理:…...
从WWDC看苹果产品发展的规律
WWDC 是苹果公司一年一度面向全球开发者的盛会,其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具,对过去十年 WWDC 主题演讲内容进行了系统化分析,形成了这份…...
无法与IP建立连接,未能下载VSCode服务器
如题,在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈,发现是VSCode版本自动更新惹的祸!!! 在VSCode的帮助->关于这里发现前几天VSCode自动更新了,我的版本号变成了1.100.3 才导致了远程连接出…...
测试markdown--肇兴
day1: 1、去程:7:04 --11:32高铁 高铁右转上售票大厅2楼,穿过候车厅下一楼,上大巴车 ¥10/人 **2、到达:**12点多到达寨子,买门票,美团/抖音:¥78人 3、中饭&a…...
基于数字孪生的水厂可视化平台建设:架构与实践
分享大纲: 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年,数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段,基于数字孪生的水厂可视化平台的…...
MODBUS TCP转CANopen 技术赋能高效协同作业
在现代工业自动化领域,MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步,这两种通讯协议也正在被逐步融合,形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...
深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南
🚀 C extern 关键字深度解析:跨文件编程的终极指南 📅 更新时间:2025年6月5日 🏷️ 标签:C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言🔥一、extern 是什么?&…...
Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理
引言 Bitmap(位图)是Android应用内存占用的“头号杀手”。一张1080P(1920x1080)的图片以ARGB_8888格式加载时,内存占用高达8MB(192010804字节)。据统计,超过60%的应用OOM崩溃与Bitm…...
docker 部署发现spring.profiles.active 问题
报错: org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...





