我一直在用Python解决图形问题,并使用set()来存储已经访问过的节点,以防止陷入循环。然而,我见过用C++/Java编写代码的人使用向量或数组来存储访问计数。我想知道哪种方法在Python中更有效,或者一般来说在时间和空间复杂性方面更有效。
例如,考虑到我们已经知道节点的索引:
visited = [0] * V # space = O(V)
if not visited[node] # takes Time = O(1)
个字符
但是根据这个答案Time complexity of python set operations?有时候set()复杂度可以是O(N)。那么,使用数组更好吗?
3条答案
按热度按时间uoifb46i1#
Python中的List是C中数组的一个很好的替代品,list甚至比数组更好地存储数据。考虑使用list而不是set,因为我已经看到在python中使用list是多么的通用,因为list是可变的,并且为了让代码不断添加图中的访问元素,我想使用list是一个不错的选择。快乐的编码!
kxxlusnw2#
你不能总是在两者之间做出选择。
如果
node
是一个范围很小的无符号整数,那么将其用作列表索引将是更好的选择:在这种情况下,您不需要hashmap的逻辑(set
的底层技术),因为不需要冲突管理:该索引唯一地标识列表中的条目。一旦分配了列表(即O(𝑛)),获取和设置的相关操作都是O(1)。如果
node
不符合这个条件,并且node
不能被Map到这样一个小的无符号整数(injective mapping的运行时间为O(1)),那么列表的选择就逐渐消失了。node
不能再用作索引。当然,您仍然可以将node
(作为值)* 追加到动态列表中,但这样in
操作的复杂度就会降低到O(𝑛)。这不是你想要的在这种情况下,使用
set
是正确的选择。例如,如果您使用OOP方法,则node
将是某个Node
类的示例,具有其键、标签和邻居的属性。除非有办法将这些node
对象Map到小的无符号整数,否则它们不能用作列表索引,而set
将是一个逻辑选择。关于集合上运算的复杂性:在实际情况中,你可以假设获取和设置的摊销时间复杂度为O(1)。冲突会使复杂性降低到O(𝑛)are rare的情况。
w6lpcovy3#
抛出大O值很有趣,也很容易。但是在某些时候,有必要坐下来编写一些代码,这样您就可以对实际的实现进行时序测试。
代码,用于比较使用向量和集合跟踪访问过的顶点的C++实现。
字符串
结果:
型
注:在使用不同随机种子的多次运行中,这些结果一致
结论:
向量实作比使用集合快约三倍。