【高级排序算法】1、归并排序法 - Merge Sort
归并排序法 - Merge Sort
简单记录 - 玩转算法系列–玩转算法 -高级排序算法(Sorting-Advance)
O(n*log n)的排序算法 归并排序法 - Merge Sort
nlogn 比 n^2 快多少?

测试用例太少了 优势  数据量
nlogn 的算法,n逐渐增大,速度优势越来越明显。
一个优化改进后的算法也许是一个笨的算法一辈子都赶不上的结果,好的优化后算法一瞬间就运算完了。
归并排序设计思想
归并排序算法会把序列分成长度相同的两个子序列,当无法继续往下分时(也就是每个子序列中只有一个数据时),就对子序列进行归并。归并指的是把两个排好序的子序列合并成一个有序序列。该操作会一直重复执行,直到所有子序列都归并为一个整体为止。
时间、空间复杂度
归并排序
执行时间:平均情况与最差情况为O(nlog(n)),
归并排序中,分割序列所花费的时间不算在运行时间内(可以当作序列本来就是分割好的)。在合并两个已排好序的子序列时,只需重复比较首位数据的大小,然后移动较小的数据,因此只需花费和两个子序列的长度相应的运行时间。也就是说,完成一行归并所需的运行时间取决于这一行的数据量。看一下上面的图便能得知,无论哪一行都是n个数据,所以每行的运行时间都为O(n)。而将长度为n的序列对半分割直到只有一个数据为止时,可以分成log2n行,因此,总共有log2n行。也就是说,总的运行时间为O(nlogn)。
存储空间:看情况。一般是归并排序的空间复杂度是O(n),因为归并时用到了辅助数组。
归并排序是将数组分成两半,这两半分别排序后,再归并在一起。排序某一半时,继续沿用同样的排序算法,最终,将归并两个只含一个元素的数组。这个算法的重点在于“归并”。
快速排序
执行时间:平均情况为O(nlog(n)),最差情况为O(n2),
存储空间:O(log(n))快速排序指随机挑选一个元素,对数组进行分割,以将所有比它小的元素排在比它大的元素前面。
快速排序在一般情况下,一致认为快速排序是最好的一种排序算法,而且不需要额外的存储空间。其最佳应用场合是应用于大型数据集。
我们知道归并排序的时间复杂度是O(nlogn),比最直观的O(n2)要快,但同时归并排序需要一个长度为n的辅助数组,相当于我们用O(n)的空间消耗换来了时间效率的提升,因此这是一种用空间换时间的算法。尽管归并排序可以使用手摇算法将额外空间复杂度降至 O(1),但这样最差情况下的时间复杂度会因此上升至O(N2)。
归并排序基本上与快速排序算法的性能相同,但它需要使用两倍于快速排序的存储空间,而具有讽刺意味的是,其最佳应用场合是在超大数据集中,因为归并排序的原理就是对原始的乱序数据不断进行对半分割。
归并排序图解
Merge Sort
归并排序
归并基本思想是将两个(或以上)有序的序列合并成一个新的有序序列。细化来说,归并排序先将长度为n的无序序列看成是n个长度为1的有序子序列,首先做两两合并,得到 n/2个长度为2的有序子序列,再做两两合并……不断地重复这个过程,最终可以得到一个长度为n的有序序列。

整个序列一直划分,直到无法继续往下分时(也就是每个子序列中只有一个数据时),就对子序列进行归并。

O(n*log n)
O(n) O(logn)
每一部分就一个元素了 。为什么分到只有一个呢?不用排序了 ,简单归并。
例如:长度为8的数据序列,只需经过3次合并。也就是说,对于长度为n的数据序列,只需经过log2n次合并。对于归并排序而言,其算法关键就在“合并”。如何将两个有序的数据序列合并成一个新的有序序列?合并算法的具体步骤如下。
左右分别排序 分半 排序 归并
8 6 2 3 1 5 7 4
6 8 2 3 1 5 4 7




归并过程Merge


辅助我们 临时空间 存储序列

