归并排序
归并排序是采用分治法的一个非常典型的应用。归并排序的思想就是先递归分解数组,再合并数组。
将数组分解最小之后,然后合并两个有序数组,基本思路是比较两个数组的最前面的数,谁小就先取谁,取了后相应的指针就往后移一位。然后再比较,直至一个数组为空,最后把另一个数组的剩余部分复制过来即可。
归并排序的分析
实现
def MergeSort(alist): '''归并排序''' n = len(alist) # 建立递归终止条件 if n <= 1: return alist # 二分分解 mid_index = n // 2 # 递归分解列表 left_li = MergeSort(alist[: mid_index]) right_li = MergeSort(alist[mid_index :]) # 递归分解完成,进行合并排序 left_index, right_index = 0, 0 # 创建一个新列表 result_li = [] # 对分解返回的左右两个列表,进行对比合并 while left_index < len(left_li) and right_index < len(right_li): # 将小的元素依次添加到新的列表中去 if left_li[left_index] <= right_li[right_index]: # 等于,就可以证明递归排序的稳定性 result_li.append(left_li[left_index]) left_index += 1 else: result_li.append(right_li[right_index]) right_index += 1 # 退出循环后,将剩下的元素都添加到新的列表中去 result_li += left_li[left_index :] result_li += right_li[right_index :] # 不能使用append,因为append只能在后面添加元素,不能是列表,但是列表与列表之间可以进行相加 # result_li.append(left_li[left_index:]) # result_li.append(right_li[right_index:]) # 最后返回合并后的新列表 return result_li if __name__ == '__main__': #alist = [6,5,3,1,8,7,2,4] alist = [54, 26, 93, 17, 77, 31, 44, 55, 20] print(alist) result_li = merge_sort = MergeSort(alist) print(alist) print(result_li)
运行结果:
/home/longhui/Desktop/数据结构与算法/venv/bin/python /home/longhui/Desktop/数据结构与算法/venv/MyCode/6_sorting_and_searching/merge_sort.py [54, 26, 93, 17, 77, 31, 44, 55, 20] [54, 26, 93, 17, 77, 31, 44, 55, 20] [17, 20, 26, 31, 44, 54, 55, 77, 93] Process finished with exit code 0
时间复杂度
- 最优时间复杂度:O(nlogn)
- 最坏时间复杂度:O(nlogn)
- 稳定性:稳定
- 需要消耗更多的空间,用空间换取时间