MIT算法导论学习笔记-Lecture4 分治法(续)

第四讲:分治法(续)

4.1 快速排序(Quicksort)

         1这是一种分治法实现

         2这是原地(“in place”)排序,即不需要额外的存储空间

         3该算法很实用

算法步骤:

—Devide,把输入序列分成两个子序列,左边的子序列小于等于pivot,右边的序列大于pivot,即如下图:


—Conquer,递归地用上述方法对两个子序列进行排序;

—Combine,trivial(无足轻重),因为是已经排列好了的。

Merge Sort本质上是递归地Merging,而Quicksort本质上是递归地Partitioning(分成子序列)


关键步骤:划分(Partitioning)
伪代码:



对于n个元素的划分的时间复杂度为:

         T(n) = Theta(n),即是线性时间复杂度

那么,有了划分的子程序,分别对两个子序列进行递归调用即可,Quicksort的伪代码实现为:

上述是一种尾递归方法,可以使用一些尾递归方法对其做优化(关于递归,在《算法精解C语言描述》里有一章专门讲述基础,有兴趣的可以去参考下);对其可以做小的改进,但是核心思想不变。

代码实现:可以参照此前的一篇文章,《六种排序算法分析及C语言实现》。

http://blog.csdn.net/ai552368625/article/details/37904631

4.2 算法分析

4.2.1Worst-Case 分析

什么情况会出现Worst-Case呢???

当输入的序列是有序的,或者逆序的时候,即划分的一边一直是没有元素。原因是,此时:


上面的解,可以用递归树来验证,从上到下的每一层分别是n,n-1,…,Theta(1),


4.2.2 Best-Case 分析

该分析只为直观理解,因为大多数的情况下,我们并不关心最好的情况,因为这根本无法保证算法的性能。
        第一种情况: 假设每一次划分都能把序列分成n/2:n/2,即每次都能将序列对半分,此时:
                   T(n)= 2T(n/2) + Theta(n) = Theta(nlgn)
         这与归并排序的时间复杂度相同。
         第二种情况:假设每一次划分都是将序列的长度分为1/10:9/10,此时:
                   T(n)= T(n/10) + T(9n/10) + Theta(n) = Theta(nlgn)

具体的推导,请参照视频或者课件,这里给出按递归树推导的最后一步,如下图

上图中需要注意的是,每一个分支的深度是不同的,e.g.,一直按1/10展开的路径是log10(n),而一直按9/10展开的路径深度是log(10/9)(n),那么由此即可以得到T(n)的上下界,都为

         T(n)= Theta(nlgn)

我们将Theta(n^2)的情况当做unlucky情况,而把Theta(nlgn)的情况当做lucky情况,一个更一般的假设是,这两种情况交替出现时结果是什么???

4.2.3 交替情况分析

Lucky情况时,时间复杂度为:

 L(n)= 2U(n/2) + Theta(n)

Unlucky情况时,时间复杂度为:

U(n)= L(n-1) + Theta(n)

用代入法很容易解决,即:

 L(n)= 2(L(n/2 - 1) + Theta(n/2) ) + Theta(n)

 =2L(n/2 - 1) + Theta(n)

=Theta(nlgn)  <—Lucky

即,在二者交替出现时,结果仍然是最好的情况,那么怎么样保证结果一直是好的呢???

随机快排法:

——序列随机化

——随机选择pivot

视频中给出了随机pivot的分析,运用了一点统计的知识,这里不再给出证明,其结果是证明了其运行时间的期望为:

         E[T(n)]<= anlg(n),即其时间复杂度仍然是Theta(nlgn)







  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值