python列表快速排序_Python实现快速排序

快速排序

快速排序使用分而治之来获得与归并排序相同的优点,而不使用额外的存储。

算法步骤:

首先选择一个值,该值称为 枢轴值 。使用列表中的第一项作为枢轴值。枢轴值的作用是帮助拆分列表。枢轴值属于最终排序列表(通常称为拆分点) 的实际位置,将用于将列表划分为快速排序的后续调用。如果列表的长度小于或等于一,它已经排序。 如果它更大,那么它可以被分区和递归排序。

分区从通过在列表中剩余项目的开始和结束处定位两个位置标记(我们称为左标记和右标记) 开始。分区的目标是移动相对于枢轴值位于错误侧的项,同时也收敛于分裂点。

首先增加左标记(左标记右移),直到左标记指向的值大于枢轴值。 然后递减右标(右标记左移),直到右标记指的值小于枢轴值。这两个值就是相对于最终分裂点位置(指的就是枢轴值)不适当的项。 交换这两个项,然后重复该过程。

在右标变得小于左标记的点时停止。右标记的位置现在是分割点。枢轴值可以与拆分点的内容交换,枢轴值现在就位。 此外,分割点左侧的所有项都小于枢轴值,分割点右侧的所有项都大于枢轴值。

在分割点处划分列表,并且可以在两半上递归调用快速排序。

完整代码:

def quickSort(alist):

"""

快排的主要函数

:param alist: 要排序的列表

:return:

"""

quickSortHepler(alist, 0, len(alist) - 1)

def quickSortHepler(alist, first, last):

"""

快排使用的递归函数

:param alist: 要排序的列表

:param first: 首位作为左标记

:param last: 末位作为右标记

:return:

"""

if first < last:

# 对列表分区

splitpoint = partition(alist, first, last)

# 递归调用,对两个半块上进行快排

quickSortHepler(alist, first, splitpoint - 1)

quickSortHepler(alist, splitpoint + 1, last)

def partition(alist, first, last):

"""

分区函数

:param alist: 要排序的列表

:param first: 首位

:param last: 末位

:return:

"""

# 首位作为枢轴值

pivotvalue = alist[first]

# 确定左标记和右标记

leftmark = first + 1

rightmark = last

done = False

while not done:

# 增加左标记(左标记右移),直到左标记指向的值大于枢轴值

while leftmark <= rightmark and alist[leftmark] <= pivotvalue:

leftmark = leftmark + 1

# 递减右标(右标记左移),直到右标记指的值小于枢轴值

while alist[rightmark] >= pivotvalue and rightmark >= leftmark:

rightmark = rightmark - 1

# 右标变得小于左标记的点时,停止循环

if rightmark < leftmark:

done = True

else:

# 交换左标记与右标记指向的值

temp = alist[leftmark]

alist[leftmark] = alist[rightmark]

alist[rightmark] = temp

# 交换枢轴值和分割点(右标记)的值

temp = alist[first]

alist[first] = alist[rightmark]

alist[rightmark] = temp

return rightmark

进阶

通过使用称为中值三的技术来减轻一些不均匀分割的可能性。要选择枢轴值,我们将考虑列表中的第一个,中间和最后一个元素。想法是,在列表中的第一项不属于列表的中间的情况下,中值三将选择更好的“中间”值。当原始列表部分有序时,这将特别有用。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值