我试图澄清一些关于TreeSet的一些操作的复杂性的事情。在javadoc上它说:
“此实现提供 保证log(n)的时间成本 基本操作(添加,删除和 包含)。“
到目前为止一切顺利。我的问题是在addAll(),removeAll()等上发生了什么。这里的Set的javadoc说:
“如果指定的集合也是 设置,有效的addAll操作 修改此设置以使其值为 两套联盟。“
它只是解释操作的逻辑结果还是提示复杂性?我的意思是,如果这两组由例如红黑树,以某种方式加入树木比将“添加”彼此的每个元素更好。
在任何情况下,有没有办法将两个TreeSet合并为一个具有O(logn)复杂度的TreeSet?
提前谢谢你。 : - )
答案 0 :(得分:7)
您可以想象如何将特殊情况优化到O(log n)
,但最糟糕的情况必须是O(m log n)
,其中m
和n
是数字每棵树中的元素。
编辑:
http://net.pku.edu.cn/~course/cs101/resource/Intro2Algorithm/book6/chap14.htm
描述了一个可以在O(log(m + n))
中加入树的特殊情况算法,但请注意限制:S1
的所有成员必须少于S2
的所有成员。这就是我的意思,对特殊情况有特殊的优化。
答案 1 :(得分:3)
查看TreeSet的java源代码,看起来如果传入的集合是SortedSet,那么它使用O(n)时间算法。否则它调用super.addAll,我猜这将导致O(n logn)。
编辑 - 猜测我读得的代码太快,如果支持地图为空,TreeSet只能使用O(n)算法
答案 2 :(得分:1)
根据这篇博客文章:
http://rgrig.blogspot.com/2008/06/java-api-complexity-guarantees.html
它是O(n log n)。由于文档没有提供有关复杂性的提示,因此如果性能对您至关重要,您可能需要编写自己的算法。
答案 3 :(得分:0)
不可能像在Disjoint-set数据结构中那样执行树的合并或连接集,因为您不知道2树中的元素是否是不相交的。由于数据结构具有其他树中内容的知识,因此有必要在添加到另一个树之前检查另一个树中是否存在一个元素,或者至少尝试将其添加到另一个树中,如果找到它则中止添加它方式。 所以,它应该是O(MlogN)