归并排序 java_Java学习算法——归并排序法的思想与实现

224a83a96f85468d0ddc55818ec7013c.png

归并排序(merge-sort),是一种时间复杂度为O(nlog n),空间复杂度为T(n)的排序算法,发明者为大名鼎鼎的20世纪的全能通才——约翰·冯·诺依曼。

我们先来看看O(nlog n)和O(n^2)的时间复杂度的比较:

bb9362edb8867c1a2f153d9771f8ac17.png

差距一目了然。。。不用说了吧。

然后我们来看一下归并排序算法:我们想把下图中的元素从小大到排序,使用归并排序算法的思想怎么做呢?

7d62a1557e79374ea209807dbad599c0.png

是这样的,归并算法的思想是:我们可以把上面的元素分成两半,两半排好序,再把它们归并。

accdb651ac6c04da573924bbc23a82ff.png

上面这个图,我们是怎么让左边的一半和右边的一半都拍好序的呢?其实我们的思想也是又继续对半的分

先将左右两边的那组

元素分成一半的一半,然后再分成一半的一半,然后再分成一半一半.......就像下图这样的分,直到分到只有一个元素的时候,这时候就不能再分了。

这时候,可以把只有一个元素的部分看成已经排好序,然后依次归并回去。

0cb54e7676a3b46ee657eb635aba1ba3.png

080eeec48d0f03875b23ac859d1e5c2d.png

c42a6096f11b8d00e3d0ddff37f9ffe3.png

下面我们来看:

9fb4eef0e2d45a958f6bfe370206b562.png

上图有8个元素,分到不能再分,最底层是第3层(从0开始),找规律可得其实就是8/2,8/2/2,8/2/2/2,也就是log以2为底8的对数层,那么有N个元素,就是log(N)层

ec07e90628ed8948e45c64be690c3c4d.png

总之,当元素有N个的时候,这个层数就是log(N)这样的数量级的,在这种情况下,我们要处理的数量级都是一样的N,虽然我们把它分成了不同的部分。

52b2a0b3ef6268268aa4a04cee2181c4.png

到上面这里,我们又怎么让左右两边的元素归并呢?看着虽然简单,但是代码不简单啊。。。。天才的世界就是不一样。

我们不能再像冒泡排序、插入排序,选择排序那样的判断交换位置了,而是需要开辟一个新的一毛一样和原来的数组元素一样大的空间来辅助我们完成归并排序。

使用了临时空间,归并的过程将变得非常容易。。。。(( ╯□╰ ))

7ea857918213fd6487a56f65e88bd65e.png

然后,我们需要使用3个索引,用于指向不同的位置

9a962bfb07e6e71aeb9ae5b2d1fbf720.png

a20270d57e376e29a75d60a9eff54b6c.png

我们左边和右边的两个索引对应的元素比较大小,小的放入临时空间中,同时,移动指针

1de891f8f5ab059e765a371e0d5b5463.png

重复上面的过程就可以完成了归并排序

下面是Java代码的实现(主要代码):

49328f40f82473d51952a413b0351d32.png

merge(arr,l,mid,r)归并方法:

05c7a74104cdbfe8371523118c906fcb.png

d8b19acea587fa4432844cb0135a7d8c.png

4ada54f219d743b5eed56a9d42e6235e.png

当我们的元素像上图这样的话,可能左边已经归并好,右边还没有好,防止索引越界之后一序列问题,这时候我们就需要判断了

05f1806137b257366e2dfafbea5fff6c.png

同理,也有可能右边已经归并好了,左边的没有好

时间复杂度分析,一共有log(N)层,每层的元素都一样都是N,我们在归并过程中,每层都归并N次,也就是时间复杂度为O(nlog n),空间复杂度为T(n)

以后再补充吧,有的地方还是不太懂,慢慢来咯,比如优化方面,还有其他的( ╯□╰ )

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值