算法 - 快速排序

快速排序是由东尼·霍尔所发展的一种排序算法。快速排序又是一种分而治之思想在排序算法上的典型应用。本质上来看,快速排序应该算是在冒泡排序基础上的递归分治法。

快速排序基本思想

选择一个基准数,通过一趟排序将要排序的数据分割成独立的两部分

其中一部分的所有数据都比另外一部分的所有数据都要小

再按此方法对这两部分数据分别进行快速排序

递归进行后,可以让整个数据变成有序序列

稳定性

快速排序是不稳定的算法,它不满足稳定算法的定义。

算法稳定性 :假设在数列中存在 a[i]=a[j],若在排序之前, a[i]a[j] 前面;并且排序之后, a[i] 仍然在 a[j] 前面。则这个排序算法是稳定的

时间复杂度

快速排序的时间复杂度在最坏情况下是O(N2),平均的时间复杂度是O(N*lgN)

img

图源:https://www.runoob.com/

代码实现

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
def quickSort(arr, left=None, right=None):
    # 如果 left 不是整数或浮点数,那么将 left 设置为 0;否则保留 left 的原值。
    left = 0 if not isinstance(left, (int, float)) else left

    # 如果 right 不是一个整数或浮点数,那么 right 的值会被设置为数组 arr 的最后一个索引。
    # 如果 right 已经是一个整数或浮点数,那么它的值将保持不变。
    right = len(arr) - 1 if not isinstance(right, (int, float)) else right

    if left < right:
        # 执行分区操作,将数组分为两部分,左边都小于等于基准值,右边都大于基准值
        partition_index = partition(arr, left, right)
        # 对左半部分进行递归排序
        quickSort(arr, left, partition_index - 1)
        # 对右半部分进行递归排序
        quickSort(arr, partition_index + 1, right)
    return arr


def partition(arr, left, right):
    # 将第一个元素设为基准
    pivot = left
    # 初始化基准最终位置的索引
    index = pivot + 1

    # 从基准的下一个元素开始遍历数组
    i = index
    while i <= right:
        # 如果当前元素小于基准,将其与索引位置的元素交换,并递增索引
        if arr[i] < arr[pivot]:
            swap(arr, i, index)
            index += 1
        i += 1

    # 将基准与索引 -1 位置的元素交换,以将基准放置在其正确位置
    swap(arr, pivot, index - 1)
    return index - 1


def swap(arr, i, j):
    arr[i], arr[j] = arr[j], arr[i]