多使用了存储空间 O(n)
时间、空间 一般优先考虑时间





三个索引 i j k
…
最后序列 1 2 3 4 5 6 7 8
归并过程 一部分与另一部分比较 一个个比 小到大 小就放过去
递归 归并排序
归并排序描述
像快速排序算法一样,由于归并排序也是一种分治算法,因此可以用分治法的思想将排序分为三个步骤,这样有助理解:
1.分:将数据集等分为两半。
2.治:分别在两个部分用递归的方式继续使用归并排序法。
3.合:将分开的两个部分合并成一个有序的数据集。
归并排序与其他排序最大的不同在于它的归并过程。这个过程就是将两个有序的数据集合并成一个有序的数据集。正如我们看到的,合并两个有序数据集的过程是高效的,因为我们只需要遍历一次即可。根据以上事实,再加上该算法是按照可预期的方式来划分数据的,这使得归并排序在所有的情况下都能达到快速排序的平均性能。遗憾的是,归并排序需要额外的存储空间来运行,这也是它的一个缺点。因为合并过程不能在无序数据集本身中进行,所以必须要有两倍于无序数据集的空间来运行算法。这点不足极大地降低实际中使用归并排序的频率,因为通常可以使用不需要额外存储空间的快速排序来代替它。然而,归并排序对于海量数据处理还是非常有价值的,因为它能够按预期将数据集分开。这使得我们能够将数据集分割为更加可管理的数据,接着用归并排序将处理数据,然后不断地合并数据,在这个过程中并不需要一次存储所有的数据。
归并排序小结
归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。归并排序是一种稳定的排序方法。归并排序算法会把序列分成长度相同的两个子序列,当无法继续往下分时(也就是每个子序列中只有一个数据时),就对子序列进行归并。归并指的是把两个排好序的子序列合并成一个有序序列。该操作会一直重复执行,直到所有子序列都归并为一个整体为止。
归并排序执行时间:平均情况与最差情况为O(nlog(n)),存储空间:看情况。一般是归并排序的空间复杂度是O(n),因为归并时用到了辅助数组。
快速排序在一般情况下,一致认为快速排序是最好的一种排序算法,而且不需要额外的存储空间。归并排序与快速排序一样,它依赖于元素之间的比较来排序,归并排序在所有的情况下都能达到快速排序的平均性能。但是,归并排序需要额外的存储空间来完成排序过程。
参考资料
1、算法精解:C语言描述作者:【美】劳顿(Loudon,K.)
2、我的第一本算法书作者:[日]宫崎修一,石田保辉
3、玩转算法系列–玩转算法 -高级排序算法
【高级排序算法】1、归并排序法 - Merge Sort的更多相关文章
- 【DS】排序算法之归并排序(Merge Sort)
		
一.算法思想 归并排序是建立在归并操作上的一种有效的排序算法.该算法是采用分治法的一个非常典型的应用,指的是将两个已经排序的序列合并成一个序列的操作.其归并思想如下: 1)申请空间,使其大小为两个已经 ...
 - 排序算法:归并排序(Merge Sort)
		
