python排序算法实现——(四)快速排序

快速排序简介

快速排序(英语:Quicksort),又称划分交换排序(partition-exchange sort),通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

步骤为:

从数列中挑出一个元素,称为”基准”(pivot),
重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区结束之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。
递归的最底部情形,是数列的大小是零或一,也就是永远都已经被排序好了。虽然一直递归下去,但是这个算法总会结束,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。

代码实现

def quick_sort1(arr):
    if len(arr) < 2:
        return arr  # 基线条件:数列为空或者为1
    else:
        pivot = arr[0]  # 递归条件
        less = [i for i in arr[1:] if i <= pivot]
        greater = [i for i in arr[1:] if i > pivot]
        return quick_sort1(less) + [pivot] + quick_sort1(greater)

算法优化

快速排序的速度取决于选取的基准值,选取不同基准值时时间复杂度变化如下:

平均(取随机值为基准):O(nlogn)

最佳(取中间值为基准):O(nlogn)

最糟(取第一个值为基准):O(n^2)

针对这一点,可以选取中间值作为基准,代码如下:

def quick_sort2(alist, start, end):
    """快速排序"""
    if start >= end:  # 递归结束基准
        return

    mid = alist[start]  # 设定基准元素

    low = start

    high = end

    while low < high:
        while low < high and alist[high] >= mid:  # 如果该元素大于基准
            high -= 1  # 不对该元素做处理,移动下标处理下一个元素
        # 如果元素小于基准
        alist[low] = alist[high]

        while low < high and alist[low] < mid:
            low += 1
        # 将low指向的元素放到high的位置上
        alist[high] = alist[low]

    # 循环结束,low与high重合,指向基准元素的位置
    alist[low] = mid

    # 对基准值右边的元素进行快速排序
    quick_sort2(alist, start, low - 1)

    # 对基准值左边的元素进行快速排序
    quick_sort2(alist, low + 1, end)

两者的速度比较如下:

li = [41, 45, 44, 2, 78, 62, 25, 34, 65]

q1 = timeit.Timer("quick_sort1(li)", "from __main__ import quick_sort1, li")
q2 = timeit.Timer("quick_sort2(li, 0, len(li) - 1)", "from __main__ import quick_sort2, li")

print(q1.timeit(number=1))
print(q2.timeit(number=1))
1.6820492118368674e-05
9.846141727825561e-06

可见明显快了!

时间复杂度

最优时间复杂度:O(nlogn)
最坏时间复杂度:O(n2)
稳定性:不稳定

猜你喜欢

转载自blog.csdn.net/m0_38106113/article/details/81805348