有人能用英语向我解释Merge Sort是O(n * logn)。我知道'n'来自这样一个事实:它需要附加n合并两个大小为n / 2的排序列表。令我困惑的是日志。如果我们要在32元素列表上绘制运行Merge Sort的函数调用树,那么它将有5个级别。 Log2(32)= 5.这是有道理的,但是,为什么我们使用树的级别,而不是实际的函数调用和Big O定义中的合并? 在这个diagram中我们可以看到,对于8个元素列表,有3个级别。在这种情况下,Big O试图找到操作数量随输入增加的行为,我的问题是(函数调用的)级别如何被视为操作?
答案 0 :(得分:0)
函数调用的级别被认为是这样的(在[算法简介]一书中{({3}}第2.3.2章):
我们建议如下设置T(n)的递归,这是n个数字上合并排序的最坏情况运行时间。仅对一个元素进行合并排序需要恒定的时间。当我们有n> 1个元素,我们按如下方式分解运行时间。
划分:划分步骤只计算子阵列的中间位置,这需要恒定的时间。因此,D(n)=Θ(1)。
征服:我们递归地解决两个子问题,每个子问题大小为n / 2,对运行时间贡献2T(n / 2)。
组合:我们已经注意到n元素子阵列上的MERGE过程需要时间Θ(n),所以C(n)=Θ(n)。
当我们为合并排序分析添加函数D(n)和C(n)时,我们添加一个函数Θ(n)和一个函数Θ(1)。该和是n的线性函数,即Θ(n)。将其添加到“征服”步骤的2T(n / 2)项中,可以得出合并排序的最坏情况运行时间T(n)的重现性:
T(n)=Θ(1),如果n = 1;如果n> 1,则T(n)= 2T(n / 2)+Θ(n)。 1。
然后使用递归树或主定理,我们可以计算:
T(n)=Θ(nlgn)。
答案 1 :(得分:0)
简单分析: - 假设数组的长度是n来排序。 现在每次都会被分成两半。 所以,见下: - ñ n / 2 n / 2 n / 4 n / 4 n / 4 n / 4 ............................ 1 1 1 ......................
正如您所见,树的高度将为logn(2 ^ k = n; k = logn) 在每个级别总和将是n。 (n / 2 + n / 2 = n,n / 4 + n / 4 + n / 4 + n / 4 = n)。
所以最后level = logn,每个级别都需要n 结合我们得到nlogn
现在关于您的问题,如何将级别视为操作,请考虑如下: - 阵列9,5,7 假设它分为9,5和7 对于9,5,它将被转换为5,9(在此级别需要一次交换) 然后在上层5,9和7,而合并转换为5,7,9 (再次在这个级别需要一次交换)。
在最坏的情况下,任何级别的操作都可以是O(N)和logn级别。因此nlogn。
为了更加清晰,尝试编写合并排序,您将能够将其可视化。
答案 2 :(得分:0)
让我们以你的8项数组为例。我们从[5,3,7,8,6,2,1,4]
开始。
如你所说,有三个通行证。在第一遍中,我们合并了1个元素的子阵列。在这种情况下,我们将5与3,7与8,2与6和1与4进行比较。典型的合并排序行为是将项目复制到辅助数组。所以每个项目都被复制;我们只是在必要时改变相邻物品的顺序。第一次传递后,数组为[3,5,7,8,2,6,1,4]
。
在下一次传递中,我们合并了两个元素的序列。因此[3,5]
与[7,8]
合并,[2,6]
与[1,4]
合并。结果是[3,5,7,8,1,2,4,6]
。同样,每个元素都被复制了。
在最后一次传递中,算法再次复制每个项目。
有log(n)次传递,每次传递都会复制所有n个项目。 (当然,也有比较,但数字是线性的,不超过项目数。)无论如何,如果你做n次操作log(n)次,那么算法就是O(n log n) )。