我正在开发一个基于the Select algorithm的快速变体实现,用于选择一个好的枢轴元素。传统智慧似乎是将数组划分为5个元素块,取每个元素的中位数,然后递归地将相同的阻塞方法应用于生成的中位数,以获得“中位数中位数”。
令我困惑的是选择5元素块而不是3元素块。使用5个元素块,在我看来,您执行n/4 = n/5 + n/25 + n/125 + n/625 + ...
5个中值运算,而使用3个元素块,您执行n/2 = n/3 + n/9 + n/27 + n/81 + ...
3个中值运算。因为每个5的中位数是6个比较,并且每个3的中位数是2个比较,这导致3*n/2
比较使用5的中位数和n
比较使用中位数 - 3。
任何人都可以解释这种差异,以及使用5元素块的动机是什么?我不熟悉应用这些算法的常规做法,所以也许你可以通过某种方式减少一些步骤,并且仍然能够“接近”中位数以确保良好的转向,并且这种方法可以更好地使用5元素块?
答案 0 :(得分:9)
原因是通过选择3的块,我们可能会失去使用O(n)时间算法的保证。
对于5个块,时间复杂度为
T(n)= T(n / 5)+ T(7n / 10)+ O(n)
对于3块,它出来是
T(n)= T(n / 3)+ T(2n / 3)+ O(n)
检查出来:http://www.cs.berkeley.edu/~luca/w4231/fall99/slides/l3.pdf
答案 1 :(得分:5)
我认为这与确保“好”分裂有关。划分为5个元素块可确保70-30的最坏情况分割。标准参数如下:在n/5
块中,至少有一半的中位数> =中位数的中位数,因此至少有一半的n/5
块具有至少3个元素(1/2的1/2)> =中位数的中位数,这给出3n/10
分裂,这意味着在最坏的情况下其他分区是7n/10
。
这给了T(n) = T(n/5) + T(7n/10) + O(n)
。
自n/5 + 7n/10 < 1
起,最坏情况下的运行时间为 O(n)。
选择3个元素的块因此:至少有一半n/3
块具有至少2个元素&gt; =中位数中位数,因此这会产生n/3
分割,或{ {1}}在最坏的情况下。
这给了2n/3
。
在这种情况下,T(n) = T(n/3) + T(2n/3) + O(n)
,在最坏的情况下,它会减少到 O(n log n)。
答案 2 :(得分:4)
您可以使用3号块!是的,我和你一样惊讶。在2014年(你在2010年问过),有一篇文章说明了如何做到这一点。
这个想法如下:不是median3
,partition
,median3
,partition
,......,而是median3
,{{ 1}},median3
,partition
,median3
,median3
,....在论文中,这被称为&#34;重复步算法&#34;。
所以而不是:
partition
一个人得到:
T(n) <= T(n/3) + T(2n/3) + O(n)
T(n) = O(nlogn)
上述文章由K. Chen和A. Dumitrescu(2014,arxiv)撰写Select with Groups of 3 or 4 Takes Linear Time,或Select with groups of 3 or 4(2015年,作者的主页)。
PS:A。Alexandrescu的Fast Deterministic Selection(D语言成名!),它展示了如何更有效地实现上述目标。