文章目录

  • 排序算法时间O(n log2n)篇概述
  • 算法思路
  • 动画演示
  • 代码实现
  • 算法特点
  • 总结

排序算法时间O(n log2n)篇概述

在排序算法中,平均时间O(n log2n)是除特殊排序算法之外最快的啦,其中快速排序更是人们心目中最实用的排序算法。于是,蒟蒻君就为大家整理的最常见的三种时间复杂度O(n log2n)的排序算法。
大家最好从第一篇开始看。

算法思路

归并排序,就是先归再并,是典型的分治法。

将数组不停地分为两半,直到每部分只有一个元素。

不停地将所有相邻两组数排成一组有序的数,直到整个数组中只有一组数。

举个栗子

给定8个元素的数组{8, 5, 3, 6, 1, 2, 7, 4}。


我们先把数组每次二分,直到每组数都只有1个数。

自底向上地将所有相邻的两组数排序成一组有序的数。此时,每组数的个数均为2个。

然后,我们将两个数一组的数每两组放在一起排序。此时,每组数的个数均为4个。

最后,我们将这两组数排序,就得到了最终的结果。
所以,我们目前最大的问题就是如何将两个有序的子序列合并成一个有序的序列,最短又能用多长时间合并呢?

我们分别定义两个指针(红/绿色箭头),开始分别指向两个子序列的开头。
我们每次需要将目前两个指针指向的元素取最小的放入答案数组,因为若两个数组a和b均为升序排列,则a数组与b数组中的最小值也就是a[0]和b[0]中的最小值。
在这里,a数组和b数组就是数组目前部分的前半部分和后半部分啦

因为1<3,所以将1存入答案数组中。b数组指针同时后移一位,指向下一个元素。


继续比较,2<3,将2存入答案数组,b数组指针后移一位。


3<4,将3存入答案数组,a数组指针后移一位。

后面以此类推~
还有一种特殊情况,就是一个数组已经全部进入答案数组,而另一个还有一部分。此时直接将这个数组的剩余部分全部放入答案数组就ok了,因为此数组本来就是有序的。
小伙伴,你学会了吗?

动画演示

代码实现

