【发布时间】:2011-03-07 00:53:11
【问题描述】:
【问题讨论】:
标签: java algorithm complexity-theory treeset
【问题讨论】:
标签: java algorithm complexity-theory treeset
实际上,我原以为这些操作都将是O(logN) 用于一般实现。
为了使first() 和last() 成为O(1),TreeSet 实现需要分别维护一个指向树中最左边和最右边叶子节点的指针。维护这些会增加每次插入的恒定成本,并且至少会增加每次删除的恒定成本。实际上,该实现可能会即时找到最左边/最右边的节点......这是一个O(logN) 操作。
lower() 和 higher() 方法必须与 get 完成相同的工作,因此是 O(logN)。
当然,您可以自己检查源代码以了解实际发生的情况。 (正如其他人所做的那样:见下文。)
【讨论】:
TreeMap.get[First|Last|Lower|Higher]Entry() 中。全部遍历树以找到节点,因此 Stephen C 是正确的,O(log N)。
根据 TreeSet 默认使用的 TreeMap 的 Implentation(sun jdk 1.6.0_23),first() 和 last() 看起来都是 O(log n) 而不是 O(1):
/**
* Returns the first Entry in the TreeMap (according to the TreeMap's
* key-sort function). Returns null if the TreeMap is empty.
*/
final Entry<K,V> getFirstEntry() {
Entry<K,V> p = root;
if (p != null)
while (p.left != null)
p = p.left;
return p;
}
/**
* Returns the last Entry in the TreeMap (according to the TreeMap's
* key-sort function). Returns null if the TreeMap is empty.
*/
final Entry<K,V> getLastEntry() {
Entry<K,V> p = root;
if (p != null)
while (p.right != null)
p = p.right;
return p;
}
【讨论】:
其实我查了源代码, 在http://developer.classpath.org/doc/java/util/TreeSet-source.html 中,first() 调用 maps.firstKey() 然后在 http://developer.classpath.org/doc/java/util/TreeMap-source.html
393: public K firstKey()
394: (
395: if (root == nil)
396: throw new NoSuchElementException();
397: return firstNode().key;
398: )
在 firstNode() 中,它执行 while 循环一直到左侧
952: final Node<K, V> firstNode()
953: (
954: // Exploit fact that nil.left == nil.
955: Node node = root;
956: while (node.left != nil)
957: node = node.left;
958: return node;
959: )
【讨论】:
这将取决于实施。我对 JAVA 不是很熟悉,但似乎所有这些操作都是遍历操作(获取最低元素,获取最高元素,获取下一个更高或下一个更低的元素)。
如果 Tree 实现为 Self-Balancing Binary Search Tree(如 AVL Tree)或任何其他类型的平衡树结构,您将看到平均情况和最坏情况 O(log n)每个操作的时间,以及 O(1) 的最佳情况。
【讨论】:
API 不做任何保证,因为这些都是基于 trie 的标准模型。最好的情况是 O(1),平均情况是 O(log n),最坏的情况是 O(n)。
来自文档:
此实现为基本操作(添加、删除和包含)提供有保证的 log(n) 时间成本。
这些不是您要求的函数,但请考虑一下 Java 将如何遍历 TreeSet。
【讨论】: