上一次我们说了快排的其他版本,还有就是快排的非递归实现
这次我们就说一哈归并排序,归并排序也是很厉害的一种排序,而且归并排序的时间复杂度可以说成标准的O(n log n)
下面我们就来看一下归并排序
我们先来看一下什么是归并排序
假设我们有两组有序的数组
我们要把这两组归并排序
那么就是这样的
假设我们要对这两组有序进行排序
那么我们怎么排序?
首先我们让一个在第一组的第一个位置,让另一个变量在第二个数组的起始位置
就是这样子的
我们先让两个变量记录在两个数组的的位置
如果我们想归并的话
我们在来一个数组,这时候我们给一个i来记录该tmp数组中的值的位置
所以我们此时我们两个数组中begin1和begin2两个位置的值进行比较,如果begin1中的值小于begin2位置的值那么就让begin1位置的值放在tmp数组中i的位置然后让begin1和i都++如果是begin2位置的值小的话,就让begin2位置的值放在tmp数组i的位置然后让begin2和 i都++ 就是这样,下面我们看一下图片
这是第一次
这时候begin1已经结束了,所以我们只需要把begin2剩下的值拷贝到tmp数组中就可以了
就是这样
如果现在还是不清楚归并是什么,那么请好好看一下上面的图片
下面我们就说一下归并排序
其中归并排序就是把两组有序的数组归并好,但是由于我们给的是一组完全无序的数组那么我们要怎么办呢?
其中我们认为如果是只有一个数字那么这个数字就是有序的,所以我们可以使用分治
下面在画一个图片请看一下
请看这个图片,看明白了没有?
那么在看下一个
看明白了没有,同志们
那么在看一下
首先请看上半部分,上半部分就是把这一组数组给依次划分,为一个一个的小数组,知道只剩一个值,那么这时候如果只剩下一个值,我们就认为这个值是有序的
OK看下半部分
既然上面的都是有序的,所以我们首先两两归并,然后两两归并好后,对归并好的数组继续两两归并,最后知道归并结束
OK就是这个样子
所以下面还是看代码
此时,我们来看一下,首先看一下参数里面的tmp就是我们的临时数组,a当然是要排序的数组了
这时候我们的a是一整个大数组,我们怎么样才能让他变成一个个有序的数组呢,那么就是如果是一个值的话,我们就认为他是有序的,这时候我们就定义一个mid它就等于right+left然后对他们的值÷2,这样我们就得到一个中间值,我们使用递归,把left到mid的值传给他自己,然后就是对后半段数组分开把mid+1到right传给他自己,直到left小于等于right(也就是只剩下一个值,或者是没有值) 然后我们就结束递归
此时我们就把这一数组给分成了一个一个的小份
然后我们就可以对这些小数组进行归并,我们定义一个i然后我们继续定义第一个数组的begin和end和第二个数组的begin和end然后就是我们的归并了
就是中间这一段代码,我把他专门截取出来,各位好好看一下,然后我们把他归并到tmp数组中,我们当然得把他拷贝回去,拷贝到a中,毕竟我们是对a进行排序,然后我们就继续递归,直到结束
所以我们可以这样调用,我们把他弄成一个子函数,我们在这个函数里面开一个tmp数组,然后等排序结束后free掉就可以了