【发布时间】:2016-12-10 19:56:20
【问题描述】:
深度优先树遍历示例:
class Node:
def __init__(self, value):
self._value = value
self._children = []
def add_child(self, child):
self._children.append(child)
def __iter__(self):
return iter(self._children)
def depth_first(self):
yield self
for c in self:
yield from c.depth_first()
我知道yield from 不会立即使用生成器,而是将yield 向上传递给它的调用者。
但是这个传递的过程还是存在的,所以yield会从每个节点一直传递到它的根节点,我们可以用递归来描述运行时间(假设为简单起见是二叉树,但思路是一样的):
T(n) = 2*T(n/2) + Θ(n)
Θ(n) 存在是因为该节点必须将所有从其后代传递的yield 传递给其父节点。而由上式推导出的时间复杂度为:
O(nlogn)
但是,如果我根本不使用yield 或yield from,树遍历的时间复杂度只有O(n)。
我想知道我是否误解了yield 的工作原理,或者编写这样的递归生成器根本不可行。
【问题讨论】:
-
公式中的 Θ(n) 不应该是 Θ(1) 吗?平衡树中节点的后代数不是常数吗?
-
@DYZ 我认为应该是 Θ(n)。它不传递后代的数量,而是传递其所有后代的
yield语句。 -
“所有的后代”是否包括后代的后代等? (我假设它没有。)如果不是,它仍然是一个常数。
-
@DYZ 它确实包括后代的后代,因为每个节点都会做两件事:(1)将自己屈服于其调用者(2)产生其后代以及其后代产生的后代的后代对它等等......
-
哦,你是对的。那么它确实是 O(n log n),因为你本质上将遍历结果委托给了根节点,而不是在本地使用它们。
标签: python time-complexity yield