【发布时间】:2021-04-12 22:09:26
【问题描述】:
正在学习归并排序算法,发现归并排序的时间复杂度为O(n log n)。
想知道我们是否可以说O(n log n) = O(n) * O(log n)?
【问题讨论】:
标签: time-complexity big-o mergesort
正在学习归并排序算法,发现归并排序的时间复杂度为O(n log n)。
想知道我们是否可以说O(n log n) = O(n) * O(log n)?
【问题讨论】:
标签: time-complexity big-o mergesort
不,这样做没有任何意义。 Big-O 函数产生函数集合,集合不能相乘。
更一般地说,您通常不会对 O(...) 结果执行任何操作。没有加法、减法、乘法。没有代数。 O(...) 通常出现在证明的结论中:“根据上面的分析,我得出结论,Finkle 算法的最坏情况复杂度是 O(whatever)。” t 真的出现在可能对其进行代数操作的中间。
(我想你可以执行集合操作。我从未见过有人这样做。)
【讨论】:
其实Big-o的定义是不可交换的,看例子:
让 f 定义为 f(n) = n
f(n) = O(n^2) & f(n) = O(n^3),但是 O(n^2) != O(n^3)
那是因为使用 equal sign = 在这里没有准确定义,我们应该说 f(n) is O(g)。
总之有点不准确,下面是 sipser 抓取的 Big-O 的定义:
说 f (n) = O(g(n))
如果存在正整数 c 和 n 0 使得对于每个整数 n ≥ n0, f (n) ≤ c g(n)。
当 f (n) = O(g(n)) 时,我们说 g(n) 是 当 f (n) = O(g(n)) 时,我们说 g(n) 是 f (n),或者更准确地说,g(n) 是一个渐近上界 f (n),强调我们正在抑制常数因子。
因此,为了证明您所说的,您必须首先定义 * 在您的等式中的含义。并显示每个 O(n log n) 的函数,它也是 O(n) * O(log n),反之亦然。
但是再次不准确并将 * 定义为符号多项式乘法,对于某些常数正 c 和 d,我们有以下内容。
O(n log n) = O(cn log n) = O(log n ^ (cn)) = O(d log n^(cn)) = O(log (n^cn) ^ d) = O(log n^cdn) ~= log n ^ cdn ~= cdn * log n
= O(n) * O(log n) = O(cn) * O(d log n) = O(cn) * O(log n^d) ~= cn * (log n^d) ~ = cn * d*logn ~= cdn * log n
【讨论】:
为了正式定义O(n) * O(log n) 的含义,我们来做如下定义:
一个函数
f在O(n) * O(log n)中当且仅当它可以写成一个产品f(n) = g(n) h(n),其中g在O(n)中并且h在O(log n)中。
现在我们可以证明集合O(n) * O(log n)等于集合O(n log n),通过证明两个集合中的函数是相同的:
g in O(n) 和h in O(log n),有N_g, c_g, N_h, c_h 这样对于所有n >= max(N_g, N_h) 和@98765433434 |h(n)| <= c_h log n。由此可见|g(n) h(n)| <= c_g c_h n log n,因此max(N_g, N_h) 和c_g c_h 足以证明f 在O(n log n) 中。O(n log n) 中给定f,则有N_f >= 1、c_f,这样|f(n)| <= c_f n log n 对应于所有n >= N_f。定义g(n) = max(1, n)和h(n) = f(n) / max(1, n);显然g 在O(n) 中,我们还可以看到对于n >= N_f,我们有|h(n)| <= c_f n log n / max(1, n),其中右侧的边界等于c_f log n,因为n >= 1,所以N_f,@ 987654362@ 足以表明h 在O(log n) 中。由于我们有f(n) = g(n) h(n),因此f 在我们定义的O(n) * O(log n) 中。N_f >= 1和g(n) = max(1, n)的选择是为了避免n为零时被零除。
【讨论】: