归并排序
介绍:
归并排序是创建在归并操作上的一种有效的排序算法,1945年由冯·诺伊曼首次提出。
思想:
归并排序的实现分为递归实现与非递归(迭代)实现。递归实现的归并排序是算法设计中分治策略的典型应用,我们将一个大问题分割成小问题分别解决,然后用所有小问题的答案来解决整个大问题。非递归(迭代)实现的归并排序首先进行是两两归并,然后四四归并,然后是八八归并,一直下去直到归并了整个数组,归并排序算法主要依赖归并(Merge)操作
代码:
#!/usr/bin/python
def MergeSort(input_list):
def merge(input_list,left,mid,right,temp):
#合并函数
i = left
j = mid+1
k=0
while i <= mid and j <= right:
#将左右两个升序子序列中较小的那个元素放入临时列表temp中
if input_list[i] <= input_list[j]:
temp[k] = input_list[i]
i += 1
else:
temp[k] = input_list[j]
j += 1
k += 1
#将剩余子序列中的元素按序加入temp中
while i <= mid:
temp[k] = input_list[i]
i += 1
k += 1
while j <= right:
temp[k] = input_list[j]
j += 1
k +=1
#将合并好且排好序的temp复制给input_list
k = 0
while left<=right:
input_list[left] = temp[k]
left += 1
k += 1
def merge_sort(input_list,left,right,temp):
#递归进行归并排序
if left >= right:
return
mid = (left+right)//2
#左边子序列归并
merge_sort(input_list,left,mid,temp)
print("本次归并后的结果是")
print(input_list)
#右边子序列归并
merge_sort(input_list,mid+1,right,temp)
merge(input_list,left,mid,right,temp)
if input_list == []:
return []
sorted_list = input_list
#新建一个与input_list等空间的temp变量
temp = [0]*len(sorted_list)
merge_sort(sorted_list,0,len(sorted_list)-1,temp)
return sorted_list
if __name__ == '__main__':
input_list = [50,123,543,187,49,30,0,2,11,100]
print("input_list:")
print(input_list)
sorted_list = MergeSort(input_list)
print("sorted_list:")
print(input_list)
结果:
input_list:
[50, 123, 543, 187, 49, 30, 0, 2, 11, 100]
本次归并后的结果是
[50, 123, 543, 187, 49, 30, 0, 2, 11, 100]
本次归并后的结果是
[50, 123, 543, 187, 49, 30, 0, 2, 11, 100]
本次归并后的结果是
[50, 123, 543, 187, 49, 30, 0, 2, 11, 100]
本次归并后的结果是
[50, 123, 543, 187, 49, 30, 0, 2, 11, 100]
本次归并后的结果是
[49, 50, 123, 187, 543, 30, 0, 2, 11, 100]
本次归并后的结果是
[49, 50, 123, 187, 543, 30, 0, 2, 11, 100]
本次归并后的结果是
[49, 50, 123, 187, 543, 0, 30, 2, 11, 100]
本次归并后的结果是
[49, 50, 123, 187, 543, 0, 2, 30, 11, 100]
本次归并后的结果是
[49, 50, 123, 187, 543, 0, 2, 30, 11, 100]
sorted_list:
[0, 2, 11, 30, 49, 50, 100, 123, 187, 543]
分析:
1.算法性能
2.时间复杂度
归并排序的形式就是一棵二叉树,它需要遍历的次数就是二叉树的深度,而根据完全二叉树的可以得出它的时间复杂度是O(n*log2n)
3.空间复杂度
需要一个与待排序列等空间大小的变量,故空间复杂度为O(n)
4.算法稳定性
归并排序是一种稳定排序算法,在merge函数里有如下代码,如果碰到前部分序列里元素和后部分序列里元素相等时,先把前部分序列元素放入新序列中,故,相等元素的顺序是不发生改变的。因此是稳定的
if input_list[i] <= input_list[j]:
temp[k] = input_list[i]
i += 1
else:
temp[k] = input_list[j]
j += 1
k += 1
5.归并排序和堆排序、快速排序的比较
若从空间复杂度来考虑:首选堆排序,其次是快速排序,最后是归并排序。
若从稳定性来考虑,应选取归并排序,因为堆排序和快速排序都是不稳定的。
若从平均情况下的排序速度考虑,应该选择快速排序。