归并排序

一、定义

基本思想

​ 归并排序,其基本思想是合并2个已经排序的表,因为2个表已经排序,所以合并时,将数据放到第三个表中,则该算法可以通过对输入数据一样排序来完成。

  • 基本的算法是取2个输入数组A和B,一个输出数组C。
  • 3个计数器,Actr,Bctr,Cctr,他们初始置于对应数组的开始端。
  • A[Actr]和B[Bctr]中较小者拷贝到C中的下一个位置,相关计数器向前推进一步。
  • 当一个表有一个用完的时候,则将另一个表中剩余部分拷贝到C中。
图解

1328967-20190417233807698-252569612.png

过程描述

​ 基本过程如图所示,将两个已经排序的数组进行合并。每次比较之后将小的元素拷贝到C,知道A指针到最后。B数组无从比较,因为A和B都已经排序,所以直接将B最后都数字拷贝到C。

编程描述

​ 实际问题中,我们处理一个未排序的数组,怎么用它来实现排序呢,因为程序的目的是处理一个数组,而不是2个已排序的数组。例如,程序将数组a={24,13,26,1,2,27,38,15}排序,我们应当如何用程序描述这一过程。

​ 这里采用一个实际经常使用的方法:分治策略

  • 使用递归将前4个数字和后4个数字排序:1,13,24,26,2,15,27,38。
  • 再合并这两部分。

二、算法分析

​ 这里采用递归的程序实现,根据策略是分治的方法。而且是对半递归。我们可以很简单的分析其时间。
\[ T(1)=1\\ T(N)=2T(N/2)+N\\ \]
​ 对上述公式的说明和求解:当N=1,即只有1个元素的时候,我们需要时间是1。当N个元素时,需要先处理前1/2和后面1/2。最后将所有的N拷贝一份。所以得到\(T(N)=2T(N/2)+N\)
\[ T(N)=2T(N/2)+N\\ \frac{T(N/2)}{N/2}=\frac{T(N/4)}{N/4}+1\\ \frac{T(N/4)}{N/4}=\frac{T(N/8)}{N/8}+1\\ ·\\ ·\\ ·\\ \frac{T(2)}{2}=\frac{T(1)}{1}+1 \]
​ 然后使用叠缩求和:将方程左边和右边相加,消去相等项,并且容易知道一共\(logN\)个方程。得到:
\[ \frac{T(N)}{N}=\frac{T(1)}{1}+logN \]
​ 最后得到:\(T(N)=NlogN+N=O(NlogN)\)

结论

  • 所以我们得到归并排序最后的时间为\(O(NlogN)\)

  • 但是它有一个明显的缺陷是:需要创建数组并拷贝。拷贝为常数时间,但是创建一个数组,额外增加了它的内存开销。

​ 但是对数组的拷贝和内存的开辟,不同的语言是不一样的。例如:Java的引用对象排序时,拷贝数组,只是拷贝其对象的引用。只涉及到引用的赋值。所以归并排序作为Java范型排序的算法

​ 而C++的范型排序则不同,如果拷贝的对象过于庞大,那会产生很大的时间和内存开销。是不能接受的。

三、代码地址

https://github.com/dhcao/dataStructuresAndAlgorithm/blob/master/src/chapterSeven/MergeSortEx.java

转载于:https://www.cnblogs.com/dhcao/p/10727077.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值