(1)基本概念
归并排序(Merge Sort)是一种非常高效的排序方式,它用了分治和递归的思想,基本排序思想是:先将整个序列两两分开,然后每组中的两个元素排好序。接着就是组与组和合并,只需将两组所有的元素遍历一遍,即可按顺序合并。以此类推,最终所有组合并为一组时,整个数列完成排序。
递归三要素:
基本结束条件:数据表仅有一个数据项,且是排好序的。
缩小规模:将数据表分裂为相等的两半,规模减小为原来的二分之一;
调用自身:将两半分别调用自身排序,然后将分别排好序的两半进行归并,得到排好序的数据表。
#代码一
def merge_sort(lst):
#递归结束条件
if len(lst)<=1:
return lst
#分解问题,并递归调用
middle = len(lst)//2
left=merge_sort(lst[:middle])#左半部排好序
right=merge_sort(lst[middle:])#右半部切片排好序
#合并左右半部完成排序
merged=[]
while left and right:#左右半部还有数据就进行合并
if left[0]<=right[0]:#左半部与右半部首个数据进行比较
merged.append(left.pop(0))#将较小的数据添加至归并列表后面并删除原来的
else:
merged.append(right.pop(0))
merged.extend(right if right else left)#将左边或右边最后剩余的一个数据嫁接至归并列表后
return merged
if __name__ == '__main__':
a = [3,4,38,5,47,15,36,26,27,2,46,4,19,50,48]
print (merge_sort(a))
#代码二
def merge(a, b):
c = []
while len(a) > 0 and len(b) > 0:
if a[0] < b[0]:
c.append(a.pop(0))
else:
c.append(b.pop(0))
c.extend(a)
c.extend(b)
return c
def merge_sort(lst):#采用分治法,将列表分为左右两个子列表并进行排序
if len(lst) <= 1:
return lst
mid = len(lst) // 2
left = merge_sort(lst[:mid])
right = merge_sort(lst[mid:])
return merge(left, right)
lst = [3,4,38,5,47,15,36,26,27,2,46,4,19,50,48]
print(merge_sort(lst))
3)算法分析
将归并排序分为分裂和归并两个过程
分裂的过程借鉴二分查找中的分析结果,是对数复杂度,时间复杂度为O(log n)
归并的过程相对于分裂的每个过程,其所有数据项都会被比较和放置一次,是线性复杂度,其时间复杂度是O(n)。
综合考虑,每次分裂的部分都是进行一次O(n)的数据项归并,总的时间复杂度是O(nlog n)