我正在编写一个比较算法,它将n个数字和一个数字k作为输入。
它将n个数字分成k个组,以便组1中的所有数字都小于组2的所有数字,...,小于组k。
同一组的编号不一定要排序。
我正在使用选择(A [],左,右,k)来找到第k个元素,在我的例子中是n / k元素(将整个数组分成2个)和然后重复每个部分,直到初始数组被分成k个部分的n / k数字。
它的复杂度为Θ(n logk),因为它是logk级别(深度)的树,每个级别的cn计算成本最高。这是线性时间,因为logk被认为是常数。
我被要求证明所有以这种方式将Array [n]排序到k组的比较算法,在最坏的情况下花费Ω(nlogk)。
我在这里搜索过,谷歌和我的算法书(Jon Kleinberg Eva Tardos)我只找到对所有元素进行排序的比较算法的证据。在我的案例中不接受这种算法复杂性的证明,因为所有这些都在不符合我的问题的情况下,也不能被改变以解决我的问题。 (还要考虑随机选择的常规快速排序导致Θ(nlogn)与Ω(nlogk)不是线性的)
您可以在此处找到常规算法证明: https://www.cs.cmu.edu/~avrim/451f11/lectures/lect0913.pdf 它也清楚地解释了为什么我的问题不属于O(nlogn)
的比较排序情况答案 0 :(得分:3)
排序需要进行lg(n!) = Omega(n log n)
次比较,因为n!
个输出排列不同。
对于这个问题,有
n!
-------
k
(n/k)!
输出排列的等价类,因为k
元素的n/k
个独立组中的顺序无关紧要。我们计算
n!
lg ------- = lg (n!) - k lg((n/k)!)
k
(n/k)!
= n lg n - n - k ((n/k) lg (n/k) - n/k) ± O(lg n + k lg (n/k))
(write lg (...!) as a sum, bound with two integrals;
see https://en.wikipedia.org/wiki/Stirling's_approximation)
= n (lg n - lg (n/k)) ± O(lg n + k lg (n/k))
= n lg k ± O(lg n + k lg (n/k))
= Omega(n lg k).
(O(lg n + k lg (n/k)) = O(n), since k <= n)
答案 1 :(得分:0)
证明所有以这种方式将Array [n]排序为k组的比较算法,在最坏的情况下花费Ω(nlogk)。
我认为该陈述是错误的。如果使用具有较差枢轴选择的quickselect(例如始终使用第一个或最后一个元素),那么最坏的情况可能是O(n ^ 2)。
只有一些比较算法会出现O(n log(k))的最坏情况。使用枢轴中位数(n / 5版本)阻止quickselect解决了枢轴问题。还有其他算法也是O(n log(k))。