zoukankan      html  css  js  c++  java
  • 分治策略

    快速排序算法

    基本思想:被排序数组为A,用数组首元素作为标准将A分成前后两部分,比首元素小的元素构成数组的前部分,比首元素大的部分构成数组的后部分。这两部分构成两个新的子问题,算法接着对这两个数组进行递归。

    Quicksort(A,p,r) //p,r分别为数组A的首元素和尾元素的下标

    输入:数组A[p..r],1<=p<=r<=n
    输出:从A[p]到A[r]按递增顺序排好序的数组A

    if p<r
    then q <- Partition(A,p,r)   //划分数组,找到首元素A[p]在排好序后的位置q
         A[p] <-> A[q]
         Quicksort(A,p,q-1)
         Quicksort(A,q+1,r)
    

    Partition是划分的过程

    x <- A[p]
    i <- p+1
    j <- r+1
    while true do
        repeat j <- j-1
        until A[j] <= x
        repeat i <- i+1
        until A[i] > x
        if i < j
        then A[i] <-> A[j]
        else return j
    

    下面举一个例子
    image

    算法的时间复杂度分析

    1. 每个元素都要和首元素进行一次比较(在i,j相遇位置附近的元素可能比较2次),所以划分过程的工作量是O(n)。
    2. 两个子问题递归调用的工作量

    快速排序算法的各种情况分析

    1.

    均等划分子问题

    先看均等划分的例子,如果每次划分得到的子问题大小都相等,即每个子问题的规模都等于n/2,那么在当前实例下时间复杂度函数的递推方程是:

    [left{ egin{array}{lr} T(n)=2T(n/2)+O(n) & \ T(1)=0& end{array} ight. ]

    根据主定理,该方程的解(T(n)=O(nlogn)),这是一种比较好的情况。

    2.

    子问题规模不同,但遵从一定比例

    即使子问题规模不一样,但两个子问题的规模遵从一定的比例,比如1:9,那么时间复杂度函数的递推方程为:

    [left{ egin{array}{lr} T(n)=T(n/10)+T(9n/10)+O(n) & \ T(1)=0& end{array} ight. ]

    image
    c是常数

    这棵树不均衡,从树根到最左边树叶的路径最短,在这条路径上,每层的子节点的值是父节点值的1/10,设树根是第0层,每层为第k层,
    (frac{1}{10})^k^n代表当前第k层的值,即子问题规模。
    (frac{1}{10})^0^
    n=n,代表第0层值为n,
    (frac{1}{10})^k^*n=1,即子问题规模为1,到达树叶时,k=(log)~10~((x))。
    同理得到最右边路径长度是log~10/9~n,为了表示时间渐进的上界,不妨取最长路径作为树的层次,即所有节点的数值之和为

    T(n) = c(nlog)~10/9~(n) = O((nlog(n)))

    这说明,即使子问题规模不均衡,但是只要比例一定,快速排序算法的时间复杂度仍旧是(O(nlog(n)))

    3.

    下面介绍极端不均衡的情况

    即划分后两个子问题的规模一个是0,另一个是(n-1)的情况,当数组元素是按从小到大正排序或从大到小逆排列时,就会呈现这种划分。

    [left{ egin{array}{lr} W(n)=W(n-1)+O(n) & \ W(1)=0& end{array} ight. ]

    根据迭代归纳,此时(W(n)=O(n^2))
    但最坏情况出现的概率很低,它的平均性能还是不错的。

    4.

    平均情况

    假设交换后,数组A的首元素在排好序后处在(n)个位置中的任何位置都是等可能的,即它处在任何位置的概率都是(1/n)。如果它处在位置(i)(i)=1,2,...,(n)),那么划分后的两个子问题规模分别是(i-1)(n-1)。考虑到(T(0)=0),因此可以得到
    image
    当把(O(n))看作(n-1)时,这个方程的解是(T(n)=O(nlogn))
    对于排序问题,平均情况下效率最高的算法就是时间复杂度为(O(nlogn))的算法。在这个情况下,快速排序算法是平均情况下效率最高的算法之一。

  • 相关阅读:
    PHP中空字符串介绍0、null、empty和false之间的关系
    腾迅股票数据接口 http/javascript
    PHP关于依赖注入(控制反转)的解释和例子说明
    Xcode离线安装帮助文档
    php对二维数组进行相关操作(排序、转换、去空白等)
    phpqrcode不能输出二维码
    Google Chrome浏览器中如何使用命令
    Mac OS X 懒人版安装教程(之前的图全部挂了,所以重发了)
    酷友观点/经验:支付接口返回数据接收地址,session数据丢失(或者说失效)的问题浅析(原创文章)
    第三方支付过程中session失效问题
  • 原文地址:https://www.cnblogs.com/HIIM/p/12578188.html
Copyright © 2011-2022 走看看