归并排序
归并排序是采用分治法的一个非常典型的应用。归并排序的思想就是先递归分解数组,再合并数组。
将数组分解最小之后,然后合并两个有序数组,基本思路是比较两个数组的最前面的数,谁小就先取谁,取了后相应的指针就往后移一位。然后再比较,直至一个数组为空,最后把另一个数组的剩余部分复制过来即可
归并排序的分析
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)
- 稳定性:稳定
常见排序算法效率比较
一般面试时,需要掌握几种排序算法,快速排序尽量一定要掌握