2.3 - 7
其实这道星号题的思路已经在前面几个习题中给了提示。
思路是先用merge sort对数组升序排列,然后进行binary search即可, 时间复杂度为
\T(n)=Θ(nlogn+logn)=θ(nlogn)
算法分析如下:
设二叉搜索下边界为
low
,上边界为
high
,中间index为
mid
。
则每次迭代后,待搜索区域为
Ssorted[low...high]
(loop invariant)。
针对loop invariant, 对算法的三个阶段进行分析验证:
1. Initialization: after MERGE-SORT
此时loop invariant为待搜索区域,初始条件正确。
2. Maintenance:
mid=⌊(low+high)/2⌋ ,每次迭代后,如果未满足终止条件,则有两种情况:
if S[mid]+S[mid+1]<x:low=mid+1
else if S[mid]+S[mid−1]>x:high=mid−1
迭代后均满足loop invariant保持正确。
- Termination:
终止条件有两种情况,一是找到了 sum=x , 二是没找到。
if S[mid]+S[mid+1]==x||s[mid]+s[mid−1]==x return YES
if low>high return NIL
感觉书上介绍的initialize-maintence-terminate分析方法很好用,用这个方法分析迭代算法感觉条理很清晰,边界问题也容易想清楚。根据分析结果来写代码感觉6了很多。
思考题 2-1
这题是将merge sort和insert sort综合起来了,题设是把数组分成k长度的sublist时开始用insert sort排序,最后merge。a.b.c很简单,纯粹数学题而已,这里想记录一下我自己对d小问的想法,问题如下:
d. How should we choose k in practice?
自己实在资质愚钝,一开始没什么想法,只是感觉应该选一个小一点的k。后来上网查,看到有人说选insert sort排序时间比merge sort排序时间小的最大k值即可。
乍看感觉很有道理,似乎取了一个最优值,但是细想,觉得不对。从降低running time的角度出发,k值的选取应该是让running time最小。因此,直觉上,感觉k值的选取应该是insert sort排序这个sublist时能够比merge sort省最多的时间,也就是尽量选取靠近 kTmax|T=Tinsert−Tmerge 的k值. 这个k值不会是insert sort比merge sort时间小的最大k值,因为此时insert sort和merge sort所花费的时间已经相差无几。