我正在阅读有关通过ardendertat median-of-medians
算法找到数组中第k个最高元素的文章。在解释复杂性的部分中,作者似乎已经忽略了一个因素,即递归地为每个分区找到median-of-medians
的成本。当然我不能通过初始支点对所有子阵列进行分区,对吧?那么这不会增加复杂性吗?
答案 0 :(得分:2)
中值中值算法是为快速选择算法开发的,它与快速排序非常相似,但实际上是线性而不是O(n log n),因为它只在分区的一侧进行递归。选择问题是选择集合S中的k th 最大元素;找到中位数是特殊情况,其中k =(| S | + 1)/ 2。
算法很简单:
选择一些透视值,p。
将元素分为两组:S &lt; (所有元素&lt; p)和S ≥(所有元素≥p)。< / p>
递归:如果S &lt; 至少为k,则在S &lt; 中找到k th 最大元素;否则,在S ≥中找到(k - | S &lt; |) th 最大元素。
与quicksort一样,关键是找到透视值。我们将按如下方式进行:
构造S medians ,由每组五个元素的中间人组成。
通过递归调用select来找到S medians 的确切中位数。
现在,| S medians |正好是0.2 * | S |。此外,一旦我们有了支点,我们就知道max(| S &lt; |,| S ≥)≤0.7* | S |。 [fn 1]所以这两个递归调用选择总和为0.9 * | S |。
因此,我们现在可以证明计算选择的时间与Σ0.9 i n成正比,这在n中是明显线性的。
我希望这对你来说足够清晰。
如果不明显,S medians 中的一半中位数必须至少为p(因为p是它们的中位数),并且对于那些对应于这些中位数的每组五个,三个五个元素(中位数和两个较大元素)必须至少为p。因此,这是S中50%的总元素的60%,即30%。类似的论证适用于“至多”代替“至少”,因此我们知道两个子集中较小的一个至少是S大小的30%,因此较大的子集最多为该大小的70%。
答案 1 :(得分:1)
分区数组后中位数中位数p
介于0.3*n
和0.7*n
之间。
所以在一轮之后,我们有三种可能性:
p == n-k
,幸运的是,第一个支点是k
个最大的元素,在O(n)中找到(中位数和分区的中位数都是O(n))。 p > n-k
,然后第k
个最大元素小于第一个数据透视图,我们需要找到第一部分的k - (n-p)
个最大元素,它最多包含0.7*n
个元素,因此找到k
个最大元素的总成本是
T(n) <= T(0.7*n) + C*n
p < n-k
,然后我们需要找到第二部分的第k
个最大元素(在数据透视之后),该部分最多也是0.7*n
个元素,所以我们再次估算
T(n) <= T(0.7*n) + C*n
迭代,我们找到了
T(n) <= T((0.7)^k * n) + C*(1 + 0.7 + ... + (0.7)^(k-1))*n
<= T(1) + C/(1 - 0.7)*n
显然是O(n)。