__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))