排序思路
- 取一个元素P(第一个元素),目标是使得元素P归位;
- 列表被元素P分成了两个部分,左边的比P小,右边的比P大;
- 分别再对左右两个部分的列表重复1,2步骤,递归完成排序
评价:
时间复杂度
最坏情况:
O
(
n
2
)
O(n^2)
O(n2) # 输入的序列刚好是逆序的情况(每次归为后只产生一条序列)
平均情况:
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
)
O(n)
O(n)
稳定性:不稳定。排序过程中不是相邻两位交换。
快速排序示意图:
定义归位函数
# 定义归位函数,每次将首元素归位并返回对应的序号
def partition(lst, left, right):
"""思路:
定义left、right指针,首先将left指针的值传给temp,至此left指针”空缺“。
while(左右指针没有相遇):
(1)从right指针开始移动寻找比temp小的值,放到left所指的”空缺“。完成后right”空缺“
(2)从left指针开始移动寻找比temp大的值,放到right所指的”空缺“。完成后left”空缺“
"""
# 将首元素用临时变量存放
temp = lst[left]
# 用双指针移动归位,left指针向右移动,right指针向左移动,相等后结束。
while left < right:
# 操作right指针向左走
while left < right and lst[right] >= temp:
right -= 1 # 向左走
lst[left] = lst[right] # 寻找比temp小的值,放到left所指的”空缺“
# 操作left指针向右走
while left < right and lst[left] <= temp:
left += 1
lst[right] = lst[left]
# left=right,循环结束temp归位
lst[left] = temp
return left
定义递归函数
递归函数思路:
- 结束条件:列表只有一个元素(递归条件就是左右指针不相等)
- 循环部分:归位传入的序列,并将左右两个部分也归位。
def quick_sort(lst, left, right):
# 只有lst有两个及以上元素
if left < right:
# 归位后返回归为元素的序号
mid = partition(lst, left, right)
quick_sort(lst, left, mid - 1)
quick_sort(lst, mid + 1, right)
lst = [1, 9, 7, 4, 5]
quick_sort(lst, 0, len(lst) - 1)
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 partition(lst, left, right):
"""思路:
定义left、right指针,首先将left指针的值传给temp,至此left指针”空缺“。
while(左右指针没有相遇):
(1)从right指针开始移动寻找比temp小的值,放到left所指的”空缺“。完成后right”空缺“
(2)从left指针开始移动寻找比temp大的值,放到right所指的”空缺“。完成后left”空缺“
"""
# 将首元素用临时变量存放
temp = lst[left]
# 用双指针移动归位,left指针向右移动,right指针向左移动,相等后结束。
while left < right:
# 操作right指针向左走
while left < right and lst[right] >= temp:
right -= 1 # 向左走
lst[left] = lst[right] # 寻找比temp小的值,放到left所指的”空缺“
# 操作left指针向右走
while left < right and lst[left] <= temp:
left += 1
lst[right] = lst[left]
# left=right,循环结束temp归位
lst[left] = temp
return left
def _quick_sort(lst, left, right):
# 只有lst有两个以上元素
if left < right:
# 归位后返回归为元素的序号
mid = partition(lst, left, right)
_quick_sort(lst, left, mid - 1)
_quick_sort(lst, mid + 1, right)
@calculate_time
def quick_sort(lst):
_quick_sort(lst, 0, len(lst) - 1)
if __name__ == '__main__':
# 测试代码
lst = list(range(10000))
random.shuffle(lst)
print(lst)
quick_sort(lst)
print(lst)