归并排序
归并排序是采用分治法的一个非常典型的应用。归并排序的思想就是先递归分解数组,再合并数组。
将数组分解最小之后,然后合并两个有序数组,基本思路是比较两个数组的最前面的数,谁小就先取谁,取了后相应的指针就往后移一位。然后再比较,直至一个数组为空,最后把另一个数组的剩余部分复制过来即可
归并排序的分析
def merge_sort(alist):
'''归并排序'''
n=len(alist)
if n<=1:
return alist
mid=n//2
#left分解后左边采用归并排序后形成的有序的新的列表
left_list=merge_sort(alist[:mid])
# left分解后右边采用归并排序后形成的有序的新的列表
right_list=merge_sort(alist[mid:])
#将两个有序的子序列合并为一个新的整体
# merge(left,right)
#左右序列游标
left_pointer,right_pointer=0,0
#建一个列表用于存放做判断后的结果值
result=[]
while (left_pointer<len(left_list)) and (right_pointer<len(right_list)):
if left_list[left_pointer]<=right_list[right_pointer]:
result.append(left_list[left_pointer])
left_pointer+=1
else:
result.append(right_list[right_pointer])
right_pointer+=1
result+=left_list[left_pointer:]
result+=right_list[right_pointer:]
return result
alist=[54,226,93,17,77,31,44,55,20]
ml=merge_sort(alist)
print(alist)
print(ml)
#merge_sort 递归分析 alist=[54,226,93,17,77,31,44,55,20]
'''
1.进入递归左
mid=4-->merge_sort(alist[:4])-->a_list=[54,226,93,17]
2.进入递归左
-->mid=2-->merge_sort(alist[:2])-->a_list=[54,226]
3.进入递归左
-->mid=1-->merge_sort(alist[:1])-->n=1-->return left_list=[54]
3.进入递归右
-->mid=1-->merge_sort(alist[1:])-->n=1-->return right_list=[226]
返回排序后的列表
result=[]-->:return left_list=[54,226]
2.进入递归右
-->mid=2-->merge_sort(alist[2:])-->a_list=[93,17]
3.进入递归左
-->mid=1-->merge_sort(alist[:1])-->n=1-->return left_list=[93]
3.进入递归右
-->mid=1-->merge_sort(alist[1:])-->n=1-->return right_list=[17]
result=[]-->:return right_list=[17,93]
result=[]-->:return left_list=[17,54,93,226]
1.进入递归右
mid=4-->merge_sort(alist[4:])-->a_list=[77,31,44,55,20]
2.进入递归左
-->mid=2-->merge_sort(alist[:2])-->a_list=[77,31]
3.进入递归左
-->mid=1-->merge_sort(alist[:1])-->n=1-->return left_list=[31]
3.进入递归右
-->mid=1-->merge_sort(alist[1:])-->n=1-->return right_list=[77]
返回排序后的列表
result=[]-->:return left_list=[31,77]
2.进入递归右
-->mid=2-->merge_sort(alist[2:])-->a_list=[44,55,20]
3.进入递归左
-->mid=1-->merge_sort(alist[:1])-->n=1-->return left_list=[44]
3.进入递归右
-->mid=1-->merge_sort(alist[1:])-->n=2
3.进入递归左
-->mid=1-->merge_sort(alist[:1])-->n=1-->return left_list=[55]
3.进入递归右
-->mid=1-->merge_sort(alist[1:])-->n=1-->return right_list=[20]
result=[]-->:return right_left=[20,55]
result=[]-->:return right_list[20,44,55]
result=[]-->:return right_left=[20,31,44,55,77]
合并排序 result=[17, 20, 31, 44, 54, 55, 77, 93, 226]
'''
时间复杂度
- 最优时间复杂度:O(nlogn)
- 最坏时间复杂度:O(nlogn)
- 稳定性:稳定
常见排序算法效率比较
![](https://i-blog.csdnimg.cn/blog_migrate/39f3dc71c8bbd71548859bdedf8a0f4e.png)
一般面试时,需要掌握几种排序算法,快速排序尽量一定要掌握