Solution to CLRS Chapter 7

7-1.1
0: 13,19,9,5,12,8,7,4,21,2,6,11
1: 9,19,13,5,12,8,7,4,21,2,6,11
2: 9,5,13,19,12,8,7,4,21,2,6,11
3: 9,5,8,19,12,13,7,4,21,2,6,11
4: 9,5,8,7,12,13,19,4,21,2,6,11
5: 9,5,8,7,4,13,19,12,21,2,6,11
6: 9,5,8,7,4,2,19,12,21,13,6,11
7: 9,5,8,7,4,2,6,12,21,13,19,11
8: 9,5,8,7,4,2,6,11,21,13,19,12
return 8

7-1.2
返回结果是r
只要先特判一遍,如果全部相等就取一半。

7-1.3
n的复杂度,主要就是来自于j的遍历

7-1.4
基本上每一种排序都会出这道题目,也许理解一个排序算法的核心,就是弄清楚他的大小分配吧。只要把LINE4的小于等于改成大于等于就可以了。

7.2-1
这题也不用substitution method,展开就能够看出来是n^2的复杂度。

7.2-2
由于之前的练习给了一个调整,所以在所有元素相同的情况下,复杂度应该是标准的nlog(n)

7.2-3
这个也比较简单,主要就是想表达quicksort的worst case 就是n^2的复杂度。如果是递减的话,每次partition都只能够把数组长度减少1,从而形成严重不平衡,时间复杂度变成了7.2-1中的那个公式。

7.2-4
这题定性分析,在一个数组几乎已经排好序的情况之下,用insertion sort的复杂度是十分接近线性的,但是quicksort的复杂度很高,根源就在于quicksort在遇到已排序数组的时候,partition过程会生成不平衡的划分,导致quicksort出现worst case。所以银行工作人应该采用的是insertion sort,应该不会有人去用quick sort去排序,就算他们知道这个算法也不会去用。

7.2-5
这个不是显而易见的么,a个儿子的树高度应该是log(n)/log(a)。。。

7.2-6
这个是一个数学题。比较复杂的数学题,对算法本身的理解似乎没有什么帮助,跳过了。

7.3-1
因为没有什么input能够让算法达到worst case,同时所有的input都可能让算法达到worst case,所以worst case没有意义,因为不存在这样的case

7.3-2
由于Random和Partition 是绑定的,所以Random的调用次数就是partition的调用次数,那么这道题其实就是之前的题目,问最坏最好的情况。没什么难度。调用n次和log(n)次

Problem

7-1 Hoare partition correctness
(a)
0: 13,19,9,5,12,8,7,4,11,2,6,21 i=0,j=13,x=13
1: 6,19,9,5,12,8,7,4,11,2,13,21 i=1,j=11
2: 6,2,9,5,12,8,7,4,11,19,13,21 i=2,j=10
3: 6,2,9,5,12,8,7,4,11,19,13,21 i=10,j=9
return 9
一开始我对这个结果挺疑惑的,不理解为什么返回9因为13不在9这个位置,后来发现这个算法的目的只是把序列分开来,至于划分的标准,没有必要在划分点。。
(b)
证明i,j绝对不会越界。
证明,第一次i和j必然能够在A[p]停下来(这个是由循环判断中的等号保证的),这个时候,直接返回。这个情况的意思是,如果i,j停下来之前,没有做任何的交换,那么它们也不会越界。
那剩下的情况,就只是:i,j在停下来之前,做了交换,比如分别在A[x],A[y]的位置,那么j最起码一定会在交换后的x处停止,i同理!!这个部分我觉得无比奇妙,达到这个效果,仅仅只是在判断条件中,添加了一个等号!!
(c)
证明划分停止时,j在区间内,而且j不在r处。
这个根据上面的结论一定得出j在区间内,j不在r处的意思,就是说这个划分一定能保证数组在变小,那么为什么j不在r处呢?其实很简单,如果j在r停止,而i必然在p停止一次,两者交换后,j必须移向r-1,告别了r
(d)
循环不变量来证明循环的正确性,在我看来其实是提供一种机械的手段,来确保自己算法的正确性。这个循环不变量的成立很显然。
(e)
这里有一个细节,注意到之前给出的算法,经过划分之后,保证划分点一定是已经排好序了的,但是Hoare不能保证这一点!

RANDOMIZED-QUICK-SORT(A, p, r)
        if p < r
                q = RANDOM-PARTITION(A, p, r)
                RANDOMIZED-QUICK-SORT(A, p, q+1)
                RANDOMIZED-QUICK-SORT(A, q+1, r)

RANDOM-PARTITION(A, p, r)
        i = RANDOM(p, r)
        swap(A[i], A[p])
        HOARE-PARTITION(A, p, r)

HOARE-PARTITION(A, p, r)
        j = r + 1
        i = p - 1
        x = A[p]
        while true
                do 
                        j = j - 1
                until A[j] <= x
                do 
                        i = i + 1
                until A[i] >= x
                if i < j
                        swap(A[i], A[j])
                else
                        return j

