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

【排序】归并排序(C语言实现)

文章目录

  • 1. 递归版的归并排序
  • 1.1 归并排序的思想
    • 2. 递归版的归并排序的实现
  • 2. 非递归版的归并排序




1. 递归版的归并排序


1.1 归并排序的思想

归并排序(MERGE - SORT)是建立在归并操作上的一种有效的排序算法, 该算法是采用分治法(Divide andConquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。 归并排序核心步骤:
在这里插入图片描述
请添加图片描述

这里我们先介绍一下递归版本的归并排序的思想:

  • 我们需要先创建一个临时数组,用来将需要排序的数组归并到这个临时数组里面去,然后再将这个数组拷贝到原数组中去,这样就完成了排序的过程。

2. 递归版的归并排序的实现

具体实现方式如下:

void Sub_MergeSort(int* a, int* tmp, int begin, int end)
{if (begin >= end - 1) // 我控制的是左闭右开区间return;int key = (begin + end) / 2;// [left,key + 1) [key,end) 左闭右开的空间一定要控制好int begin1 = begin, end1 = key;int begin2 = key, end2 = end;Sub_MergeSort(a, tmp, begin1, end1);Sub_MergeSort(a, tmp, begin2, end2);// 归并过程int indix = begin;while (begin1 < end1 && begin2 < end2){if (a[begin1] <= a[begin2]){tmp[indix++] = a[begin1++];}else{tmp[indix++] = a[begin2++];}}while (begin1 < end1){tmp[indix++] = a[begin1++];}while (begin2 < end2){tmp[indix++] = a[begin2++];}// 将tmp数组中的元素拷贝到元素中memmove(a + begin, tmp + begin, (end - begin)*sizeof(int));
}void MergeSort(int* a, int n)
{int* tmp = (int*)malloc(sizeof(int) * n);if (tmp == NULL){perror("malloc fail\n");return;}// 因为这里开一次空间就够用了,所以递归过程我们还是要写成一个子函数来完成Sub_MergeSort(a, tmp, 0, n);free(tmp);tmp = NULL;
}


2. 非递归版的归并排序


所以在平时我们要使用归并排序时,使用递归版的完全够用了。但由于现在还在学习阶段,所以掌握一下非递归版的归并排序还是有必要的。

把递归改成非递归,这个怎么处理呢?可以像我们之前讲的快速排序的非递归一样使用栈吗?

这里实现非递归的归并排序使用栈其实不是很好的方式,反而会使问题变复杂。

在这里插入图片描述
所以我们就得想其他办法:

可以这样:
请添加图片描述
但是这里需要注意两种情况:
在这里插入图片描述
这里不控制好边界的话,很容易就造成越界了,这里我分享两种控制边界的方式,细节我写在注释里了:

方式一:

// 归并排序 -- 非递归
void MergeSortNonR(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 + i){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 indix = i;while (begin1 <= end1 && begin2 <= end2){if (a[begin1] < a[begin2]){tmp[indix++] = a[begin1++];}else{tmp[indix++] = a[begin2++];}}while (begin1 <= end1){tmp[indix++] = a[begin1++];}while (begin2 <= end2){tmp[indix++] = a[begin2++];}// 将tmp数组拷贝回原数组memcpy(a + i, tmp + i, (end2 - i + 1) * sizeof(int));}gap *= 2;}free(tmp);tmp = NULL;
}


方式二:

void MergeSortNonR2(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){int j = 0;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;// end1 >= n - 1 和begin2 >= n 都代表没有第二组,所以第二组就不用参与归并过程if (end1 >= n){end1 = n - 1;// 此时begin2和end2一定是越界的// 我们手动让这段空间不存在begin2 = n;end2 = n - 1;}else if (begin2 >= n){// 我们手动让这段空间不存在begin2 = n;end2 = n - 1;}else if (end2 >= n) // 此时end1 和 begin2都没有越界{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, tmp, sizeof(int) * n);gap *= 2;}free(tmp);tmp = NULL;
}

相关文章:

【排序】归并排序(C语言实现)

文章目录 1. 递归版的归并排序1.1 归并排序的思想2. 递归版的归并排序的实现 2. 非递归版的归并排序 1. 递归版的归并排序 1.1 归并排序的思想 归并排序&#xff08;MERGE - SORT&#xff09;是建立在归并操作上的一种有效的排序算法, 该算法是采用分治法&#xff08;Divide a…...

127. 单词接龙

和433.最小基因变化这道题一样的解法。 https://blog.csdn.net/qq_43606119/article/details/135538247 class Solution {public int ladderLength(String beginWord, String endWord, List<String> wordList) {Set<String> cnt new HashSet<>();for (int …...

计算机算法贪心算法

贪心算法&#xff08;Greedy Algorithm&#xff09;是一种常见的算法思想&#xff0c;它在每一步选择当前状态下最优的解决方案&#xff0c;从而希望最终能够达到全局最优解。 贪心算法的基本思路是每一步都选择当前状态下的局部最优解&#xff0c;而忽略了当前选择所带来的影…...

基于css实现动画效果

介绍 本文将会基于css&#xff0c;实现各种动画效果&#xff0c;接下来会从简单几个例子入手。 案例 三颗球 <!DOCTYPE html> <html lang"en"><head><meta charset"utf-8" /><title>React App</title><style>…...

18.将文件上传至云服务器 + 优化网站的性能

目录 1.将文件上传至云服务器 1.1 处理上传头像逻辑 1.1.1 客户端上传 1.1.2 服务器直传 2.优化网站的性能 2.1 本地缓存优化查询方法 2.2 压力测试 1.将文件上传至云服务器 客户端上传&#xff1a;客户端将数据提交给云服务器&#xff0c;并等待其响应&#xff1b;用户…...

Linux: module: kheaders;CONFIG_IKHEADERS

文章目录 参考错误开一个玩笑。configcommit参考 https://github.com/iovisor/bcc/pull/2312 https://github.com/iovisor/bcc/pull/3588 https://bugs.gentoo.org/809347 https://lore.kernel.org/lkml/20190408212855.233198-1-joel@joelfernandes.org/ 错误 <built-in…...

Page 251~254 Win32 GUI项目

win32_gui 源代码&#xff1a; #if defined(UNICODE) && !defined(_UNICODE)#define _UNICODE #elif defined(_UNICODE) && !defined(UNICODE)#define UNICODE #endif#include <tchar.h> #include <windows.h>/* Declare Windows procedure */…...

Kafka(七)可靠性

目录 1 可靠的数据传递1.1 Kafka的可靠性保证1.2 复制1.3 Broker配置1.3.1 复制系数1.3.2 broker的位置分布1.3.3 不彻底的首领选举1.3.4 最少同步副本1.3.5 保持副本同步1.3.6 持久化到磁盘flush.messages9223372036854775807flush.ms9223372036854775807 1.2 在可靠的系统中使…...

Spring Data JPA入门到放弃

参考文档&#xff1a;SpringData JPA&#xff1a;一文带你搞懂 - 知乎 (zhihu.com) 一、 前言 1.1 概述 Java持久化技术是Java开发中的重要组成部分&#xff0c;它主要用于将对象数据持久化到数据库中&#xff0c;以及从数据库中查询和恢复对象数据。在Java持久化技术领域&a…...

MES系统数据采集的几种方式

生产制造执行MES系统具有能够帮助企业实现生产数据收集与分析、生产计划管理、生产过程监控等的功能板块&#xff0c;在这里小编就不一一介绍了&#xff0c;主要讲讲它的数据采集功能板块&#xff0c;可以说&#xff0c;数据采集是该系统进行数据统计与生产管理等后续工作的基础…...

铭文 LaunchPad 平台 Solmash 推出早鸟激励计划

为感谢用户对Solmash的支持&#xff0c;Solmash 特别推出“Solmash早鸟激励计划”&#xff0c;以回馈社区的早期参与者&#xff0c;这是专为已经参与Staking Pool或Honest Pool的用户推出的激励。 Solmash NFT激励 被列入早鸟计划的用户&#xff0c;可通过点击&#xff1a;sol…...

【前端规范】

1 前言 HTML 作为描述网页结构的超文本标记语言&#xff0c;一直有着广泛的应用。本文档的目标是使 HTML 代码风格保持一致&#xff0c;容易被理解和被维护。 2 代码风格 2.1 缩进与换行 [强制] 使用 4 个空格做为一个缩进层级&#xff0c;不允许使用 2 个空格 或 tab 字符…...

12、JVM高频面试题

1、JVM的主要组成部分有哪些 JVM主要分为下面几部分 类加载器&#xff1a;负责将字节码文件加载到内存中 运行时数据区&#xff1a;用于保存java程序运行过程中需要用到的数据和相关信息 执行引擎&#xff1a;字节码文件并不能直接交给底层操作系统去执行&#xff0c;因此需要…...

【Docker】Docker安装入门教程及基本使用

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是Java方文山&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的专栏《Docker实战》。&#x1f3af;&#x1f3af; &…...

语义解析:如何基于SQL去实现自然语言与机器智能连接的桥梁

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 &#x1f4ab;个人格言:"没有罗马,那就自己创造罗马~" 目录 语义解析 定义 作用 语义解析的应用场景 场景一&#xff1a; 场景二&#xff1a; 总结语…...

Java项目:117SpringBoot动漫论坛网站

博主主页&#xff1a;Java旅途 简介&#xff1a;分享计算机知识、学习路线、系统源码及教程 文末获取源码 117SpringBoot动漫论坛网站 一、项目介绍 动漫论坛网站是由SpringBootMybatis开发的&#xff0c;旅游网站分为前台和后台&#xff0c;前台为用户浏览&#xff0c;后台进…...

Jenkins基础篇--添加节点

节点介绍 Jenkins 拥有分布式构建(在 Jenkins 的配置中叫做节点)&#xff0c;分布式构建能够让同一套代码在不同的环境(如&#xff1a;Windows 和 Linux 系统)中编译、测试等。 Jenkins 运行的主机在逻辑上是 master 节点&#xff0c;下图是主节点和从节点的关系。 添加节点 …...

【C++】手撕 list类(包含迭代器)

目录 1&#xff0c;list的介绍及使用 2&#xff0c;list_node 3&#xff0c;list_node() 3&#xff0c;list 4&#xff0c;list() 5&#xff0c;push_back(const T& x) 6&#xff0c;print() 7&#xff0c;_list_iterator 8&#xff0c;operator*() 9&#xff0c…...

@Autowired 和 @Resource 的区别是什么?

Java面试题目录 Autowired 和 Resource 的区别是什么&#xff1f; Autowired 是 Spring 提供的注解。默认的注入方式为byType&#xff08;根据类型进行匹配&#xff09;。 Resource 是 JDK 提供的注解。默认注入方式为 byName&#xff08;根据名称进行匹配&#xff09;。 当一…...

栈和排序.

给你一个1->n的排列和一个栈&#xff0c;入栈顺序给定 你要在不打乱入栈顺序的情况下&#xff0c;对数组进行从大到小排序 当无法完全排序时&#xff0c;请输出字典序最大的出栈序列 输入 第一行一个数n 第二行n个数&#xff0c;表示入栈的顺序&#xff0c;用空格隔开&…...

eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)

