我正在自学CLRS第3版,这是我遇到的更强硬的问题之一及其答案作为对所有人的服务。
7.4-5
我们可以利用这个优势,在实践中改善快速排序的运行时间
当输入“几乎”排序时,插入排序的快速运行时间。打电话
快速排序使用少于k
个元素的子数组,让它简单地返回
对子阵列进行排序。在对quicksort的顶级调用返回后,运行插入排序
在整个阵列上完成排序过程。认为这种排序算法
在O(nk+nlg(n/k))
预期时间内运行。理论上我们应该怎样选择k
并在实践中?
答案 0 :(得分:5)
如果您计算等式nlgn > nk + nlog(n/k)
,则会得到log k > k
。这是不可能的。因此在理论上它是不可能的。但在实践中,插入排序和快速排序涉及不变因素。看看这个pdf中讨论的解决方案。您可能想要更新您的答案。 。
答案 1 :(得分:2)
实际上,答案是k = 8
。
您获得的算法是两个匿名函数的组合,其中一个是O(nk)
,另一个是O(n lg n/k)
。这些匿名函数隐藏了平均大小写常量。插入排序在n^2/4
时间内以平均情况运行,随机快速排序在1.386 n lg n
中以平均情况运行。我们希望找到k
的值,以最小化等于nk/4 + 1.386( n lg n/k )
的{{1}}的值。这意味着找到函数nk/4 + 1.386 n lg n - 1.386 n lg k
的最大值。该最大值出现在1.386 lg k - k/4
。
答案 2 :(得分:0)
叶子在1
到k
之间的大小概率相等
所以叶子的预期大小是k/2
如果叶子的预期大小为k/2
,那么我们期望n/(k/2)=(2n)/k
这样的叶子
为简单起见,我们假设我们期望n/k
这样的叶子,并且每个叶子的预期大小为k
。
INSERTION-SORT
的预计运行时间为O(n^2)
我们发现在练习5.2-5和问题2-4c中
因此INSERTION-SORT
使用的预计运行时间为O((n/k)*(k^2))=O(nk)
如果我们希望我们的分区组大小为k
,那么递归树的高度应该是lgn-lgk=lg(n/k)
,因为我们希望先前停止lgk
。
递归树的每个级别都有O(n)
次操作
这导致我们O(nlg(n/k))
我们得出结论,预计运行时间为O(nk+nlg(n/k))
。
理论上,我们应该选择k=lgn
,因为这样我们就可以获得O(nlgn)
的最佳预期运行时间。
在实践中,我们应该k
选择lgn
周围的一个值,这样可以提供比仅运行RANDOMIZED-QUICKSORT
更好的性能。
答案的第二部分使用了大O符号,因此为了更精确地选择k
,请按照Ankush在第二个答案中给出的链接。