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

数据结构系列-归并排序

🌈个人主页:羽晨同学 

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

归并排序

递归版本

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

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

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

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

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

  • 用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)

稳定性:稳定

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

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

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

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 网络安全售前入门01——产品了解
  • 【Tools】区块链技术有哪些应用场景
  • NLP -->定义、应用、与职业前景解析
  • 代码随想录算法训练营第16天 | 第六章 二叉树 part06
  • macOS symbol(s) not found for architecture arm64错误原因总结
  • windows安全软件之火绒杀毒的密码忘记后处理
  • C++ | Leetcode C++题解之第371题两整数之和
  • Java排序算法详解
  • Easysearch 性能测试方法概要
  • 《纳瓦尔宝典》-- 读书笔记
  • 深度学习与神经网络戴做讲解
  • 第1章-04-Chrome及Chrome Driver安装及测试
  • JavaScript 文件上传详解与实现
  • pytorch深度学习基础 8 (使用PyTorch的内置功能和默认参数来构建和训练一个简单的线性模型)
  • (贪心) LeetCode 45. 跳跃游戏 II
  • 【399天】跃迁之路——程序员高效学习方法论探索系列(实验阶段156-2018.03.11)...
  • C++11: atomic 头文件
  • CAP理论的例子讲解
  • If…else
  • Laravel Mix运行时关于es2015报错解决方案
  • Logstash 参考指南(目录)
  • macOS 中 shell 创建文件夹及文件并 VS Code 打开
  • swift基础之_对象 实例方法 对象方法。
  • vue数据传递--我有特殊的实现技巧
  • 分布式事物理论与实践
  • 前端面试总结(at, md)
  • 强力优化Rancher k8s中国区的使用体验
  • 我的面试准备过程--容器(更新中)
  • 我是如何设计 Upload 上传组件的
  • 线性表及其算法(java实现)
  • ​LeetCode解法汇总2182. 构造限制重复的字符串
  • #define与typedef区别
  • (04)Hive的相关概念——order by 、sort by、distribute by 、cluster by
  • (12)Hive调优——count distinct去重优化
  • (Java实习生)每日10道面试题打卡——JavaWeb篇
  • (NSDate) 时间 (time )比较
  • (zhuan) 一些RL的文献(及笔记)
  • (附源码)springboot 校园学生兼职系统 毕业设计 742122
  • (附源码)ssm高校社团管理系统 毕业设计 234162
  • (附源码)ssm失物招领系统 毕业设计 182317
  • (附源码)小程序儿童艺术培训机构教育管理小程序 毕业设计 201740
  • (接口封装)
  • (三)Kafka 监控之 Streams 监控(Streams Monitoring)和其他
  • (十一)c52学习之旅-动态数码管
  • (学习日记)2024.04.10:UCOSIII第三十八节:事件实验
  • (一)、python程序--模拟电脑鼠走迷宫
  • (已解决)报错:Could not load the Qt platform plugin “xcb“
  • (转)fock函数详解
  • (自用)交互协议设计——protobuf序列化
  • .net2005怎么读string形的xml,不是xml文件。
  • .NET开发人员必知的八个网站
  • .NET中统一的存储过程调用方法(收藏)
  • .pyc文件是什么?
  • .sh文件怎么运行_创建优化的Go镜像文件以及踩过的坑
  • /run/containerd/containerd.sock connect: connection refused