归并排序的核心是,每次将两个有序数组组合成为一个新的有序数组。对于俩个有序数组:
def merge(a:List[],b:List[])-->List[]:
l_a,l_b = len(a),len(b)
res = [0 for i in range(l_a+l_b)]
index = 0
i,j = 0,0
while i<l_a or j<l_b:
if a[i]<b[j]:
res[index],index,i = a[i],index+1,i+1
else:
res[index],index,j = b[j],index+1,i+1
while i<l_a:
res[index],index,i = a[i],index+1,i+1
while j<l_b:
res[index],index,j = b[j],index+1,i+1
return res
归并排序中,两个有序数组是一段连续数组的俩部分:
#arr 传入数组,l,mid,r 传入数组的左边界,中间,右边界。l到mid与mid到r均有序,对l到r进行排序
def merge(arr,l,mid,r):
hel = [0 for i in range(r-l+1)]
i = 0
p1,p2 = l,mid+1
while p1<=mid and p2<=r:
if arr[p1]<arr[p2]:
hel[i],i,p1=arr[p1],i+1,p1+1
else:
hel[i],i,p2=arr[p2],i+1,p2+1
while p1<=mid:
hel[i],i,p1 = arr[p1],i+1,p1+1
while p2<=r:
hel[i],i,p2 = arr[p2],i+1,p2+1
arr[l:r+1] = hel[:]
对于归并排序:
#归并排序,arr:排序数组 l:排序数组左边界,r:排序数组右边界。递归最深处的排序数组均为一个数字的数组,可以视为有序数组。
def sortProcess(arr,l,r):
if l==r:
return
mid = (l+r>>1)
sortProcess(arr,l,mid)
sortProcess(arr,mid+1,r)
merge(arr,l,mid,r)
def merge(arr,l,mid,r):
hel = [0 for i in range(r-l+1)]
i = 0
p1,p2 = l,mid+1
while p1<=mid and p2<=r:
if arr[p1]<arr[p2]:
hel[i],p1=arr[p1],p1+1
else:
hel[i],p2=arr[p2],p2+1
i+=1
while p1<=mid:
hel[i],i,p1 = arr[p1],i+1,p1+1
while p2<=r:
hel[i],i,p2 = arr[p2],i+1,p2+1
arr[l:r+1] = hel[:]
附上完整代码+对数器
import random
#size:数组长度
#end:范围
def getRandomArray(size,end,start=1):
res = [random.randint(start,end) for i in range(size)]
return res
def sortProcess(arr,l,r):
if l==r:
return
mid = (l+r>>1)
sortProcess(arr,l,mid)
sortProcess(arr,mid+1,r)
merge(arr,l,mid,r)
def merge(arr,l,mid,r):
hel = [0 for i in range(r-l+1)]
i = 0
p1,p2 = l,mid+1
while p1<=mid and p2<=r:
if arr[p1]<arr[p2]:
hel[i],p1=arr[p1],p1+1
else:
hel[i],p2=arr[p2],p2+1
i+=1
while p1<=mid:
hel[i],i,p1 = arr[p1],i+1,p1+1
while p2<=r:
hel[i],i,p2 = arr[p2],i+1,p2+1
arr[l:r+1] = hel[:]
nums = getRandomArray(20,15)
print(nums)
a = sorted(nums)
sortProcess(nums,0,len(nums)-1)
print(nums)
print(nums==a,'\n')
结果集:
[2, 1, 4, 10, 7, 5, 14, 1, 8, 2, 10, 10, 9, 15, 15, 12, 4, 2, 11, 3]
[1, 1, 2, 2, 2, 3, 4, 4, 5, 7, 8, 9, 10, 10, 10, 11, 12, 14, 15, 15]
True
时间复杂度O(nlogn),空间复杂度O(n)
同时,俩个数组合并的merge函数可以修改为:
def merge(arr,l,mid,r):
hel = [0 for i in range(r-l+1)]
i = 0
p1,p2 = l,mid+1
while p1<=mid and p2<=r:
if arr[p1]<arr[p2]:
hel[i],p1=arr[p1],p1+1
else:
hel[i],p2=arr[p2],p2+1
i+=1
# while p1<=mid:
# hel[i],i,p1 = arr[p1],i+1,p1+1
if p1<=mid:
hel[i:] = arr[p1:mid+1]
i = r-l+1
arr[l:l+i] = hel[:i]
与原函数没有差距。