点击蓝字“莫名Coder”关注我哟
加个“星标★”,每日良时,好文必达!
快速排序
快速排序是一种常用的排序算法,比选择排序要快得多。
下面来使用快排对数组进行排序。对于排序算法来说,最简单的数组就是不需要排序的数组。因此基线条件为数组我诶空或只包含一个元素,在这种情况下,只需要原样返回数组----根本不需要排序。
def array_sort(list):
if len(list) < 2:
rerurn list
对包含两个元素的数组进行排序很容易,检查第一个元素是否比第二个小,如果不是,则交换位置即可。那三个以上呢?
快速排序工作原理:首先,从数组中选择一个元素,这个元素被称为基准值;稍后我们暂时将数组的第一个元素作为基准值;接下来找出比基准值小的元素以及比基准值大的元素。
例1:现有一个所有小于基准值的数字组成的子数组,基准值,一个由所有大于基准值的数字的子数组
案例1中,我们对数组进行了分区,得到的两个子数组都是无序的,但是如果这两个数组是有序进行排序非常容易。
如果子数组是有序的,左边的数组+基准值+右边的数组,结果就是一个有序数组。
但是数组无序如何操作?
选择基准值
将数组分为两个子数组,小于基准值组成的子数组和大于基准值组成的子数组
对两个子数组进行排序
假设现在有一个五个元素的数组?
list_num = [3, 5, 2, 1, 4]
假设选择的基准值是1,分区为:
[ ]
和[3, 5, 2, 4]
假设选择的基准值是2,分区为:
[1, ]
和[3, 5, 4]
假设选择的基准值是3,分区为:
[2, 1]
和[5, 4]
假设选择的基准值是4,分区为:
[3, 2, 1]
和[5]
假设选择的基准值是3,分区为:
[3, 2, 1, 4]
和[]
注意:这些子数组包含的元素个数都在0~4之间,而你已经知道如何选择进行排序,因此不管选择任何基准值,你都可以划分两个子数组进行递归排序。
假如:你使用3用于基准值,可以对得到的数组进行排序。
将任何元素作为基准值都可以,同理你可以对其他长度的数组进行排序,以次类推。
快速排序代码实现:
def quick_list_sort(array):
# 基线条件
if len(array) < 2:
return array
else:
# 基准值
pivot = array[0]
less = [i for i in array[1:] if i <= pivot]
greater = [i for i in array[1:] if i > pivot]
return quick_list_sort(less) + [pivot] + quick_list_sort(greater)
array = [10, 4, 5, 1,89, 33]
print(quick_list_sort(array))
平均情况和最糟情况
快速排序的性能高度主要依赖于你选择的基准值,假设你总是将第一个元素用作于基准值,且处理的数组是有序的,由于快速排序不检查数组是否有序,因此他依旧对其进行排序。
注意:数组并没有分为两半,有一个数组始终为空,这导致 调用栈时间非常长。
现在将基准值作为一个中间值,则如下图示:
示例中,第二种明显是最优情况:栈的高度为O(log n),而每层的时间是O(n),这个算法的时间就是O(n log n)。这就是最优情况。最糟情况算法:O(n) * O(n) = O(n 2)。
知道吗?最佳情况也是平均情况,只要你每次都随机取一个数组元素作为基准值,这样的平均时间就是O(n log n)。快速排序是最快的排序算法之一。
注意:
实现快速排序算法的时候,请随机选择作为基准值的元素,快速排序算法平均运行时间是O(n log n)。
---END---
莫名Coder
关于 Python 都在这里