排序思路
- 将输入的列表递归分解成若干个有序的子列表(只含有一个元素);
- 将分解后的有序子列表两两归并成一个新的有序列表;
- 重复步骤2,直到完成排序。
重点:如何定义一个归并函数,可以将两个有序的序列,归并成一个有序的新序列。
评价:
时间复杂度
最坏情况:
O
(
n
l
o
g
n
)
O(n logn)
O(nlogn)
平均情况:
O
(
n
l
o
g
n
)
O(n logn)
O(nlogn)
最好情况:
O
(
n
l
o
g
n
)
O(n logn)
O(nlogn)
空间复杂度
所有情况:
O
(
n
l
o
g
n
)
O(n logn)
O(nlogn)
稳定性:稳定。排序过程中没有不相邻的两位交换。
快速排序示意图:
定义合并函数
合并前:
合并后:
# 定义合并函数,将两个有序序列合并为一个有序序列
def merge(lst, left, mid, right):
"""
思路:定义一个列表merged,循环比较两个有序序列的首元素大小,并放入临时空列表。
"""
if left < right:
merged = []
i = left
j = mid + 1
while i <= mid and j <= right:
if lst[i] < lst[j]:
merged.append(lst[i])
i += 1
else:
merged.append(lst[j])
j += 1
# 代码执行至此,有一个序列元素为空,另一个不为空,接下来将剩下的元素放入空列表
while i <= mid:
merged.append(lst[i])
i += 1
while j <= right:
merged.append(lst[j])
j += 1
lst[left:right + 1] = merged
return lst
定义递归函数
递归函数思路:
- 结束条件:列表只有一个元素,因为一个元素必为有序序列(递归条件就是左右指针不相等)
- 循环部分:将序列分解为左右两个子序列直到为只含一个元素(有序),再将序列合并。
def merge_sort(lst, left, right):
if left < right:
mid = (left + right) // 2
merge_sort(lst, left, mid)
merge_sort(lst, mid + 1, right)
merge(lst, left, mid, right)
lst = [2, 9, 6, 4, 1, 3, 5, 7]
merge_sort(lst, 0, 7)
print(lst)
完整代码
import time
import random
def calculate_time(func):
def wrapper(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs)
end_time = time.time()
execution_time = end_time - start_time
print(f"函数 {func.__name__} 的执行时间为:{execution_time} 秒")
return result
return wrapper
# 定义合并函数,将两个有序序列合并为一个有序序列
def merge(lst, left, mid, right):
"""
思路:定义一个列表merged,循环比较两个有序序列的首元素大小,并放入临时空列表。
"""
if left < right:
merged = []
i = left
j = mid + 1
while i <= mid and j <= right:
if lst[i] < lst[j]:
merged.append(lst[i])
i += 1
else:
merged.append(lst[j])
j += 1
# 代码执行至此,有一个序列元素为空,另一个不为空,接下来将剩下的元素放入空列表
while i <= mid:
merged.append(lst[i])
i += 1
while j <= right:
merged.append(lst[j])
j += 1
lst[left:right + 1] = merged
return lst
def _merge_sort(lst, left, right):
if left < right:
mid = (left + right) // 2
_merge_sort(lst, left, mid)
_merge_sort(lst, mid + 1, right)
merge(lst, left, mid, right)
@calculate_time
def merge_sort(lst):
_merge_sort(lst, 0, len(lst) - 1)
if __name__ == '__main__':
# 测试代码
lst = list(range(10000))
random.shuffle(lst)
print(lst)
merge_sort(lst)
print(lst)