快速排序

快速排序

快速排序是对冒泡排序的一种改进。基本思想是分治法:在待排序表 L[1.....n]中任取一个元素pivot作为基准,通过一趟排序将待排序表划分为独立的两部分 L[1...k-1]和 L[k+1...n] ,使得L[1...k-1]的所有元素小于pivot,L[k+1...n]中所有元素大于pivot,则pivot放在了其最终位置L(k)上,这个过程称为一趟快速排序。而后分别递归的对两个子表重复上述过程,直至每部分内只有一个元素或空为止,即所有元素放在了其最终位置。

快速排序思路:

a. 取一个元素p(第一个元素),使元素p归位;
b. 列表被p分成两部分,左边都比p小,右边都比p大;
c. 递归完成排序。

假设划分算法已知,记为partation(),递归的调用快排,具体结构如下:

def quick_sort(data, left, right):
    if left < right:
        mid = partition(data, left, right)
        quick_sort(data, left, mid - 1)
        quick_sort(data, mid + 1, right)

 可以看出快排关键在于划分操作,同时快排性能也主要取决于划分操作好坏。

对于划分算法,假设每次总是以当前表中第一个元素作为枢纽值(基准)对表进行划分,则必须将表中枢纽值大的元素向右移,比枢纽值小的向左移动,使得一趟partition()操作后,表中的元素被枢纽值一分为二。

def partition(data, left, right):
    tmp = data[left]
    while left < right:
        while left < right and data[right] >= tmp:
            right -= 1
        data[left] = data[right]
        while left < right and data[left] <= tmp:
            left += 1
        data[right] = data[left]
    data[left] = tmp
    return left

 

快排性能分析:

空间效率:

由于快排是递归的,需要借助一个递归工作栈来保存每一层递归调用的必要信息,其容量应于递归调用的最大深度一致。最好情况下为[log(n+1)];最坏情况下,O(n)。所以空间复杂度:平均为O(logn),最坏情况O(n)。

时间效率:与划分是否对称有关,快排最坏情况发生在两个划分区域分别含n-1个元素和0个元素时,这种最大程度的不对称性发生在每一层递归上,就得到最坏情况下的时间复杂度O(n^2)。如所有逆序排列的元素,对其进行快排,时间复杂度O(n^2)。

在理想状态下partition()可以做到最平衡的划分,此时时间复杂度为O(nlogn)。

快速排序是内部排序平均性能最优的算法。

快排在划分算法时,若右端区间存在两个关键字相同,且均小于基准值记录,则在交换到左区间后,相对位置发生变化,故快排是一个不稳定排序方法。

 

posted @ 2019-04-13 12:26  Dylan123  阅读(214)  评论(0编辑  收藏  举报