数据结构系列-归并排序

🌈个人主页:羽晨同学 

💫个人格言:“成为自己未来的主人~”  

归并排序

递归版本

首先,我们来看一下归并的示意图:

这是归并排序当中分解的过程。 然后便是两个两个进行排序,组合的过程。

归并完美的诠释了“分治的思想”,分治分治,分而治之,我们将一个大的问题不断地分为一个个小的子问题,然后通过解决子问题的目的对大问题进行解决。

为了更好的理解,接下来,请看下面的这一张动图: 

我们在这张图中可以理解到归并的实现逻辑,它的实现,需要借助一个新的数组,并两个,四个,逐渐进行排序。

  • 用malloc函数开辟一个新的数组,并对数组进行检查
  • 确定最小子问题(当只有一个元素的时候就不用在进行递归,一个就是有序的)
  • 进行递归找到最小子区间(第一张示意图的最后一行)
  • 然后其实就是两个有序数组的合并,合并之后再进行拷贝,然后又进行合并,继续拷贝。

首先,我们给到归并排序在.h文件中的定义。

//Sort.h
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<string.h>
void MergeSort(int* a, int n);

接下来,我们在.c文件中进行归并排序的实现

首先,我们写一下归并排序的整体框架:

void MergeSort(int* a, int begin, int end, int* tmp)
{//......
}
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);tmp = NULL;
}

接下来,我们在子函数当中,对代码进行完善 

#define _CRT_SECURE_NO_WARNINGS
#include"Sort.h"
void _MergeSort(int* a, int begin, int end, int* tmp)
{if (begin == end)return;//定义初始变量int mid = (begin + end) / 2;int begin1 = begin, end1 = mid;int begin2 = mid+1, end2 = end;_MergeSort(a, begin1, end1, tmp);_MergeSort(a, begin2, end2, tmp);int i = begin;while (begin1 <= end1 && begin2 <= end2){if (a[begin1] >= a[begin2]){tmp[i++] = a[begin2++];}else{tmp[i++] = a[begin1++];}}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(sizeof(int) * n);if (tmp == NULL){perror("malloc fail");return;}_MergeSort(a, 0, n-1, tmp);free(tmp);tmp = NULL;
}

接下来是归并排序的测试代码:

#define _CRT_SECURE_NO_WARNINGS
#include"Sort.h"
int main()
{int a[] = { 5,1,2,7,5,6,2,5,3,9,7 };MergeSort(a, sizeof(a) / sizeof(int));for (int i = 0; i < sizeof(a) / sizeof(int); i++){printf("%d ", a[i]);}return 0;
}

非递归版本

  • 我们设置一个gap表示begin1,end1,begin2,end2
  • 非递归版本主要就是通过控制gap来实现递归

 

