为什么不合并排序O(N ^ 2)?请看这个例子

时间:2018-12-12 02:12:49

标签: algorithm mergesort

由16个元素组成的冒泡排序需要15步进行2-2比较,以对它们进行逐一排序。

合并排序首先将它们划分为16个元素,然后每次合并2个元素,但是如果绘制图片,总体步骤仍为15,即8 + 4 + 2 + 1 = 15 在这种情况下,合并成本O(n),而2-2比较成本O(n)则应为O(n ^ 2)。 为什么它是假的?

3 个答案:

答案 0 :(得分:3)

合并排序的时间复杂度为O( n log n )。

通过仔细检查您描述的迭代实现,可以更轻松地确认这一点。该算法扫描列表日志( n )次。在您的示例中,它合并每对,然后每四对,然后每八对,然后全部十六对,合并起来总共进行4 = log 2 (16)次迭代。由于列表本身的长度为 n ,因此总时间复杂度为 n log( n ),可通过计算通过扫描16个项目的列表4次,总共迭代了64个元素。

假设每个合并都以O( n )的时间复杂度执行,则分析中的错误是错误的。合并排序中每个合并的时间复杂度不能用 n 来简单表示。

答案 1 :(得分:0)

我总是发现可视化合并排序的最佳方法是绘制其递归树。

enter image description here

为简单起见,让我们假设我们正在处理一个大小为2的幂的列表。

递归深度

我们应该问的第一个问题是:递归深度是多少?

由于每次递归,归并排序将列表分为两部分,所以递归的数量直到到达基本情况等于n可以除以2的时间。即 log(n) 定义。

在给定深度处的台阶

然后我们计算在给定的递归深度下要合并所有子列表的步骤。

假设我们处于深度 k ,其中 k = 1 是顶层,我们有2 k-1 对子列表大小分别为 n / 2 k 。通过将子列表两两合并,我们需要 2 k-1 *(2 * n / 2 k ,正好是 n 个步骤。

您的错误来自上述步骤,您错误地认为合并总是需要 n 个步骤,而实际上却需要 n / 2 k-1 ,其中 k 是递归深度。

结论

如果我们有 log(n)个递归级别,并且每个递归级别都 n 个步骤,则说明我们有 n个log(n)步骤我们的算法。

结论:合并排序为 O(n log(n))

答案 2 :(得分:-1)

我在声明中注意到了逻辑错误。 2-2个比较步骤并不能单独确定复杂性,当您对1个元素和1个元素进行排序时,只需花费O(1)即可完成,这样的行为中有16个变为o(N),从这个意义上讲,是合并sort的合并次数为logN次,每次合并都需要进行22个比较的步骤,但每次的总体复杂度仍为O(N)。 合并排序的功能在于它分配的额外空间,当为要比较的较小元素数创建新矢量时,它会降低每个较小子集的比较成本。