归并排序(python)

7.归并排序

7.1算法思想

归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。

归并排序是一种稳定的排序方法。时间复杂度为O(nlogn)。但是和的排序算法不同,归并排序需要需要额外的空间,空间复杂度为o(n)。

7.2算法过程

归并排序算法的过程是先分在合,即:

  1. 将一个序列从中间位置分成两个序列;
  2. 在将这两个子序列按照第一步继续二分下去;
  3. 直到所有子序列的长度都为1,也就是不可以再二分截止。这时候再一步一步往上子序列两两合并,最终合并成一个有序序列即可。
    详细的过程可以通过下面这个图来理解(来源于百度):
    归并排序(python)_第1张图片

7.3 python代码

def mergeSort(numList):
    if len(numList) == 0 or len(numList) == 1:
        return numList
    # 分,将原来的序列分成从中间分成两个子序列
    mid = len(numList) // 2
    left = numList[:mid]
    right = numList[mid:]
    # 分别对左子序列和右子序列进行递归,得到排好序的左右子序列
    sortedLeft = mergeSort(left)   # 同样的进行分分合合
    sortedRight = mergeSort(right)
    # 将左右两个排好序的子序列在合并成一个总的排好序的序列,并返回
    return merge(sortedLeft,sortedRight)
def merge(left,right):     # 将两个排好序的子序列合并成一个排好序的子序列
    result = []     # 需要额外的存储空间来存储最后的排好序的结果,所以空间复杂度是o(n)
    while len(left) > 0 and len(right) > 0:   # left和right可能不等长。
        if left[0] <= right[0]:
            result.append(left.pop(0))
        else:
            result.append(right.pop(0))
    # 这里也可以不用pop,而是利用两个移动指针,达到遍历两个数组的目的。
    #最后根据两个指针是否等于数组长度来判断这个子序列里的元素是否已经都进入result中了。
    # 循环结束,不管最后哪个非空,都加上就行。
    result += right 
    result += left
    return result
numlist = [2,4,7,5,8,1,3,6]
print(mergeSort(numlist))
# 输出结果为:[1,2,3,4,5,6,7,8]

你可能感兴趣的:(算法)