python归并排序
1. 思路:
1. 拆分:将列表划分成多个不可再分的子序列,拆分到子序列中仅有 1 个元素;
2. 合并: 拆分完成后,开始合并,合并得到有序序列。
1. 拆分:从列表的中间位置开始拆分 mid = (low + high) // 2
2. li: 列表
low:列表第一个元素下标
mid:第一个子序列的最后位置
high:第二个子序列(也是列表的最后一个位置)
low,mid,high限定两个序列的范围。
2.代码
1. 一次归并代码的实现
一次归并要想将列表排好序:需要两个子序列分别有序。
def merge(li, low, mid, high):
i = low
j = mid + 1
ltmp = [] # 临时列表,merge_sort(li, 0, len(li) - 1)
while i <= mid and j <= high: # i小于等于mid,j小于等于high,。i和j要分别在各自的范围内
if li[i] < li[j]: # 如果i小于j,将i添加到列表,否则将j添加到列表
ltmp.append(li[i])
i += 1
else:
ltmp.append(li[j])
j += 1
# while执行完,两部分如果有一部分没数了,则将另外一部分的数直接添加到ltmp列表里
while i <= mid:
ltmp.append(li[i])
i += 1
while j <= high:
ltmp.append(li[j])
j += 1
li[low:high + 1] = ltmp # 把临时列表的数据重新拿过来
li = [1, 3, 6, 9, 2, 4, 8, 10]
merge(li, 0, 3, 7)
print(li)
2. 利用递归实现归并排序
递归的终止条件:拆分的只剩下一个。
def merge(li, low, mid, high):
i = low
j = mid + 1
ltmp = []
while i <= mid and j <= high:
if li[i] < li[j]:
ltmp.append(li[i])
i += 1
else:
ltmp.append(li[j])
j += 1
while i <= mid:
ltmp.append(li[i])
i += 1
while j <= high:
ltmp.append(li[j])
j += 1
li[low:high + 1] = ltmp
def merge_sort(li, low, high):
if low < high: # 至少有两个元素
mid = (low + high) // 2
merge_sort(li, low, mid) # 左边
# print('左:', li[low:mid + 1])
merge_sort(li, mid + 1, high) #右边
# print('右:', li[mid+1:high + 1])
merge(li, low, mid, high) # 合并
print('合并:', li[low:high + 1])
li = [13, 15, 17, 11, 10, 14, 19, 12]
print(li)
merge_sort(li, 0, len(li) - 1)
print(li)
时间复杂度:O(nlog2n)。每层是n,有logn层,所以时间复杂度是O(nlog2n)
空间复杂度:O(n)。需要一个临时变量来存储。