一、归并排序思想
将数组分解成两个较小的数组,直到子数组的大小为一
递归对子数组进行排序合并,直到合并成完整的数组
二、归并排序图示
三、分解方式和合并方式
分解
将数组等分
合并
如上图,如此循环下去就能将两个小数组排好序,合并成大数组
归并排序代码及解释
merge_sort函数完成分解递归工作
merge函数完成排序合并工作
链接: [代码具体运行——小蜘蛛](链接: link)
代码
def merge_sort(arr):
#如果数组中只有一个元素,返回这个列表
if len(arr)<=1:
return arr
#分解:将数组分成左右两部分
mid=len(arr)//2
left_half=arr[:mid]
right_half=arr[mid:]
#递归拆解左右两个序列
left_half=merge_sort(arr[:mid])
right_half=merge_sort(arr[mid:])
#将拆解好的两个最小子序列排序合并(第一次调用该函数时数组中只有一个元素)
return merge(left_half,right_half)
def merge (left,right):
merged=[]
left_point=0
right_point=0
#左右比较,较小的放在新列表中
while left_point<len(left) and right_point<len(right):
if left[left_point]<right[right_point]:
merged.append(left[left_point])
left_point+=1
else:
merged.append(right[right_point])
right_point+=1
#如果左右数组中还有别的元素,直接将其他所有元素补充到新数组即可
merged.extend(left[left_point:])
merged.extend(right[right_point:])
#这一步 将排好序的较大数组再一次返回到 merge_sort函数的递归语句中
#比如返回[14,20] , 递归语句会把[30]、[35]传给 merge 函数,进行排序、合并
return merged
arr1=[20,14,30,35,7,22,18,40]
print(merge_sort(arr1))
时间复杂度、空间复杂度、最坏情况、最好情况
时间复杂度:T=O(nlogn)
时间函数:T(n)=2T(n/2)+cn
空间复杂度((用数组存储数据):S=O(n)
由于归并排序需要申请额外的空间,即创建一个新数组来存放排好序的数组,因此空间复杂度就是该数组的大小n
用链表存储数据空间复杂度为:S=O(1)
最坏情况和最好情况均相同、因为数据都是被一分为二的、不存在像快速排序分割方式不当的情况