归并排序
假设现在的列表分成两段有序的列表,如何将其合并成一个有序列表。
这种操作称为一次归并。
一次归并代码:
def merge(nums, left, mid, right): """ 一次归并(把列表) :param nums: :param left: 第一个元素位置 :param mid: 中间元素位置 :param right: 边界元素位置 :return: """ i = left j = mid + 1 temp = [] # 只要左右两边都还有数,就不断循环 while i <= mid and j <= right: if nums[i] < nums[j]: temp.append(nums[i]) i += 1 else: temp.append(nums[j]) j += 1 # 循环完毕有一边还有数 while i <= mid: temp.append(nums[i]) i += 1 while j <= right: temp.append(nums[j]) j += 1 # 替换原数组指定了要归并的区域 nums[left: right + 1] = temp
归并排序----使用归并
- 分解:将列表越分越小,直至分成一个元素
- 终止条件:一个元素是有序的
- 合并:将两个有序列表合并,列表越来越大。
归并排序代码实现
def merge_sort(nums, left, right): if left < right: mid = (left + right) >> 1 # 关于mid,和mid+1 主要是考虑数组个数为偶数 # 例如 [1,2,3,4,5,6] mid = (0 + 5) // 2 = 2 # 若左边分治的时候出传递的是 (nums, left, mid - 1)的话,那么只拿到两个元素去求解 merge_sort(nums, left, mid) merge_sort(nums, mid + 1, right) merge(nums, left, mid, right)
NB三人组(快速排序,堆排序,归并排序)小结:
- 三种排序算法的时间复杂度都是O(nlogn)
- 一般情况下,就运行时间而言:
- 快速排序>归并排序>堆排序
- 三种排序算法的缺点:
- 快速排序:极端的情况下排序效率低
- 归并排序:需要额外的内存开销
- 堆排序:在快的排序算法中相对较慢
6种常见排序算法小结:(冒泡排序,选择排序,插入排序,快速排序,堆排序,归并排序)