我们知道合并排序具有以下算法的时间复杂度O(nlogn):
void mergesort(n elements) {
mergesort(left half); ------------ (1)
mergesort(right half); ------------(2)
merge(left half, right half);
以下实施的时间复杂性是什么?
(1)
void mergesort(n elements) {
mergesort(first quarter); ------------ (1)
mergesort(remaining three quarters); ------------(2)
merge(first quarter, remaining three quarters);
(2)
void mergesort(n elements) {
mergesort(first quarter); ------------ (1)
mergesort(second quarter); ------------(2)
mergesort(third quarter); ------------ (3)
mergesort(fourth quarter); ------------(4)
merge(first quarter, second quarter,third quarter, fourth quarter);
请详细说明如何找到复杂性。
答案 0 :(得分:3)
仍为O(n log n),因为n = log n / log 4的log base 4,最终为常量。
[编辑]
合并排序算法与k分割的恢复关系如下。我假设合并k个排序的数组总共n个元素花费n log2(k),log2代表log base 2。
T(1) = 0
T(n) = n log2(k) + k T(n/k)
我可以将恢复关系解决为:
T(n) = n log2(n)
无论k的值如何。
答案 1 :(得分:3)
请注意,这不是您问题的准确答案,而是一个提示。
首先,我们需要了解默认合并排序的时间复杂度是n(log n)。
如果我们有8个元素并且默认使用mergesort方法,如果我们每次将它们分成一半直到我们到达只包含一个元素的组,那么我们将需要3个步骤。
所以这意味着在N个元素上调用mergersort 3次。这就是为什么时间复杂度是3 * 8,即(log N)* N
如果您要将默认分区从一半更改为其他比例,则必须计算您到达1个元素组所需的步数。
另请注意,此答案仅旨在解释如何计算复杂性。所有分区方法的大O复杂度是相同的,如果以有效的方式实现其他2分区将具有N(logN)的精确复杂度
答案 2 :(得分:2)
您发布的所有三种算法都是O(n log n),只是略有不同的常数。
基本思想是它需要log(n)次传递,并且在每次传递中你都会检查n个项目。分区的大小并不重要,事实上,您可以使用不同大小的分区。它始终适用于O(n log n)。
运行时差异将在merge
方法中。合并排序列表是O(n log k)操作,其中n是要合并的项目总数,k是列表数。因此,合并两个列表的是n * log(2)
,这适用于n
(因为log2(2) == 1
)。
有关详细信息,请参阅我对How to sort K sorted arrays, with MERGE SORT的回答。