排序算法之归并排序

归并排序

归并排序是用到了分治的思想,分治的思想是将一个大问题拆分成很多的小问题,然后再将已经处理完成的小问题合并成整个的大问题。

归并排序首先将数组等分,然后排序等分后的数组,最后再将排好序的两个数组合并成一个排好序的数组。归并排序的时间复杂度是O(n log n)

为了能够更好的理解归并排序,我们来看下面的数组:

image

依然是上次我们用到的没有排序的数组,上面总共有八个数字,等分后就会变成每组四个数字。这样的等分一直持续到只剩下一个数字的情况。

image

由于还没有将数组等分到只有一个元素的情况,所以我们继续等分。

image

此时,每个分组中只有两个数字,还是可以继续等分。

image

在这个时候,等分结束。因为所有的分组都只能分到这种程度,没有数组还能继续等分了。

然后我们将数组进行俩俩合并,首先我们需要比较两个数组中的每一个数据,然后将这些数据放入一个新的数组中,新数组就是有序的。这里比较的过程就是 14 和 33 是升序的,不需改变。27 和 10 是降序的,需要先放入10,再放入27. 35 和19也是降序的,需要先放入19, 再放入27. 最后,42 和 44 是升序的,不需改变。

image

再下一次将前两个合并到一个数组中,后面两个合并到一个数组中。过程是:前两个数组合并,先判断14 和 10,发现 14 要 大于10,所以在新生成的数组中将 10 写在第一个位置上。然后比较14 和 27 发现14小,将 14 写在新生成的数组的第二个位置。在比较33 和 27,发现27 小,将27写在新生成的数组中。由于第二个数组写入完成,所以将第一个数组的剩余部分写入新生成的数组。第三组和第四组合并过程也是类似:19 vs. 42 => 19, 35 vs. 42 => 35, 一个结束另一个写入剩余的部分=>42, 44

image

最后,经过最终的merge操作,生成的数组就是下面的这个模样:

image

代码示例

def MergeSort(array):
    arrayLen = len(array)
    # 如果长度小于等于1,就返回array即可
    if arrayLen <= 1:
        return array
    # 取中间值
    middleNum = arrayLen >> 1
    # 左边的部分去做MergeSort
    leftArray = MergeSort(array[:middleNum])
    # 右边的部分去做MergeSort
    rightArray = MergeSort(array[middleNum:])
    # 将左右两边合并,成为一个新的数组,并已经排序成功
    return MergeCore(leftArray, rightArray)

def MergeCore(leftArray, rightArray):
    # 首先需要定义两个指针,这两个指针分别指向两个数组的第一个元素
    leftPointer, rightPointer = 0, 0
    # 定义一个返回列表(这一步就代表控件复杂度至少是O(n))
    retArray = []
    leftLen = len(leftArray)
    rightLen = len(rightArray)
    # 循环两个数组,循环最小值加入到返回值得数组中
    while leftPointer < leftLen and rightPointer 

你可能感兴趣的:(排序算法之归并排序)