参考:
百度百科:归并排序
归并排序(merge sort)
工作原理
将序列分为若干个子序列(子序列均有序),两两子序列进行 归并操作,得到一个新的有序列表,最终归并所有子序列,得到一个递增或递减的序列
归并操作
从左到右逐个比较两个子序列中的元素大小,比如进行递增排序,将较小的元素加入结果序列中,其下标加 1
,继续和另一个序列元素进行比较,直到某一个序列元素已经全部遍历为止,将另一个序列的剩余元素加入到结果序列中,操作完成
算法思想
对于无序列表,无法确切得知哪个子序列是有序的,可以将单个元素设为一个子序列,从而两两进行归并操作
归并排序通常采用递归算法,每次都将序列均分为两个子序列,直到序列数为 1
,将两个子序列进行归并操作后返回
Python 算法实现
# -*- coding: utf-8 -*-
"""
归并排序
"""
import random
__author__ = 'zj'
def create_data(leng, min, max):
"""
创建待排序序列
:param leng: 序列长度
:param min: 最小值
:param max: 最大值
:return: 列表
"""
li = range(min, max)
return random.sample(li, leng)
def merge_sort(li, reverse=False):
"""
归并排序实现
:param li: 待排序列表
:param reverse: 是否从大到小排序,默认为False
:return: 已排序列表
"""
if len(li) == 1:
return li
m = len(li) // 2
l = merge_sort(li[:m], reverse)
r = merge_sort(li[m:], reverse)
return merge_operation(l, r, reverse)
def merge_operation(llist, rlist, reverse=False):
"""
归并操作实现
:param llist: 左侧已排序序列
:param rlist: 右侧已排序序列
:param reverse: 是否从大到小排序,默认为False
:return: 一个已排序序列
"""
llen = len(llist)
rlen = len(rlist)
i = j = 0
res = []
while i < llen and j < rlen:
if llist[i] <= rlist[j]:
if reverse:
res.append(rlist[j])
j += 1
else:
res.append(llist[i])
i += 1
else:
if reverse:
res.append(llist[i])
i += 1
else:
res.append(rlist[j])
j += 1
res.extend(llist[i:])
res.extend(rlist[j:])
return res
if __name__ == '__main__':
da = create_data(10, 30, 60)
print da
res = merge_sort(da, True)
print res
性能分析
稳定性
归并排序是稳定排序算法
其归并操作是发生在相邻两个子序列中,遇到相同大小的元素时,也是左侧的元素先加入结果序列中
时间复杂度
最好,最坏,平均时间复杂度均为 O(nlogn)
空间复杂度
每次归并操作均需要使用 n
个大小的辅助空间,所以空间复杂度为 O(n)