算法导论 第7章 课后习题

转自http://www.cnblogs.com/bigrabbit/archive/2012/06/08/2541356.html,中间有新增

7.2-4 银行经常按照交易时间,来记录有关某一账户的交易情况,但是,很多人喜欢按照票据号来收到其银行对账单。因此,如何将按交易时间排序转换成按支票编号来排序,就成为一个对几乎排好序的输入进行排序的问题。证明在这个问题上,过程INSERT_SORT的性能往往优于过程QUIKSORT。

    问题解析:
    对于QUIKSORT来说,输入一个已排序的数组属于最坏的情况,则每次区间划分都是最大程度的不对称。其算法运行的递归时间为T(n) = T(n-1) + Θ(n), 算法时间复杂度为Θ(n^2); 而对INSERT-SORT来说,输入一个已排序的数组却属于最佳的情况,算法时间复杂度为O(n)。也就是说当输入一个几乎排好序的数组,快速排序趋于最坏的情况,而插入排序却趋于最佳的情况。为降低这种最坏情况出现的概率,采用快速排序随机化版本,期望的运行时间为O(nlgn)。
 

7.3-2 在过程RANDOMIZED_QUIKSORT的运行过程中,最坏情况下对随机排序产生器RANDOM调用了多少次?最佳情况下调用了多少次?以Θ记号形式个给出你的答案。

   问题分析:

        随机快速排序中,只要区间包含元素数目大于1,则需调用RANDOMIZED-PARTITION,选取主元(pivot)进行区间划分, 而主元的选取需调用Random。主元(pivot)一旦被选出来后,就不会在加入到后续的排序了。直白来说就是, 有多少次主元(pivot)选取就有多少次随机数生成 。另一方面从算法的递归二叉树树上来看,递归树二叉树的 非叶子节点 可表示一个主元(pivot); 而叶子节点分为两种,一种节点是包含0个元素,另一种节点是包含1个元素(这一点比较抽象,下面用图说明) ,而且叶子结点元素不是主元(pivot)。 非叶子节点(主元)和包含1个元素的叶子节点的数目之和就是输入序列的大小n 。即递归树的非叶子节点(主元)的数目就是调用RANDOM的次数。调用RANDOM次数T(RANDOM)≤n,即T(RANDOM)=O(n)。
  又根据二叉树的性质, 对于任意一棵二叉树,如果其叶结点数为a,而度数为2的结点(非叶子节点)总数为b,则a=b+1;对于快速排序的递归二叉树中, 非叶子节点度数均为2。假设含有0个元素的叶子节点数目a0(≥0),含有1个元素的叶子节点数目为a1,所以 b =a-1 ≥ a1 - 1;又b+a1 = n,可得 b ≥ n/2 - 1 ,即T(RANDOM)=Ω(n)。   
  总的来说T(RANDOM)= Θ(n) 
我的理解:图示:
算法导论 第7章 课后习题_第1张图片
假定对4,3,4,1,6,5,7,8这个数列做快速排序,将第一个元素做为主元,则第一次选主元为4,将数列分成13,4和6,5,7,8两段。第二次选主元,1,3,4的主元为1。6,5,7,8的主元为6,一直选主元到最后,就如上图所示。可以看出,叶子结点不是主元,比如4,8不是主元,因为数组只有一个元素之后,partition不执行划分取主元。
现在开始考考O(n)和 Θ (n)。
假定一个数组的元素个数为n则n=非叶子节点(主元)(4,1,3,6,5,7)+包含1个元素的叶子节点数目(4,8)
则有,T(RANDOM)≤n,即 T(RANDOM)=O(n)
又根据二叉树的性质,对于任意一棵二叉树,如果其叶结点数为a,而度数为2的结点(非叶子节点)总数为b,则a=b+1;则全部结点数为a+b=b+1+b=2b+1>=n.
所以,b ≥ n/2 - 1。
总的来说T(RANDOM)=Θ(n) 


你可能感兴趣的:(C++,算法分析与设计)