归并排序的详解与python实现
算法思想
归并排序是利用归并的思想实现的排序方法,该算法采用经典的分治策略,将问题拆分成一些小的问题然后递归求解,然后再将得到的解合并在一起,即分而治之。如下图(图是盗的):
拆分:
合并:
即利用递归与分治的技术将数据序列划分为越来越小的半子表,再对半子表排序,最后再用递归方法将排好序的半子表合并成越来越大的有序序列,直至算法结束。
算法步骤
- 先把待排序区间 [s,t] 以中点二分;
- 接着把左边子区间排序;
- 再把右边子区间排序;
- 最后把左区间和右区间用一次归并操作合并成有序的区间 [s,t] 。
算法伪代码
merge_sort(A,start,end) //sorts A[1,n]
if(start<end)
mid =(start+end)/2
merge_sort(A,start,mid)
merge_sort(A,mid+1,end)
merge(A,start,mid,end)
python实现
def merge(left, right):
i, j = 0, 0
n1, n2 = len(left), len(right)
r = []
while i < n1 and j < n2:
while i < n1:
if j == n2:
break
if left[i] <= right[j]:
r.append(left[i])
else:
break
i += 1
while j < n2:
if i == n1:
break
if right[j] <= left[i]:
r.append(right[j])
else:
break
j += 1
r.extend(left[i:])
r.extend(right[j:])
return r
def merge_sort(a):
if len(a) == 1:
return a
mid = len(a) >> 1
left = merge_sort(a[:mid])
right = merge_sort(a[mid:])
return merge(left, right)
if __name__ == "__main__":
a = [23,13,4,67,2,31,43,78,12,33]
b = merge_sort(a)
print(b)
运行结果:
性能分析
时间复杂度—O(nlogn)
因为递归每次按照列表的一半进行分区,并且merge需要线性时间。所以该算法中最好、最坏和平均的时间复杂度都是O(nlogn)。
空间复杂度—O(n)
归并排序的merge函数使用长度为n的数组来存储排序后的结果,因此空间复杂度是O(n)。