解释的算法:快速排序

解释的算法:快速排序

今天,我们来看一个非常重要的排序算法: quicksort 。 Quicksort是一种采用分而治之策略的递归排序算法。

我不会在这里解释递归的工作原理,因为我已经在这里写了一篇有关递归的文章。

由于这是一种分而治之的算法,我们希望获取未排序整数的列表,然后将问题分解为两个更简单的问题,然后将每个问题分解……。 等等。

为此,我将首先介绍quicksorts的核心操作:分区。 其工作方式如下:

>>> A = [6, 3, 17, 11, 4, 44, 76, 23, 12, 30]
>>> partition(A, 0, len(A)-1)
>>> print(A)
[6, 3, 17, 11, 4, 23, 12, 30, 76, 44]

那么,这里发生了什么以及它如何工作? 我们需要选择一些数字作为我们的枢纽 。 我们的分区函数接受3个参数, 列表列表中的第一个元素数据透视表 。 我们要在此处实现的目标是,在对列表进行分区时,枢轴左侧的所有内容都小于枢轴 ,而右侧列表中的所有内容都大于枢轴 。 对于上面看到的第一个分区, 30是我们的枢轴 。 分区后,我们看到一些元素的位置发生了变化,但是30左边的所有内容都小于它,而右边的所有内容都大于它。

那对我们意味着什么? 好,这意味着30现在在列表中的正确位置我们现在有两个更容易名单排序。 所有这些都是就地完成的因此我们不会创建新列表。

让我们看一下代码:

def partition(A, p, r):
   q = j = p
   while j < r:
if A[j] <= A[r]:
A[q], A[j] = A[j], A[q]
q += 1
     j += 1
   A[q], A[r] = A[r], A[q]
   return q

最后的返回q对于我们的分区不是必需的,但是对整个列表进行排序是必不可少的。 上面的代码遍历列表A,并维护索引p,q,j,r

p是固定的,是列表中的第一个元素。 r枢轴,并且是列表中的最后一个元素。 已知A [p:q-1]范围内元素小于或等于轴,并且A [q-1:r-1]中的所有值都大于轴。 唯一变化的索引是qj 。 在每一步,我们将A [j]A [r]进行比较 。 如果它大于枢轴,则它处于正确的位置,因此我们增加j并移至下一个元素。 如果A [j]小于A [r],我们将A [q]A [j]交换 交换之后,我们增加q ,从而扩展了已知小于或等于枢轴的元素范围。 我们还将j递增以移至下一个要处理的元素。

现在进入快速排序部分。 请记住,这是一种递归算法,因此它将连续调用partition(),直到没有剩余的分区为止。

让我们看一下代码:

def quicksort(A, p, r):
   if r <= p:
return
   q = partition(A, p, r)
quicksort(A, p, q-1)
quicksort(A, q+1, r)
   return A

就这么简单。 我们在这里所做的只是检查数据透视表的索引是否小于或等于我们要分区的列表开头的索引。 如果是,则返回,因为传递的任何列表都不需要进一步分区。

否则,我们对列表A进行分区,然后在两个新的子列表上再次调用quicksort

Quicksort在完全混乱的大型列表上效果最佳。 在几乎排序的列表上,它的性能确实很差。 或以Big-O表示法,最好的情况(加扰)为O(n log(n)),最坏的情况下(几乎或完全有序列表)为O(n ^ 2)。

我们的新书“将Slither转换成Python”中对此主题有更详细的介绍,您现在只需5.99欧元即可预订—我们为初学者编写的Python编程语言入门,旨在使您从一个完整的初学者到熟练的人。和熟练的程序员,仅22章,涵盖了整个主题。 在这里查看。

Slither into Python可以预购66%的折扣。

From: https://hackernoon.com/algorithms-explained-quicksort-324305b8757b

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值