说明&#xff1a; 想象一下&#xff0c;你正在用eNSP搭建一个虚拟的网络世界&#xff0c;里面有虚拟的路由器、交换机、电脑&#xff08;PC&#xff09;等等。这些设备都在你的电脑里面“运行”&#xff0c;它们之间可以互相通信&#xff0c;就像一个封闭的小王国。 但是&#…...

【网络安全产品大调研系列】2. 体验漏洞扫描

前言 2023 年漏洞扫描服务市场规模预计为 3.06&#xff08;十亿美元&#xff09;。漏洞扫描服务市场行业预计将从 2024 年的 3.48&#xff08;十亿美元&#xff09;增长到 2032 年的 9.54&#xff08;十亿美元&#xff09;。预测期内漏洞扫描服务市场 CAGR&#xff08;增长率&…...

2024年赣州旅游投资集团社会招聘笔试真

2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...

Robots.txt 文件

什么是robots.txt&#xff1f; robots.txt 是一个位于网站根目录下的文本文件&#xff08;如&#xff1a;https://example.com/robots.txt&#xff09;&#xff0c;它用于指导网络爬虫&#xff08;如搜索引擎的蜘蛛程序&#xff09;如何抓取该网站的内容。这个文件遵循 Robots…...

Java线上CPU飙高问题排查全指南

