快速排序:块
快排思路:
取一个元素p(第一个元素),使元素p归位;
列表被p分成两部分,左边都比p小,右边都比p大;
递归完成排序.
示例演示:
排序前:5 7 4 6 3 1 2 9 8
P 归位:2 1 4 3 5 6 7 9 8
目 标:1 2 3 4 5 6 7 8 9
快排代码:
import random import time def cal_time(func): def wrapper(*args, **kwargs): t1 = time.time() result = func(*args, **kwargs) t2 = time.time() print('%s running time: %s secs.' % (func.__name__, t2 - t1)) return result return wrapper def partition(lst, start, end):
# 快排最坏情况的一种优化
i = random.randint(start, end)
li[start], li[i] = li[i], li[start]# 默认数组第一个数为基数,拿出来保存到tmp变量中 tmp = lst[start] # start < end代表数组元素大于等于2 while start < end: # 从右边找比tmp小的数,找到之后放到左边空缺位置,再从左边开始. while start < end and lst[end] >= tmp: end -= 1 # 比较过程中,如果左边和右边数字相等,那么这个位置就是tmp位置,也就是所谓的元素归位. lst[start] = lst[end] # 从左边找比tmp大的数,找到之后放到右边空缺位置,再从右边开始. while start < end and lst[start] <= tmp: start += 1 # 比较过程中,如果左边和右边数字相等,那么这个位置就是tmp位置,也就是所谓的元素归位. lst[end] = lst[start] # 写start或者end都可以,因为你此时重合了 lst[start] = tmp return start def _quick_sort(lst, start, end): # left<right至少有两个元素 # left=right有一个元素 if start < end: mid = partition(lst, start, end) _quick_sort(lst, start, mid - 1) _quick_sort(lst, mid + 1, end) # 由于快排本身有递归,所以测试时间会打印好多次, # 解决办法:通过加壳方式解决 @cal_time def quick_sort(li): return _quick_sort(li, 0, len(li) - 1) # 生成10万数据列表 li = list(range(100000)) # 用random模块打乱顺序 random.shuffle(li) # 快排 quick_sort(li) # 查看排序后的列表 # print(li)