一次归并
'''
#一次归并操作如下:
假设有一个列表,从某个位置切开,得到的两段都是有序的,则可以进行如下的排序:
例:
li=[2,3,4,0,1]
从index=2开始,[2,3,4]和[0,1]都是有序的
现设指针:low mid high
low:指向0,左边列表的起始位置
mid:指向2,左边列表的结束位置(mid+1就是右边列表的起始位置,所以不需要额外设置)
high:指向4,右边列表的结束位置
临时列表li_tmp=[]
从low和mid+1开始,依次比较左边和右边列表的值:
i=low,j=mid+1
第一次比较得:li[j]<li[i],添加li[j]到li_tmp,然后j+=1,得到li_tmp=[0]
第二次比较得:li[j]<li[i],添加li[j]到li_tmp,然后j+=1,得到li_tmp=[0,1]
此时,j=high,右边有序的列表已经排完,直接将左边剩下的所有元素添加到li_tmp即可
即:
li_tmp=[0,1,2] #添加2
li_tmp=[0,1,2,3] #添加3
li_tmp=[0,1,2,3,4] #添加4
最后,将拍好序的li_tmp赋值给li的相应位置
li[low:high+1]=li_tmp
'''
归并排序
# 一次归并
def merge(li, low, mid, high):
i, j = low, mid + 1
li_tmp = []
while i <= mid and j <= high:
if li[i] < li[j]:
li_tmp.append(li[i])
i += 1
else:
li_tmp.append(li[j])
j += 1
# 如果左边的列表有剩余就将剩下的添加到li_tmp
while i <= mid:
li_tmp.append(li[i])
i += 1
# 如果右边的列表有剩余的就将右边的添加到li_tmp
while j <= high:
li_tmp.append(li[j])
j += 1
# 将排好序的li_tmp赋值给li的相应部分
li[low:high + 1] = li_tmp
def merge_sort_(li, low, high):
# 首先将整个列表分成无数个小段
if low < high: # low<high说明至少有2个元素
mid = (low + high) // 2
# merge左边的
merge_sort_(li, low, mid)
# merge右边的
merge_sort_(li, mid + 1, high)
# merge左边和右边的
merge(li, low, mid, high)
@clocked
def merge_sort(li):
merge_sort_(li, 0, len(li) - 1)