Python 实现快速排序

快排的最坏情况:O(n^2)

期望情况:O(n*lgn),且隐含的常数因子非常小,使其性能很好,在虚存中也能很好地工作。

快排也使用分治法:
分解:将A[p:r] 以A[q] 为分界线,A[p:q-1] <= A[q]; A[q+1:r] >= A[q]
解决:递归调用快速排序,在对 A[p:q-1] 与 A[q+1:r] 排序

合并:子数组为原址排序,不需要合并操作,A[p:r]已经有序

快速排序的分解条件:
在A[i: j]中寻找A[r] 满足:A[r]左边的元素全部小于A[r],A[r]右端的元素全部大于A[r]。

算法分为两部分:
QuickSort(A, p, r) # 快排主程序

Partition(A, p, r) # 算法的关键部分,寻找A[r]满足快排的分解条件的位置,在寻找位置的过程中,对子数组A[p,r]进行原址重排:将 i (A[r] 将插入的位置,主元位置) 左侧小于A[r]的元素换到右侧。


# !/usr/bin/env python3
# -*- code:utf-8 -*-
'''QuickSort.py 2018年6月14日 快速排序'''
from numpy.random import randint


def QuickSort(A, p, r):
    '''快排主程序'''
    if p < r:
        q = Partition(A, p, r)
        QuickSort(A, p, q-1)
        QuickSort(A, q+1, r)
    return A


def Partition(A, p, r):
    '''算法的关键部分,寻找A[r]满足快排的分解条件的位置,并对子数组A[p,r]的原址重排'''
    x = A[r]  # 主元
    i = p - 1
    for j in range(p, r):
        if A[j] <= x:
            i += 1  # 将i右侧小于A[r]的元素换到左侧
            A[i], A[j] = A[j], A[i]
    A[i+1], A[r] = A[r], A[i+1]
    return i+1


if __name__ == '__main__':
    A = list(randint(1, 100, 8))
    print(A)
    QuickSort(A, 0, len(A)-1)
    print(A)
快速排序性能分析
最坏情况:划分A[p]在数组末尾,共进行n次递归,时间复杂度为 n*Θ(n)=Θ(n^2 )
最好情况:划分A[p]在数组正中间,分为两个 len(A)//2的数组,时间复杂度 Θ(n∗lgn)
但即使在不平衡的划分(如9:1,进行lgn次递归)下,运行时间仍然趋于最好情况而非最坏情况,只要分划为常数比,算法的运行时间总为O(n*lgn)
阅读更多
文章标签: 算法 Python
个人分类: 算法导论
上一篇算法导论之算法基础
下一篇Python 实现计数排序
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