很容易看出深度优先搜索的时间复杂度为O(|V|)
但是,最近,我读了一本书说:
如果在树上执行此过程,那么从
开始,系统地会在O(|E|)
|E| = Theta(|V|)
时间内系统地访问所有树顶点
我无法理解O(Theta(|V|))
。
O(|V|)
和O(Theta(|V|))
之间的区别是什么?
答案 0 :(得分:2)
答案简短:
O(|E|)
表示它在时间上与边缘量成线性关系。|E| = Theta(|V|)
表示|E| in Theta(|V|)
,因为O(.)
,Theta(.)
,...是集合。计算机科学家很懒,有时写=
而不是in
。知道这意味着边缘量与节点数成线性关系。O(|V|)
表示它与节点数量成线性关系。O(Theta(|V|))
是一个毫无意义的陈述。 O(.)
需要一个函数,而不是一个集合,而Theta(.)
是一个集合。f in O(g)
给你一个上限,比如“ f优于g(或同样好)”。
n in O(n^2)
。f in Omega(g)
给你一个下限,比如“ f并不比g(或同样好)”。
n^2 in Omega(n)
。f in Theta(g)
表示两者都有,“ f与g 有些相同”。
2n + 4 in Theta(n)
,因为2n + 4 in O(n)
和2n + 4 in Omega(n)
。small o
和small omega
通过严格的比较{{1}来交换<=
的{{1}}和Big-O
>=
}和Big-Omega
,所以“或同样好的”会被删除。我把所有内容都放在引号中,因为它完全取决于Big-O-Notation的含义,所以“相同的”就渐近增长而言。
确切的定义可以在Wikipedia找到。
我们现在接近您的具体方案。在树中,边的数量总是由顶点的数量限定。因为一个节点最多可以有一个边到父节点,一个节点到每个子节点。例如,它不能有同一个孩子的多个边缘。
顺便说一下,树中确切的边数始终是<
。因为每个节点(来自父节点)只有一条边,不包括根。
所以我们有>
,因为在Big-O-Notation(渐近增长)方面,它们是“相同的”。因此,|E| = |V| - 1
中运行的每个树算法都可以看作是在|E| in Theta(|V|)
中运行。
实际上,许多算法都在O(|E|)
中运行,而不仅仅在O(|V|)
中运行,但大多数时候只有Theta(.)
很有意思,所以他们只剩下剩余的算法了。在分析问题时,O(.)
或O(.)
更常见。例如,可以证明任何可能的基于比较的排序算法都不能快于Omega(.)
(search query to find the proof)。
答案 1 :(得分:0)
如果f(n)= O(g(n)),则存在const c和n 0,如果n> = n 0,0 <= f(n)<= c * g(n)
例如,如果时间复杂度为3n,那么它属于级别 上)。此外,如果复杂度为3,则它仍然属于O(n)。
Theta(n)表示时间复杂度大于n,但低于O(n), 在这种情况下,我们称之为theta(n)