排序——归并排序

文章目录

  • 基本思想
  • 递归版本
    • 思路
    • 代码实现
  • 非递归版
    • 思路
    • 代码实现
  • 特性
  • 结果演示

基本思想

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

递归版本

思路

1.分解:将要排序的序列每次分解为2个序列,直到不能再分解
2.合并:将分解的序列排序并两两归并
在这里插入图片描述
过程:我们需要创建一个临时数组tmp,将每次归并后的结果存入tmp,最后用memcpy将排好后的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);//将原序列分解为2段序列int i = begin;int begin1 = i, end1 = mid;int begin2 = mid + 1, end2 = end;//确定两段序列的首位下标while (begin1 <= end1 && begin2 <= end2){if (a[begin1] < a[begin2]){tmp[i++] = a[begin1++];}else{tmp[i++] = a[begin2++];}}//将2段序列中的数按顺序存入tmpwhile (begin1 <= end1){tmp[i++] = a[begin1++];}while (begin2 <= end2){tmp[i++] = a[begin2++];}//将没存完的那个序列剩下的值(有序)存入tmpmemcpy(a + begin, tmp + begin, sizeof(int) * (end - begin + 1));//将tmp拷贝给原数组,加上begin定位排序好的值,因为begin是我们操作2个序列的前一个序列的首下标。不加begin的话就是拷贝整个序列的第一个值,可能不是我们正在归并的序列,还没有被排序。
}
void MergeSort(int* a, int n)
{int* tmp = (int*)malloc(sizeof(int) * n);if (tmp == NULL){perror("malloc fail");return;}_MergeSort(a, 0, n - 1, tmp);free(tmp);
}

非递归版

思路

递归版本时,我们通过将要排序的序列分解、合并,在合并的过程中完成排序。在非递归的版本中,合并的思路和代码实现是一样,主要是如何将序列分解,递归版本可以利用子问题分治实现,非递归就要用循环模拟递归,我们这里引入一个gap
,代表序列的数据个数,首先让gap等于1,这样就将序列分解为好了,然后开始两两归并,之后让gap不断2倍化,直到gap等于原数组的数据个数。这里分解后的序列首位下标之差就是gap-1(因为是双闭区间,序列的数据个数就是gap)。这里还要注意分解的序列的首尾下标不能超过原序列的数据个数。
在这里插入图片描述

代码实现

void MergeSortnonR(int* a, int n)
{int* tmp = (int*)malloc(sizeof(int) * n);if (tmp == NULL){perror("malloc fail");return;}//临时数组,存归并好的数据int gap = 1;//分解好的序列的数据个数为gapwhile (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;//要归并的2个序列的首尾下标int j = begin1;if (end1 >= n || begin2 >= n){break;}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++];}//排序并合并数据memcpy(a +i, tmp +i, sizeof(int) * (end2 - i + 1));//将归并好的数据拷贝给原数组}gap *= 2;//放大排序序列的区间,begin1到end1和begin2到end2这两个区间的数据个数是2倍的gap,所以gap *= 2后新序列还是有序的,只需继续将新序列两两归并即可。}
}

特性

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

结果演示

int main()
{int a[] = { 2,5,9,1,6,11,3,4 };int n1 = sizeof(a) / sizeof(a[0]);MergeSort(a, n1);printf("MergeSort:");for (int i = 0; i < n1; i++){printf("%d ", a[i]);}printf("\n");int b[] = { 2,7,3,4,1,2,6,5,11,8 };int n2 = sizeof(b) / sizeof(b[0]);
MergeSortnonR(b, n2);
printf("MergeSortnonR:");for (int i = 0; i < n2; i++){printf("%d ", b[i]);}return 0;
}

在这里插入图片描述

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

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

相关文章

开发实践6_缓存^中间件