归并排序 归并排序采用了分治策略(divide-and-conquer),就是将原问题分解为一些规模较小的相似子问题,然后递归解决这些子问题,最后合并其结果作为原问题的解. 归并排序将排序数组A[1. ...
 - javascript数据结构与算法--高级排序算法(快速排序法,希尔排序法)
		
javascript数据结构与算法--高级排序算法(快速排序法,希尔排序法) 一.快速排序算法 /* * 这个函数首先检查数组的长度是否为0.如果是,那么这个数组就不需要任何排序,函数直接返回. * ...
 - 【算法】归并排序(Merge Sort)(五)
		
归并排序(Merge Sort) 归并排序是建立在归并操作上的一种有效的排序算法.该算法是采用分治法(Divide and Conquer)的一个非常典型的应用.将已有序的子序列合并,得到完全有序的序 ...
 - 【高级排序算法】2、归并排序法的实现-Merge Sort
		
简单记录 - bobo老师的玩转算法系列–玩转算法 -高级排序算法 Merge Sort 归并排序 Java实现归并排序 SortTestHelper 排序测试辅助类 package algo; im ...
 - [算法]——归并排序(Merge Sort)
		
归并排序(Merge Sort)与快速排序思想类似:将待排序数据分成两部分,继续将两个子部分进行递归的归并排序:然后将已经有序的两个子部分进行合并,最终完成排序.其时间复杂度与快速排序均为O(nlog ...
 - Java常见排序算法之归并排序
		
在学习算法的过程中,我们难免会接触很多和排序相关的算法.总而言之,对于任何编程人员来说,基本的排序算法是必须要掌握的. 从今天开始,我们将要进行基本的排序算法的讲解.Are you ready?Let ...
 - javascript数据结构与算法--高级排序算法
		
javascript数据结构与算法--高级排序算法 高级排序算法是处理大型数据集的最高效排序算法,它是处理的数据集可以达到上百万个元素,而不仅仅是几百个或者几千个.现在我们来学习下2种高级排序算法-- ...
 - javascript高级排序算法之快速排序(快排)
		
javascript高级排序算法之快速排序(快排)我们之前讨论了javascript基本排序算法 冒泡排序 选择排序 插入排序 简单复习: 冒泡排序: 比较相邻的两个元素,如果前一个比后一个大,则交换 ...
 
随机推荐
- 自定义radio、checkbox的样式
			
input标签中的radio和checkbox是很表单中常用的类型,大多时候,默认样式并不能满足我们的需求,所以有了此篇. 自定义样式,由此开启: html: <div class=" ...
 - Ubuntu18 安装 MySQL 8.0.22
			
Ubuntu18 安装 MySQL 8.0.22 网上教程都比旧,也不是第一次安装了,但依然还是花了比较多的时间,特此记录本次安装过程.因是安装完毕后回忆记录,或有错漏. 第一步: 下载 mysql ...
 - 恕我直言,你可能连 GitHub 搜索都不会用 - 如何精准搜索的神仙技巧
			
大家好,我是你们的 前端章鱼猫,一个不喜欢喵.又不喜欢吃鱼的超级猫 ~ 今天给大家带来的是 在 GitHub 上如何精准搜索的神仙技巧. [前端GitHub:https://github.com/bi ...
 - 图像处理论文详解 | Deformable Convolutional Networks | CVPR | 2017
			
文章转自同一作者的微信公众号:[机器学习炼丹术] 论文名称:"Deformable Convolutional Networks" 论文链接:https://arxiv.org/a ...
 - 利用设计模式消除业务代码中的 if-else
			
准备工作:假设这样的一个业务场景:有一个自动开票的功能需要实现,在程序里面需要根据账单的类型执行对应的处理逻辑. 以下使用了 Lombok 简化代码!!! 账单类型枚举: /** * @author ...
 - VS批量添加多个文件
			
步骤 1.设置项目,显示所有文件.2.点击项目,右键在资源管理器中打开.3.将要导入的文件复制到对应的文件中去.4.在解决方案中就可以看到刚才添加的多个文件.5.在新加的文件夹上右键,包括在项目中.
 - [EF] - 全连接
			
在EntityFramework里有个DeflautIfEmpty方法可以用来表示数据库里的左联接或者右连接: http://msdn.microsoft.com/en-us/library/bb39 ...
 - 面向切面@Aspect
			
package com.imooc.demo.filter; import org.springframework.core.Ordered; import org.springframework.c ...
 - Java通过IO流输出文件目录
			
//通过IO流输出文件目录,不同级的目录之间用*间隔 1 package com.fjnu.io; 2 3 import java.io.File; 4 5 public class dicOut { ...
 - Linux课程知识点总结(二)
			
Linux课程知识点总结(二) 七.Shell实用功能 7.1 命令行自动补全 在Linux系统中,有太多的命令和文件名称需要记忆,使用命令行补全功能[Tab]可以快速的写出文件名和命令名 7.2 命 ...