7-2 Quicksort with equal element values
这道题考虑当数组中出现相同的元素的时候,quicksort的效率如何。为什么排序算法会对元素是否相同敏感呢?就quicksort而言,由于划分的平衡性决定了quicksort的效率,而元素相同的情况很容易就导致了书上的划分方式的worst case(不过相同元素能够使得Hoare划分最优)
(a)
如果元素全部都是相同的话,RANDOMIZED-PARTITION并没有什么用,怎么随机都改变不了1,n-1的划分。running time 显然就是N
(b)
这里要求实现一个划分,将数组划分成三段:小于x,等于x,大于x。这样一来,中间的部分,也就是全x的部分,天生就是排序完毕的。这样如果相同元素很多的话,就大大减少的复杂度!
那么怎么去实现这样一个个划分呢?我是这么想的:
如果把所有比x小的放在数组前面,把所有比x大的放在数组后面,那么中间的部分就自然而然的是x!这个实现起来很简单,只要用两个下标指针来标记大小范围就可以了。

NEW-PARTITION(A, p, r)
        i = p - 1
        j = r + 1
        x = A[r]
        for k = p : r
                if A[k] < x
                        i = i + 1
                        swap A[i], A[k]
                elseif A[k] > x
                        j = j - 1
                        swap A[j], A[k]
        return i, j

(c)
发现自己坐上面一道题的时候已经考虑完这道题要考虑的意思了。

7-4 Stack depth for quicksort
这题指出在QuickSort中其实可以只调用一次自身就能够完成,并且引入了tail-recursion的方法
(a)
证明那个算法是正确的,由于用的是循环,所以从循环不变量的角度去考虑
Initialization:
最开始的时候,p=1,q=n,所以p之前的元素当成是有序的。
Maintenance:
假设循环前,p之前的数组一定是有序的,那么循环之后,p之前的数组一定也有序,因为p,r是一个正确的划分,那么q之前的数一定比q小,那么调用了递归对q之前的数排序后,并不影响它们和q之间的兼容,所以q之前的数有序,从而p之前的数有序,性质维持。
Termination:
结束的时候p >= r这时p之前的数有序,所以整个数组有序。

(b)
题意是设想一个最糟糕的情况,让tail-recursive-quicksort的栈的深度达到N.这个其实就是QS的最坏划分啦,就每次分离一个元素。比如,若是用书中正文的划分程序,那么所有元素都相同就可能导致这种划分。

(c)
这题要你调整尾递归的QS代码,使得最大栈深度是log(n).
这题其实我不是很有把握,根据题目的expected running time,所以我考虑的方向是用随机划分代替这里的普通划分。

7-5 Median-of-3 partition
Median-of-3是对QuickSort的一个常数级的优化,算法本身很简单,就是在划分时,选取3个随机数,然后从中选择三者的中位数。

7-6 Fuzzy sorting of intervals
模糊排序。这题是对几个区间的模糊排序,除非两个区间互斥,否则他们的大小可以随意改变。
这题可能是有实际意义的,但我不是很清楚。这个也比较简单,之前的QS的题目里面有一个是判断和x相等的值有多少个,可以直接用那个算法,也就是说,判断两个区间是否有重叠,如果有,那么就当作是“相同的数”,这样一来,如果区间全部重叠的话,那么就是QS全部相同的值,区间划分在第一次就是0 n 0分配,时间复杂度n

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
目前最全的算法导论第三版的答案 清晰度极好 另每章都有章节重点总结 在第二版基础上新增习题的解答详尽清楚 很适合 用这本经典教材的同学! Contents Revision History R-1 Preface P-1 Chapter 2: Getting Started Lecture Notes 2-1 Solutions 2-17 Chapter 3: Growth of Functions Lecture Notes 3-1 Solutions 3-7 Chapter 4: Divide-and-Conquer Lecture Notes 4-1 Solutions 4-17 Chapter 5: Probabilistic Analysis and Randomized Algorithms Lecture Notes 5-1 Solutions 5-9 Chapter 6: Heapsort Lecture Notes 6-1 Solutions 6-10 Chapter 7: Quicksort Lecture Notes 7-1 Solutions 7-9 Chapter 8: Sorting in Linear Time Lecture Notes 8-1 Solutions 8-10 Chapter 9: Medians and Order Statistics Lecture Notes 9-1 Solutions 9-10 Chapter 11: Hash Tables Lecture Notes 11-1 Solutions 11-16 Chapter 12: Binary Search Trees Lecture Notes 12-1 Solutions 12-15 Chapter 13: Red-Black Trees Lecture Notes 13-1 Solutions 13-13 Chapter 14: Augmenting Data Structures Lecture Notes 14-1 Solutions 14-9 iv Contents Chapter 15: Dynamic Programming Lecture Notes 15-1 Solutions 15-21 Chapter 16: Greedy Algorithms Lecture Notes 16-1 Solutions 16-9 Chapter 17: Amortized Analysis Lecture Notes 17-1 Solutions 17-14 Chapter 21: Data Structures for Disjoint Sets Lecture Notes 21-1 Solutions 21-6 Chapter 22: Elementary Graph Algorithms Lecture Notes 22-1 Solutions 22-13 Chapter 23: Minimum Spanning Trees Lecture Notes 23-1 Solutions 23-8 Chapter 24: Single-Source Shortest Paths Lecture Notes 24-1 Solutions 24-13 Chapter 25: All-Pairs Shortest Paths Lecture Notes 25-1 Solutions 25-9 Chapter 26: Maximum Flow Lecture Notes 26-1 Solutions 26-12 Chapter 27: Multithreaded Algorithms Solutions 27-1 Index I-1
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值