归并排序原理
采用分而治之的原理:
一、将一个序列从中间位置分成两个序列;
二、在将这两个子序列按照第一步继续二分下去;
三、直到所有子序列的长度都为1,也就是不可以再二分截止。这时候再两两合并成一个有序序列即可。
一图以明之
两种实现方式:
一、
def merge(a, b):
c = []
h = j = 0
while j < len(a) and h < len(b):
if a[j] < b[h]:
c.append(a[j])
j += 1
else:
c.append(b[h])
h += 1
if j == len(a):
for i in b[h:]:
c.append(i)
else:
for i in a[j:]:
c.append(i)
return c
def merge_sort(lists):
if len(lists) <= 1:
return lists
middle = len(lists)//2
left = merge_sort(lists[:middle])
right = merge_sort(lists[middle:])
return merge(left, right)
if __name__ == '__main__':
a = [14, 2, 34, 43, 21, 19]
print (merge_sort(a))
二、
def mergeSort(alist):
print("Splitting ", alist)
if len(alist) > 1:
mid = len(alist) // 2
lefthalf = alist[:mid]
righthalf = alist[mid:]
mergeSort(lefthalf)
mergeSort(righthalf)
i = 0
j = 0
k = 0
print('alist',alist)
while i < len(lefthalf) and j < len(righthalf):
print('one',len(lefthalf),len(righthalf))
if lefthalf[i] < righthalf[j]:
alist[k] = lefthalf[i]
i = i + 1
print('one', alist)
else:
alist[k] = righthalf[j]
j = j + 1
print('one1', alist)
k = k + 1
while i < len(lefthalf):
print('two', len(lefthalf), len(righthalf))
alist[k] = lefthalf[i]
i = i + 1
k = k + 1
print('two', alist)
while j < len(righthalf):
print('three', len(lefthalf), len(righthalf))
alist[k] = righthalf[j]
j = j + 1
k = k + 1
print('three', alist)
print("Merging ", alist)
alist = [54,26,93,17,77,31,44,55,20]
mergeSort(alist)
print(alist)
首先,列表被分成两半。我们已经计算过(在二分查找中)将列表划分为一半需要 log^n 次,其中 n 是列表的长度。第二个过程是合并。列表中的每个项将最终被处理并放置在排序的列表上。因此,大小为 n 的列表的合并操作需要 n 个操作。此分析的结果是 logn 的拆分,其中每个操作花费n,总共 nlogn 。归并排序是一种 O(nlogn) 算法。