1.原理
采用分治法(Divide and Conquer)的一个非常典型的应用。
典型的分而治之思想的算法应用,归并排序的实现由两种方法:
- 自上而下的递归(所有递归的方法都可以用迭代重写,所以就有了第 2 种方法);
- 自下而上的迭代;
2.算法步骤
-
申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列;
-
设定两个指针,最初位置分别为两个已经排序序列的起始位置;
-
比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置;
-
重复步骤 3 直到某一指针达到序列尾;
-
将另一序列剩下的所有元素直接复制到合并序列尾。
import math
def mergeSort(arr):
if len(arr) < 2:
return arr
mid = math.floor(len(arr) / 2) # 分割
left, right = arr[0:mid], arr[mid:] # 得到左边和右边
return merge(mergeSort(left), mergeSort(right)) # 递归分割和排序
def merge(left, right):
result = []
while left and right:
if left[0] <= right[0]: # 左边小于右边,左边添加到result,同时移除
result.append(left.pop(0))
else: # 左边大于右边,右边添加到result,同时移除
result.append(right.pop(0))
while left:
result.append(left.pop(0)) # 剩下的自动添加到result
while right:
result.append(right.pop(0))
return result
if __name__ == '__main__':
arr = [1, 4, 6, 2, 3, 8, 5, 9, 0, 7]
print(mergeSort(arr))
或者
def merge_sort(items, comp=lambda x, y: x <= y):
"""归并排序(分治法)"""
if len(items) < 2:
return items[:]
mid = len(items) // 2
left = merge_sort(items[:mid], comp)
right = merge_sort(items[mid:], comp)
return merge(left, right, comp)
def merge(items1, items2, comp):
"""合并(将两个有序的列表合并成一个有序的列表)"""
items = []
index1, index2 = 0, 0
while index1 < len(items1) and index2 < len(items2):
if comp(items1[index1], items2[index2]):
items.append(items1[index1])
index1 += 1
else:
items.append(items2[index2])
index2 += 1
items += items1[index1:]
items += items2[index2:]
return items