首页 > 编程语言 > 详细

归并排序

时间:2019-04-18 00:30:05      阅读:237      评论:0      收藏:0      [点我收藏+]

一、定义

基本思想

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

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

图解

技术分享图片

过程描述

? 基本过程如图所示,将两个已经排序的数组进行合并。每次比较之后将小的元素拷贝到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

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!