以下学习 朔宁夫 开发工程师 课程。 缓存可提高程序响应速度。数据库缓存(可过期)/ Redis缓存(Key:Value)/ Memcacheed缓存/ 程序层缓存。 一 缓存 1. 数据库缓存 创建缓存数据表 // python manage.py createcachetable cache_table setting // # 缓存配置 CACHES {def…

12.云原生之kubesphere中应用部署方式

云原生专栏大纲 文章目录 k8s中应用部署Kubernetes常用命令 kubesphere中可视化部署应用创建工作负载服务暴露 helm部署应用helm命令行部署应用kubesphere中使用应用仓库 k8s中应用部署 在k8s中要想部署应用&#xff0c;需要编写各种yaml文件&#xff0c;一旦应用依赖比较复杂…

蓝桥杯备赛 | 洛谷做题打卡day2

​ 蓝桥杯备赛 | 洛谷做题打卡day2 嵌套循环yyds&#xff01;&#xff01; 题目来源&#xff1a;洛谷P2670 [NOIP2015 普及组] 扫雷游戏 题目背景 NOIP2015 普及组 T2 题目描述 扫雷游戏是一款十分经典的单机小游戏。在 n n n 行 m m m 列的雷区中有一些格子含有地雷&am…

如何去开发直播电商系统小程序

明确你的直播电商系统的功能和特性&#xff0c;包括用户注册、商品展示、购物车、支付结算、直播功能、评论互动等。根据需求确定系统的基本架构和主要模块。 技术选型&#xff1a;选择适合你的直播电商系统的技术栈。考虑前端框架&#xff08;如React、Vue.js&#xff09;、后…

C语言:编译和链接

目录 一&#xff1a;翻译环境和运行环境 二&#xff1a;翻译环境 2.1预处理&#xff08;预编译&#xff09; 2.2编译 2.2.1 词法分析&#xff1a; 2.2.2语法分析 2.2.3语义分析 2.3 汇编 三&#xff1a;运行环境 一&#xff1a;翻译环境和运行环境 在ANSI C的任何一种…

力扣每日一练(24-1-16)

我一开始想到的是&#xff0c;如果数字相同则加一。 然而&#xff0c;对了一点点&#xff0c;而已。 高手的方法不是普通人在几分钟内能想得出来的&#xff0c;hh 继续补充&#xff1a; 如果数字不同则减一&#xff0c;如果计数到达了0&#xff0c;则更新数字&#xff0c;最…

论文复现|tightly focused circularly polarized ring Airy beam

请尊重原创的劳动成果 如需要转载&#xff0c;请后台联系 前言 采用MATLAB复现一篇论文里面的插图&#xff0c;涡旋光束的聚焦的仿真方式有很多种&#xff0c;这里采用MATLAB进行仿真&#xff0c;当然也有其他的很多方式&#xff0c;不同的方式各有千秋。 论文摘要 本文证明…

Kafka消费流程

Kafka消费流程 消息是如何被消费者消费掉的。其中最核心的有以下内容。 1、多线程安全问题 2、群组协调 3、分区再均衡 1.多线程安全问题 当多个线程访问某个类时&#xff0c;这个类始终都能表现出正确的行为&#xff0c;那么就称这个类是线程安全的。 对于线程安全&…

uni-app的学习【第三节】

五 运行环境判断与跨端兼容 uniapp为开发者提供了一系列基础组件,类似HTML里的基础标签元素,但uni-app的组件与HTML不同,而是与小程序相同,更适合手机端使用。 虽然不推荐使用 HTML 标签,但实际上如果开发者写了`div`等标签,在编译到非H5平台时也会被编译器转换为 `view`…

@RequiresApi(api = Build.VERSION_CODES.O)

问题 RequiresApi(api Build.VERSION_CODES.O) 详细问题 对于代码 // 格式化日期为MySQL的DATE类型格式private String formatDate(LocalDate date) {DateTimeFormatter formatter DateTimeFormatter.ofPattern("yyyy-MM-dd");return date.format(formatter);}o…

C# 面向切面编程之AspectCore初探

