排序算法之快速排序及其优化

快速排序


其余排序方法:选择排序冒泡排序归并排序快速排序插入排序希尔排序html


思想

从数组中选取一个元素,以它做为比较基准,比它小的都放到数组左边;比它大的则放到右边。而后左边的数组和右边的数组也进行一样的操做。这样递归下去,最后数组就会成为一个有序的数组。python

图解

借用一下百科的图:
数组

性能

快速排序时不稳定的,它的最好和平均时间复杂度为O(nlogn)。
最坏的状况就是每次所选的基准都是当前序列中的最大或最小元素,这样每次划分的两个子数组中都有一个是空数组,则最终须要通过n次划分,最坏的时间复杂度为O(logn^2)。
python的递归层数是有限制的,当n大到必定程度时,就会崩掉。因此咱们应该尽可能避免最坏的状况发生。性能

代码

Python:优化

# 快速排序
# left为第一个下标,right为最后一个下标
def quickSort(arr, left, right):
    if left >= right: return

    # 将第一位元素设为比较基准
    key = arr[left]

    i, j = left, right
    # 比基准小的元素都放到左边,大的都放到右边
    while i < j:
        while i < j and arr[j] >= key:
            j -= 1
        arr[i] = arr[j]

        while i < j and arr[i] <= key:
            i += 1
        arr[j] = arr[i]
    arr[i] = key

    # 左右两边的数组进行一样的操做
    quickSort(arr, left, i - 1)
    quickSort(arr, i + 1, right)

优化

快速排序的优化主要针对于最坏状况的优化,如何避免每次所选的基准都是当前序列中的最大或最小元素?
咱们一般是取第一位元素做为基准值。数组若是一开始就是有序的话,就是最坏状况了。
改进方法:
有一种方法就是在排序以前shuffle一下(打乱顺序);
还有一种是不取第一位元素,而是取第一位、最后一位和中间位中的中值元素做为基准值,这样就能彻底避免最坏状况了。ui

# 取中值
def midVal(arr, left, right):
    mid = left + right >> 1

    if arr[mid] > arr[right]:
        arr[mid], arr[right] = arr[right], arr[mid]
    if arr[left] > arr[right]:
        arr[left], arr[right] = arr[right], arr[left]
    if arr[mid] > arr[left]:
        arr[left], arr[mid] = arr[mid], arr[left]
    return arr[left]


# 快速排序
# left为第一个下标,right为最后一个下标
def quickSort(arr, left, right):
    if left >= right: return

    # 取第一位、最后一位和中间位中的中值元素做为基准值
    key = midVal(arr, left, right)

    i, j = left, right
    # 比基准小的元素都放到左边,大的都放到右边
    while i < j:
        while i < j and arr[j] >= key:
            j -= 1
        arr[i] = arr[j]

        while i < j and arr[i] <= key:
            i += 1
        arr[j] = arr[i]
    arr[i] = key

    # 左右两边的数组进行一样的操做
    quickSort(arr, left, i - 1)
    quickSort(arr, i + 1, right)

其余排序方法:选择排序冒泡排序归并排序快速排序插入排序希尔排序code

相关文章
相关标签/搜索