算法分析—快速排序&主定理分析递归的复杂度

版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/u012495579/article/details/86685294

一、简介

快速排序对于初学者而言算是实现较为困难的一种排序方法,而其代码的实现方法也有多种,本文采用其中一种方法实现快排,并采用 主定理 对其复杂度进行分析。

二、基本思想

对于一个已经排序好的数组,一定有该特性:任取一个数字,其左边的数字(若存在)全部小于该数字,其右边的数字(若存在)一定大于该数字。

那么我们便可以对一个未排序数组,任取一个数字(中心数),将小于它的放左边,大于它的放右边,这样就实现了基本的第一步排序。
然后我们对左右两边分别重复以上步骤,直到数组彻底排序。

在快速排序算法中比较重要的一个步骤是找到中心数,一般而言,一个随机的中心数可以使算法更为高效,但为了简便,我们一般取最后一个数字作为中心数。

三、算法实现

import data

nums = data.get_data(1000)

def quick_sort(nums, l, r):
    if l < r:
        m = partition(nums, l, r)
        quick_sort(nums, l, m)
        quick_sort(nums, m + 1, r)

# 将数组进行初步划分,小于中心点放左边,大于放右边,返回中心数
def partition(nums, l, r):
    m = r - 1   # 取最后一个数作为中心数
    i = l   # i左边的元素均小于中心数,初始没有
    for j in range(i, m):
        if nums[j] <= nums[m]:
            nums[i], nums[j] = nums[j], nums[i]
            i += 1
    nums[i], nums[m] = nums[m], nums[i]     # 将中心数归位
    return i

quick_sort(nums, 0, len(nums))

print(nums)

上面是我采用的一种比较简便的实现方法,这儿有另一个博主写的其他三种方法实现的快速排序,链接:快速排序的三种实现方式以及非递归版本

四、算法分析

主定理

主定理最早出现在《算法导论》中,提供了分治方法带来的递归表达式的渐近复杂度分析。
规模为n的问题通过分治,得到a个规模为n/b的问题,每次递归带来的额外计算为f(n^d)。
即复杂度的表达式可表示为以下形式:
T(n) = aT(n/b) + f(n^d)

那么就可以得到问题的复杂度为:
1、 T(n) = O(n^d log(n)), if a = b^d
2、 T(n) = O(n^d ), if a < b^d
3、 T(n) = O(n^logb(a))), if a > b^d

主定理的证明以及应用举例可参考这篇博文:主定理的证明及应用举例

快速排序算法,我们使用的递归实现,便可用主定理加以分析。
每次问题划分为两个问题,规模减半,带来一次额外的循环,a=2,b=2,d=1,满足上述第一种情况,那么复杂度为n^2 log(n)。

猜你喜欢

转载自blog.csdn.net/u012495579/article/details/86685294
今日推荐