void merge(int a[], int l, int r) { // 数组,排序部分的范围(左,右)int tmp[r - l + 1]; // 答案数组int mid = l + r >> 1;   // 更快速的(l + r) / 2int i = l, j = mid + 1, k = 0;while (i <= mid && j <= r) {if (a[i] <= a[j]) {  // 答案数组存储两个指针指向的数中最小的数,并让指针往后移一位tmp[k] = a[i];++i;} else {tmp[k] = a[j];++j;}++k;    // 答案数组该存下一位啦}while (i <= mid) {  // 如果有一个数组还未存储完tmp[k] = a[i];++k;++i;}while (j <= r) {tmp[k] = a[j];++k;++j;}for (int i = 0; i < r - l + 1; ++i) { // 将答案数组copy回a数组a[l + i] = tmp[i];}
}
void merge_sort(int a[], int l, int r) {if (l < r) {    // 序列长度最少为1int mid = l + r >> 1;merge_sort(a, l, mid);  // 前半部分排序merge_sort(a, mid + 1, r);  // 后半部分排序merge(a, l, r); // 两个子序列排序}
}

算法特点

  • 由于每次必须将整个序列二分,再合并,即归并排序的最优/最差/平均时间复杂度均为O(n log2n)。
  • 由于每次排序两个有序序列都需要一个答案数组,空间消耗较大,空间复杂度为O(n)。
  • 若两个元素的值相等,答案数组会优先存储前面的数,即归并排序算法有稳定性。

总结

由此,我们可以总结出这张图。

这节课我们学习了经典的排序算法——归并排序,下节课我们会继续学习快速排序。

排序算法大比拼(2.1)——时间O(n log2n)篇之归并排序相关推荐

  1. 排序算法大比拼(2.2)——时间O(n log2n)篇之快速排序(左右指针法)

    文章目录 概述 算法思路 动画演示 代码实现 算法特点 概述 快速排序是对冒泡排序的一种改进,也是当前人们认为综合效率最好的排序算法. 下面,让我们一起来学习最基本的快速排序叭~ 建议大家先看看第一篇 ...

  2. 排序算法 之四 分类、时间/空间复杂度、如何选择

    写在前面   现在网上关于排序算法的文档不计其数,为什么要写这篇文章呢?主要是因为一些算法虽然在平时有用到,但是从来没有细细整理过,没有个统一.整体的认识.写这篇文章一来是进行一下总结,二来趁机再系统 ...

  3. 12八大排序算法的稳定性以及时间空间复杂度总结

    文章目录 一.排序的稳定性 二.八种排序方式的复杂度和稳定性 三.总结 一.排序的稳定性 假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中 ...

  4. 排序算法系列之(七)——分分合合的归并排序

    文章目录 前言 归并排序 排序过程 代码实现 代码分析 运行测试 总结 前言 再一次总结基础的排序算法,印象里距离上一次总结排序也没过多久,查询后才发现上一篇总结<排序算法系列之(六)--逐步砍 ...

  5. 【转】排序算法复习(Java实现) (二): 归并排序,堆排序,桶式排序,基数排序...

    http://www.blogjava.net/javacap/archive/2007/12/14/167618.html 六 归并排序 算法思想是每次把待排序列分成两部分,分别对这两部分递归地用归 ...

  6. 排序算法:希尔、归并、快速、堆排序

    排序算法 排序是非常常用,非常基本的算法.排序的方法有很多,比如插入排序.选择排序.希尔排序.归并排序.快速排序.堆排序. 本次试验重点实现:希尔排序.归并排序.快速排序.堆排序 插入排序 简单说就是 ...

  7. 六种排序算法的JavaScript实现以及总结

    最近几天在系统的复习排序算法,之前都没有系统性的学习过,也没有留下过什么笔记,所以很快就忘了,这次好好地学习一下. 首先说明为了减少限制,以下代码通通运行于Node V8引擎而非浏览器,源码在我的Gi ...

  8. 中希尔排序例题代码_【数据结构与算法】这或许是东半球分析十大排序算法最好的一篇文章...

    码农有道 历史文章目录(请戳我) 关于码农有道(请戳我) 前言 本文全长 14237 字,配有 70 张图片和动画,和你一起一步步看懂排序算法的运行过程. 预计阅读时间 47 分钟,强烈建议先收藏然后 ...

  9. Visual C# 诠释常用排序算法

    Visual C# 诠释常用排序算法 前段时间因为项目需要,做了个用来对数组排序的类,顺便把以前学过的几种排序算法用C#实现一下.用C#的一些机制来诠释了一下算法的是实现.在阅读本之前,需要一些对C# ...

最新文章

  1. IDEA 一些基本概念
  2. sersync进行实时同步数据
  3. 机器学习导论(张志华):主元分析
  4. 最短路---dijsktra--邻接矩阵
  5. 聊一聊单机、集中式、分布式和云原生存储
  6. having和where可以同时使用吗_阴、阳离子聚丙烯酰胺可以同时混合溶解使用吗?...
  7. RestAPI的进化之路,后端MVVM模式或许来临,通过观察者模式,后端收集前端的GET类请求,主动推送数据变更到前端
  8. Maven入门基础-环境篇
  9. win10系统更新在哪_五步教你win10永久关闭系统自动更新
  10. 程序员晒追女神聊天截图,坦言第一次没经验,网友直呼凭实力单身
  11. Web浏览器已经限制此文件显示
  12. 服务器装系统怎样进bios设置,重装系统怎么进入bios设置界面?进入bios设置界面详细教程!...
  13. 学而思python分几个level_学而思新概念英语课程体系表
  14. php上传文件失败解决方式
  15. 不会编程却想做APP ? 让Power Apps 来帮你
  16. 一分钟整明白web前端和Java后端的就业前景
  17. springboot+vue+element-ui下载excel模板(静态文件)
  18. 如何让网站在浏览器网址前面显示小图标?ico图标怎么放?
  19. 计算机专业毕业设计致谢,计算机毕业论文致谢范文3篇
  20. 万维网www/web —— Tim Berners-Lee理念:建立全球范围信息网,彻底打破信息存取壁垒(网页相互链接,URL,HTTP,HTML,CGI等)

热门文章

  1. 《VALORANT》: 双塔迷城的诞生
  2. 如何修改Oracle VM virtualbox虚拟机的屏幕大小
  3. css绘制实心三角形
  4. 【学习生涯】预科学习笔记
  5. 科比最新超酷广告《门徒》
  6. beamer笔记——幻灯片比例改为16:9
  7. 每日一题 极限值为5201314
  8. 【记录读论文时遇到的一些算法2】—— Occupancy Grid Map
  9. 更换计算机名后打不开PPT,PPT打不开的原因和解决办法 从检查开始 -电脑资料
  10. jxl导出excel标题乱码