一、归并过程
归并过程实现:
首先把数组分成两段,使用low表示列表中第一个元素下标,使用high表示列表中最后一个元素的下标,使用mid表示中间元素的下标。用 i 最开始指向low位置,j 指向 mid+1 位置,将li[i]与li[j]作比较,将小的数存入新的列表中,并将指向这个数的指针往后面移动一位,再进行比较,依次进行,在一趟比较过后肯定有一部分有剩余的数,将剩余的数也存入新的列表中。
二、使用归并
1、分解:将列表越分越小,直至分成一个元素
2、终止条件:一个元素时肯定是有序的
3、合并:将两个有序的列表进行归并,列表越来越大,直至合并成一个列表。
过程图解:
三、代码实现
使用递归,递归终止条件为元素分解至一个,同时对mid两边的元素进行递归。
def merge(li, low, mid, high): # 归并过程
# :param li: 列表
# :param low: 列表第一个元素
# :param mid: 列表中间元素
# :param high: 列表最后一个元素
i = low
j = mid + 1
ltmp = []
while i <= mid and j <=high: # 只要mid左右两边都有数,开始循环
if li[i] < li[j]:
ltmp.append(li[i])
i += 1
else:
ltmp.append(li[j])
j += 1
# while执行完,肯定mid一侧没数
while i <= mid: # 如果左边有数
ltmp.append(li[i])
i += 1
while j <= high: # 如果右边有数
ltmp.append(li[j])
j += 1
li[low:high+1] = ltmp # 把ltmp中的值写回到li
# li = [2, 4, 6, 4, 1, 9, 5, 7]
# merge(li, 0, 3, 7)
# print(li)
# 归并排序--使用归并
# 分解:将列表越分越小,直至分成一个元素
# 终止条件:一个元素是有序的
# 合并:将两个有序列表归并,列表越来越大
# 代码实现
def merge_sort(li, low ,high):
if low < high: # 至少有两个元素,递归
mid = (low + high) // 2
merge_sort(li, low, mid)
merge_sort(li, mid+1, high)
merge(li, low, mid, high)
# 归并排序时间复杂度 O(nlogn)
# 空间复杂度 O(n)
li = list(range(100))
import random
random.shuffle(li)
print(li)
merge_sort(li, 0, len(li)-1)
print(li)
归并排序时间复杂度:O(nlogn)
空间复杂度O(n)