基本思想
归并排序是分治思想的一种运用【和快速排序的思想一样】,首先将一个序列分成一个个子序列,然后对子序列进行排序,最后将排好序的子序列进行合并;----所以需要写递归函数。
将其不停的分为左边和右边两份,然后以此递归分下去。然后再将她们按照两个有序数组的样子合并起来。所以当将这左右两边分到不可分【也就是数组长度为1】,也就到了该合并的时候。
这里显示了归并排序的第一步,将数组按照middle进行递归拆分,最后分到最细之后[len(A) <= 1]再将其使用对两个有序数组进行排序的方法对其进行排序。【当子数组中只有一个元素时,开始归并】
时间复杂度分析
当分成里面只有一个元素时,其时间复杂度就是1。
由于递归拆分的时间复杂度是logN 然而,进行两个有序数组排序的方法复杂度是N。该算法的时间复杂度是N*logN 所以是NlogN。
非递归实现过程:
直接上代码:
class MergeSort():
def merge_sort(self, array):
"""
归并排序
:param array:
:return:
"""
# 递归退出条件, 开始归并的调节
n = len(array)
if n < 2:
return array
# 进行拆分
mid = n // 2
left_array = array[: mid]
right_array = array[mid: ]
# 对子数列进行拆分
self.merge_sort(left_array)
self.merge_sort(right_array)
# 拆分完成后,进行合并
return self.merge2(left_array, right_array)
def merge1(self, s1, s2, s):
"""
将两个有序列表s1,s2按照顺序合并成一个列表s, s为原始列表
:param s1: 有序列表s1
:param s2: 有序列表s2
:param s: 原始列表
:return:
这个骚操作第一次见
"""
# 首先定义两个指针,分别指向s1 和 s2的第一个位置
i = j = 0
while i+j < len(s):
if j == len(s2) or (i<len(s1) and s1[i]<s2[j]):
s[i+j] = s1[i]
i += 1
else:
s[i+j] = s2[j]
j += 1
return s
def merge2(self, s1, s2):
s = []
i = j = 0
while i < len(s1) and j < len(s2):
if s1[i] < s2[j]:
s.append(s1[i])
i += 1
else:
s.append(s2[j])
j += 1
if i == len(s1):
s.extend(s2[j: ])
elif j == len(s2):
s.extend(s1[i: ])
return s
def solution2(self, array):
"""
非递归实现过程
:param array:
:return:
"""
gap = 1
while gap < len(array):
tmp = []
i = 0
while i < len(array):
tmp.extend(self.merge2(array[i:i + gap], array[i + gap: i + 2 * gap]))
i += 2 * gap
array = tmp
gap *= 2
return array
if __name__ == '__main__':
test_array = [1, 7, 3, 5, 4]
print('测试数组', test_array)
ms = MergeSort()
print(ms.merge_sort(test_array))