Python排序算法之快速排序:深入理解与实现

快速排序是一种高效的、基于比较的、不稳定的原地分区交换式排序算法。然后将小于枢轴值的元素放到左侧数组中,假设我们要对以下列表进行升序排列:right)quick_sort(arr,

在计算机科学中,排序是一项基本的操作。无论是搜索、数据分析或者其他领域,都需要对数据进行排序。而在Python中,有多种排序算法可供选择。其中最常用的就是快速排序。

快速排序是一种高效的、基于比较的、不稳定的原地分区交换式排序算法。它通过将序列分成两个子序列来递归地进行操作,直到整个序列有序为止。

那么我们来深入了解一下快速排序吧!

1. 快速排序原理

首先我们需要了解“分治”的思想,即将问题划分为若干个子问题并求解这些子问题,在合并其结果得到原问题答案。

具体到快排中,我们选取一个元素作为枢轴(pivot),然后将小于枢轴值的元素放到左侧数组中,大于等于枢轴值的元素放到右侧数组中。接着再对左右两侧数组递归地进行上述过程即可。

下面以一个例子来说明:

假设我们要对以下列表进行升序排列:

[5, 2, 9, 3, 7]

首先选取5作为枢轴,并将其从列表中删除。然后将小于5的元素放到左侧数组,大于等于5的元素放到右侧数组:

左侧数组:[2, 3]

右侧数组:[9, 7]

接着对左右两个子序列递归进行上述过程,直到每个子序列只有一个元素为止。最终得到升序排列后的列表:

[2, 3, 5, 7, 9]

2. 快速排序实现

下面我们来看一下如何在Python中实现快速排序。

“`python

def quick_sort(arr):

if len(arr) <= 1:

return arr

pivot = arr.pop() #选取最后一个元素作为枢轴

left = []

right = []

for item in arr:

if item < pivot:

left.append(item)

else:

right.append(item)

return quick_sort(left) + [pivot] + quick_sort(right)

“`

以上是快排的简单实现,其时间复杂度为O(nlogn)。

3. 快速排序优化

虽然快排已经是一种高效的排序算法,但是我们还可以对其进行优化以提高性能。

(1)三数取中

在上述例子中,我们选择了第一个元素作为枢轴。但是如果列表本身已经有序或者部分有序,则会导致递归树变成链表结构从而使算法的时间复杂度退化为O(n^2)。

为了避免这种情况,我们可以采用“三数取中”的方式来选择枢轴。即从列表的第一个、中间和最后一个元素中选择一个中位数作为枢轴。

def quick_sort(arr, left=0, right=None):

Python排序算法之快速排序:深入理解与实现

if right is None:

right = len(arr) – 1

if left >= right:

return

pivot_index = partition(arr, left, right)

quick_sort(arr, left, pivot_index – 1)

quick_sort(arr, pivot_index + 1, right)

def partition(arr, left, right):

# 三数取中

mid = (left + right) // 2

if arr[left] > arr[right]:

arr[left], arr[right] = arr[right], arr[left]

if arr[mid] > arr[right]:

arr[mid], arr[right] = arr[right], arr[mid]

if arr[left] <arr[ mid]:

mid=left

# 将pivot放到最右边,方便操作

# 这个比较好理解,因为快排是要把小于pivot的放左边,

# 大于等于pivot放右边,所以一开始把pivot放到最右端,

# 左端就不会有影响了。

# 把mid当做枢纽

quick_sort([5 ,4 ,3 ,2])

(2) 插入排序

在序列长度小于等于10时,快排的效率会大打折扣。因为此时递归树深度较浅,而快排复杂度在递归树深度较深时表现更好。

因此,我们可以采用插入排序来优化快排。即当序列长度小于等于10时,使用插入排序进行排序。

# 序列长度小于等于10时使用插入排序

if right – left + 1 <= 10:

insertion_sort(arr, left, right)

def insertion_sort(array: List[int], low: int = None,

high: int = None) -> List[int]:

4. 总结

综上所述,快速排序是一种高效的、基于比较的、不稳定的原地分区交换式排序算法。通过将序列分成两个子序列来递归地进行操作,直到整个序列有序为止。

对快速排序进行优化可以提高其性能。例如采用“三数取中”的方式选择枢轴以避免退化为O(n^2),或者在序列长度小于等于10时使用插入排序进行优化。

最后,我们需要注意快速排序的局限性。其主要是由于其不稳定性导致的。当两个元素值相等但位置不同时,它们有可能会被交换位置。因此,在某些情况下需要考虑其他排序算法。