写在前面 AspectCore 是Lemon名下的一个国产Aop框架&#xff0c;提供了一个全新的轻量级和模块化的Aop解决方案。面向切面也可以叫做代码拦截&#xff0c;分为静态和动态两种模式&#xff0c;AspectCore 可以实现动态代理&#xff0c;支持程序运行时在内存中“临时”生成 AOP 动…

深入云原生—基于KubeWharf深度剖析-以公司实际应用场景为例深度解读

各位好&#xff0c;这里是难忘&#xff0c;本人对云原生也是研究了2年多了&#xff0c;算是略有所得&#xff0c;本次就来深入云原生—基于KubeWharf深度剖析场景与解读。我们需要先了解一下 KubeWharf&#xff0c;可能很多人都感觉到有点陌生吧&#xff0c;下面我们来一起学习…

助力工业焊缝质量检测,YOLOv7【tiny/l/x】不同系列参数模型开发构建工业焊接场景下钢材管道焊缝质量检测识别分析系统

焊接是一个不陌生但是对于开发来说相对小众的场景&#xff0c;在我们前面的博文开发实践中也有一些相关的实践&#xff0c;感兴趣的话可以自行移步阅读即可&#xff1a;《轻量级模型YOLOv5-Lite基于自己的数据集【焊接质量检测】从零构建模型超详细教程》 《基于DeepLabV3Plus…

必示科技助力中国联通智网创新中心通过智能化运维(AIOps)通用能力成熟度3级评估

2023年12月15日&#xff0c;中国信息通信研究院隆重公布了智能化运维AIOps系列标准最新批次评估结果。 必示科技与中国联通智网创新中心合作的“智能IT故障监控定位分析能力建设项目”通过了中国信息通信研究院开展的《智能化运维能力成熟度系列标准 第1部分&#xff1a;通用能…

PHP项目如何自动化测试

开发和测试 测试和开发具有同等重要的作用 从一开始&#xff0c;测试和开发就是相向而行的。测试是开发团队的一支独立的、重要的支柱力量。 测试要具备独立性 独立分析业务需求&#xff0c;独立配置测试环境&#xff0c;独立编写测试脚本&#xff0c;独立开发测试工具。没有…

STM32--7针0.96寸OLED屏幕显示(4线SPI)

本文介绍基于STM32F103C8T60.96寸OLED&#xff08;7针&#xff09;的显示&#xff08;完整程序代码见文末链接&#xff09; 一、简介 OLED&#xff0c;即有机发光二极管&#xff08; Organic Light Emitting Diode&#xff09;。 OLED 由于同时具备自发光&#xff0c;不需背光…

C++ 设计模式之桥接模式

【声明】本题目来源于卡码网&#xff08;题目页面 (kamacoder.com)&#xff09; 【提示&#xff1a;如果不想看文字介绍&#xff0c;可以直接跳转到C编码部分】 【简介】什么是桥接模式 桥接模式&#xff08;Bridge Pattern&#xff09;是⼀种结构型设计模式&#xff0c;它的U…

倍福嵌入式PLC开发团队建设

倍福嵌入式PLC开发工程师确实比较难找&#xff0c;这是因为这个领域需要具备丰富的专业知识和技能&#xff0c;而且经验越丰富的工程师越难找到。以下是一些可能导致倍福嵌入式PLC开发工程师难找的原因&#xff1a; 具备相关技能的工程师数量相对较少&#xff1a;嵌入式PLC开发…

XUbuntu22.04之免费思维导图工具(二百零六)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

Kafka集群的安装与配置

一、安装JDK 1、在usr目录下新建Java目录&#xff0c;然后将下载的JDK拷贝到这个新建的Java目录中1 创建目录命令&#xff1a;mkdir /usr/java 2、进入到Java目录中解压下载的JDK 解压命令&#xff1a;tar -zxvf jdk-18_linux-x64_bin.tar.gz 在1主机上&#xff0c;将安装包…