void MergeSortNonR(int* a, int n)
{int* tmp = (int*)malloc(sizeof(int) * n);int gap = 1;while (gap < n){for (int i = 0; i < n; i += 2 * gap){int begin1 = i, end1 = begin1 + gap - 1;int begin2 = begin1 + gap, end2 = begin2 + gap - 1;//if (end1 >= n || begin2 >= n){break;}if (end2 >= n)end2 = n - 1;int j = i;while (begin1 <= end1 && begin2 <= end2){if (a[begin1] >= a[begin2]){tmp[j++] = a[begin2++];}else{tmp[j++] = a[begin1++];}}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;}}
  1.  我们先设定一个gap=1(这个代表只有一个元素,这个自然是有序的)
  2. 然后我们令gap*=2,实现gap的递增,从而扩大排序的范围

 对于归并排序而言,

它的时间复杂度是O(N*logN)

它的空间复杂度是O(N)

稳定性:稳定

 归并排序的主要缺点就是空间复杂度较大,需要开辟新的空间。

好了,这个就是归并排序的所有内容。

归并排序此外还被用到了文件排序当中,这个我们后面会进行讲解。

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

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

相关文章

系统编程-管道

管道 目录 管道 1、管道的特点 2、无名管道的使用步骤 &#xff08;1&#xff09;在进程中使用 pipe 函数来获取管道的文件描述符 &#xff08;2&#xff09;使用 fork 函数来创建子进程 &#xff08;3&#xff09;通过获取到的文件描述符来进行数据的传输 &#xff08…

[论文阅读] mobile aloha实验部分

DP:[1] CHI C, FENG S, DU Y, et al. Diffusion Policy: Visuomotor Policy Learning via Action Diffusion[J]. 2023. Diffusion Policy: Visuomotor Policy Learning via Action Diffusion精读笔记&#xff08;一&#xff09;-CSDN博客 哥伦比亚大学突破性的方法- Diffusio…

【Leetcode 1893 】 检查是否区域内所有整数都被覆盖

给你一个二维整数数组 ranges 和两个整数 left 和 right 。每个 ranges[i] [starti, endi] 表示一个从 starti 到 endi 的 闭区间 。 如果闭区间 [left, right] 内每个整数都被 ranges 中 至少一个 区间覆盖&#xff0c;那么请你返回 true &#xff0c;否则返回 false 。 已…

【SpringBoot】11 多数据源(MyBatis:dynamic-datasource)

介绍 多数据源&#xff1a;指的是一个单一应用程序中涉及了两个及以上的数据库&#xff0c;这种配置允许应用程序根据业务需求灵活地管理和操作不同的数据库。 需求 一个应用服务中&#xff0c;连接多个数据库&#xff0c;有本地的也有远程的&#xff0c;有MysQL、Oracle、P…

前端实现首次访问,后续从本地访问

在前端实现将PDF文件下载到用户的本地磁盘&#xff0c;并在后续加载时使用本地文件&#xff0c;而不是重新从服务器下载&#xff0c;可以通过以下步骤实现&#xff1a; 1. **使用<a>标签的download属性**&#xff1a;当用户首次点击下载PDF时&#xff0c;通过<a>标…

PDPS软件 那智机器人 (丰田版)离线程序导出处理

在PDPS仿真软件中导出的那智机器人离线程序&#xff0c;一般是无法直接给TFD控制装置-那智机器人&#xff08;丰田式样版&#xff09;导入及识别使用。因此要对导出的程序进行转换编译处理&#xff0c;才能给TFD那智机器人&#xff08;丰田式样版&#xff09;导入离线程序。以下…

C语言宏的深度探索与全面应用策略

C语言的宏机制是一种预处理器功能&#xff0c;它允许程序员在编译阶段进行文本替换&#xff0c;以实现代码的复用、条件编译和性能优化等目标。然而&#xff0c;宏的使用也伴随着一些挑战&#xff0c;如可能导致代码难以理解和维护、引入未预期的行为等。本文旨在深入剖析C语言…

react antd TreeSelect实现自定义标签

<ProFormTreeSelectlabel"接收对象"name"receiverObjects"colProps{{ span: 16 }}labelCol{{span: 6,}}wrapperCol{{span: 18,}}rules{[{ required: true }]}fieldProps{{showSearch: true,multiple: true,// autoClearSearchValue: true,filterTreeNod…

NASA:北极辐射-冰桥海冰实验(ARISE)2014年原地云数据产品

ARISE_Cloud_AircraftInSitu_C130_Data 简介 ARISE_Cloud_AircraftInSitu_C130_Data_1是北极辐射-冰桥海冰实验&#xff08;ARISE&#xff09;2014年原地云数据产品。该产品是位于华盛顿的美国宇航局科学任务局地球科学部辐射科学、冰冻层科学和机载科学计划共同努力的成果。…

基于单片机的一氧化碳报警系统的设计与实现

摘 要&#xff1a; 一氧化碳对人体有害&#xff0c;尤其超标时会影响人们的健康 。 因此文章设计了一款基于单片机的一氧化氮报警器设计。 论文通过传感器检测一氧化碳浓度&#xff0c;经过 AD 转换&#xff0c;再把检测信号传递给单片机&#xff0c;经过分析处理&#xff0c…

论文辅助笔记:Large Language Models are Zero-Shot Next LocationPredictors

论文理论部分&#xff1a;论文笔记&#xff1a;lunLarge Language Models are Zero-Shot Next LocationPredictors-CSDN博客 2 Data 2.1 Dataset类 2.2 下载文件 2.3 get_dataset 2.4 get_trajectories trajectory_split暂时略去 # save the test dictionary and the true l…

redis核心数据结构源码分析

dictEntry和redisObject 在 Redis 的实现中&#xff0c;当一个键值对被创建并存储时&#xff0c;键通常是一个字符串&#xff0c;而值则是一个 redisObject。因此&#xff0c;在 dictEntry 结构中&#xff0c;key 成员指向的是一个字符串&#xff0c;而 v.val 成员则指向一个 …

ChatGPT 3.5/4.0简单使用手册

ChatGPT 3.5/4.0 是一种先进的人工智能聊天机器人&#xff0c;能够理解和生成自然语言文本&#xff0c;为用户提供信息检索、问题解答、语言翻译等服务。 系统要求 操作系统&#xff1a;无特定要求&#xff0c;支持主流操作系统。网络连接&#xff1a;需要稳定的网络连接来使…

45.5【C语言】typedef

目录&#xff1a; *全称 *格式 一般指针 数组指针 函数指针 *细节 *全称 type define 类型&#xff08;重新&#xff09;定义&#xff08;或命名&#xff09;&#xff0c;可简化输入 *格式 1.非指针类型: typedef 类型 简化名称 typedef signed long long k; signed long …

期末九天从入门到精通操作数据库(mysql)

对应资源包名称&#xff1a; 期末九天从入门到精通操作数据库(mysql) 学习目标&#xff1a; 掌握数据库的基本操作&#xff0c;熟练使用navicat工具. 九天极限掌握数据库 学习内容&#xff1a; 数据查询实验视图管理实验索引管理实验用户安全性管理实验MySQL备份和还原实…

搭建自己的金融数据源和量化分析平台(七):定时更新上市公司所属行业门类及大类

0x00 前言 由于此前从深交所下载的股票信息中只有行业门类信息&#xff0c;没有行业大类信息&#xff0c;导致后续解析三大报表和量化选股的时候无法进行&#xff1a; 可以看到深交所的股票是没有大类信息的。 再看看上交所的保险股&#xff1a; 因此需要将深交所股票的所属…

WIFI驱动开发

Linux 4.9 内核驱动移植 Linux 4.9 BSP 内核驱动 下载驱动后获得驱动的 tar.gz 压缩包 解压后找到如下驱动与文件夹 进入内核&#xff0c;找到 linux-4.9/drivers/net/wireless 文件夹中&#xff0c;新建文件夹aic8800 并且把上面的驱动与文件夹放入刚刚创建好的 aic8800 中。…

【MySQL】 黑马 MySQL进阶 笔记

文章目录 存储引擎MySQL的体系结构存储引擎概念存储引擎特点InnoDBMyISAMMemory 存储引擎选择 索引概述结构B Tree(多路平衡查找树)B TreeHash为什么InnoDB存储引擎选择使用Btree索引结构? 分类思考题 语法SQL性能分析&#xff08;索引相关&#xff09;SQL执行频率慢查询日志p…

3.3-CoroutineScope/CoroutineContext:从挂起函数里获取 CoroutineContext

文章目录 在 CoroutineScope 获取 CoroutineContext 很简单&#xff0c;只需要在使用的地方使用 coroutineContext 属性就能拿到。比如获取运行的线程&#xff1a; val scope CoroutineScope(EmptyCoroutineContext) scope.launch {val dispatcher coroutineContext[Continu…

SSRF和CSRF实战复现

文章目录 SSRFWeb-Hacking-Lab-master1、Centos未授权访问2、Ubuntu未授权访问3、Ubuntu传入公钥访问4、ssrf_redis_lab_pickle_redis_lab CSRF:windphp SSRF SSRF(Server-Side Request Forgery:服务器端请求伪造) 是一种由攻击者构造形成由服务端发起请求的一个安全漏洞。 f…