一、引言 在Java应用的线上运行环境中&#xff0c;CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时&#xff0c;通常会导致应用响应缓慢&#xff0c;甚至服务不可用&#xff0c;严重影响用户体验和业务运行。因此&#xff0c;掌握一套科学有效的CPU飙高问题排查方法&…...

10-Oracle 23 ai Vector Search 概述和参数

一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI&#xff0c;使用客户端或是内部自己搭建集成大模型的终端&#xff0c;加速与大型语言模型&#xff08;LLM&#xff09;的结合&#xff0c;同时使用检索增强生成&#xff08;Retrieval Augmented Generation &#…...

处理vxe-table 表尾数据是单独一个接口,表格tableData数据更新后,需要点击两下,表尾才是正确的

修改bug思路&#xff1a; 分别把 tabledata 和 表尾相关数据 console.log() 发现 更新数据先后顺序不对 settimeout延迟查询表格接口 ——测试可行 升级↑&#xff1a;async await 等接口返回后再开始下一个接口查询 ________________________________________________________…...

腾讯云V3签名

想要接入腾讯云的Api&#xff0c;必然先按其文档计算出所要求的签名。 之前也调用过腾讯云的接口&#xff0c;但总是卡在签名这一步&#xff0c;最后放弃选择SDK&#xff0c;这次终于自己代码实现。 可能腾讯云翻新了接口文档&#xff0c;现在阅读起来&#xff0c;清晰了很多&…...

【JVM】Java虚拟机(二)——垃圾回收

目录 一、如何判断对象可以回收 &#xff08;一&#xff09;引用计数法 &#xff08;二&#xff09;可达性分析算法 二、垃圾回收算法 &#xff08;一&#xff09;标记清除 &#xff08;二&#xff09;标记整理 &#xff08;三&#xff09;复制 &#xff08;四&#xff…...

Windows安装Miniconda

一、下载 https://www.anaconda.com/download/success 二、安装 三、配置镜像源 Anaconda/Miniconda pip 配置清华镜像源_anaconda配置清华源-CSDN博客 四、常用操作命令 Anaconda/Miniconda 基本操作命令_miniconda创建环境命令-CSDN博客...