14-快速排序
# 快速排序的思路是依据一个“中值”数据项来把数据表分为两半 :小于中值的一半和大于中值的一半,
# 然后每部分分别进行快速排序(递归)
# 如果希望这两半拥有相等数量的数据项,则应该找到数据表的中位数
# 但找中位数需要计算开销!要想没有开销,只能随意找一个数来充当中值比如,第1个数。
# 设置左右标(left/rightmark)
# 左标向右移动,右标向左移动
# 左标一直向右移动,碰到比中值大的就停止
# 右标一直向左移动,碰到比中值小的就停止
# 然后把左右标所指的数据项交换
# 继续移动,直到左标移到右标的右侧,停止移动
# 这时右标所指位置就是“中值”应处的位置
# 将中值和这个位置交换
# 分裂完成,左半部比中值小,右半部比中值大
# 快速排序过程分为两部分:分裂和移动
# 快速排序过程分为两部分:分裂和移动
# 如果分裂总能把数据表分为相等的两部分,那么就是O(log n)的复杂度;
# 而移动需要将每项都与中值进行比对,还是O(n)
# 综合起来就是O(nlogn)
def quickSort(alist):
quickSortHelper(alist, 0, len(alist)-1) # 由于需要用到传入列表的长度,因此引入一个Helper
def quickSortHelper(alist, first, last):
if first < last: # 基本结束条件
splitpoint = partition(alist, first, last) # 分裂
quickSortHelper(alist, first, splitpoint-1) #递归调用
quickSortHelper(alist, splitpoint+1, last)
def partition(alist, first, last):
pivotvalue = alist[first] # 选定中值
leftmark = first + 1 # 左右标初值
rightmark = last
done = False
while not done:
while leftmark <= rightmark and alist[leftmark] <= pivotvalue:
leftmark += 1 # 向右移动坐标
while rightmark >= leftmark and alist[rightmark] >= pivotvalue:
rightmark -= 1 # 向左移动右表
if rightmark < leftmark:
done = True # 两标相错,移动结束
else:
alist[leftmark], alist[rightmark] = alist[rightmark], alist[leftmark] # 左右标值交换
alist[first], alist[rightmark] = alist[rightmark], alist[first] # 中值就位
return rightmark # 返回分裂点索引作为划分依据
testlist = [2, 3, 3, 243, 24, 24455, 23]
quickSort(testlist)
print(testlist)
作者:lotuslaw
出处:https://www.cnblogs.com/lotuslaw/p/13968825.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
分类:
数据结构与算法
标签:
数据结构与算法学习笔记
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