数据科学家成长之旅

关注 机器学习,深度学习,自然语言处理,数学

排序算法(5)——归并排序

__author__ = 'steven'
# coding=utf-8
'''归并排序
    归并排序(Merge sort,台湾译作:合并排序)是建立在归并操作上的一种有效的排序算法。
    该算法是采用分治法(Divide and Conquer)的一个非常典型的应用

    步骤:
        1.申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
        2.设定两个指针,最初位置分别为两个已经排序序列的起始位置
        3.比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
        4.重复步骤3直到某一指针达到序列尾
        5.将另一序列剩下的所有元素直接复制到合并序列尾

    算法特点:
        可以用一个例子来体会一下假如有这样一个数组{ 3,7,2,5,1,0,4,6 },
        冒泡和选择排序的比较次数是25次。直接插入排序用了15次。
        而归并排序的次数是相对稳定的,由我们上面提到的比较次数的计算方法,
        我们的例子要合并4对长度为1的,2对长度为2的,和1对长度为4的。
        归并排序的最多的比较次数为4 * 1 + 2 * 3 + 7 = 17次。

        因为元素的随机性,直接插入排序也可能是相当悲剧的,归并排序在比较次数上的优势。

    将数列分开成小数列一共要 logn 步,每一步合并有序数列(调用一次 merge),复杂度为O(n)
    归并排序平均时间复杂度为O(nlogn),是一种稳定的算法.
'''

# list = [5, 8, 1, 4, 2, 7, 3, 6]
list = [8, 7, 6, 5, 4, 13, 2, 1]

# 合并数列
def merge(left, right):
    list = []
    i, j = 0, 0
    while i < len(left) and j < len(right):
        if left[i] < right[j]:
            list.append(left[i])
            i += 1
        else:
            list.append(right[j])
            j += 1
    # 把比较后,较长的 list剩下来的部分接上去
    list += left[i:]
    list += right[j:]
    return list

# 递归的方法从最小单元开始拆分,合并
def merge_sort(list):
    if len(list) <= 1:
        return list
    num = len(list) // 2
    left = merge_sort(list[:num])  # 递归调用,左半部分排好序
    right = merge_sort(list[num:])  # 递归调用,右半部分排好序
    # print('list:%s'%list)
    # print('left:%s'%left)
    # print('right:%s'%right)
    # print('merge:%s'%merge(left, right))
    # print('------')
    return merge(left, right)

print(merge_sort(list))

posted on 2017-03-04 19:58  会飞的蝸牛  阅读(399)  评论(0编辑  收藏  举报

导航