我知道基本操作的时间复杂度,例如add,get是O(logn)。但我没有找到lower()和更高()的细节。那么,Java中的TreeSet的lower()和更高()的时间复杂度是多少?
答案 0 :(得分:5)
TreeSet由名为TreeMap的NavigableMap实现支持。在TreeSet上计算lower()时最终调用的代码是TreeMap上的lowerEntry()。
/**
* Returns the entry for the greatest key less than the specified key; if
* no such entry exists (i.e., the least key in the Tree is greater than
* the specified key), returns {@code null}.
*/
final Entry<K,V> getLowerEntry(K key) {
Entry<K,V> p = root;
while (p != null) {
int cmp = compare(key, p.key);
if (cmp > 0) {
if (p.right != null)
p = p.right;
else
return p;
} else {
if (p.left != null) {
p = p.left;
} else {
Entry<K,V> parent = p.parent;
Entry<K,V> ch = p;
while (parent != null && ch == parent.left) {
ch = parent;
parent = parent.parent;
}
return parent;
}
}
}
return null;
}
查看此代码,看起来与while循环的每次迭代一样,每个分支返回或遍历树的一个级别。由于树形图应具有log(n)
级别,因此整个方法的复杂度为O(log(n))
。
答案 1 :(得分:0)
与get()
,O(log n)相同。
lower()
或higher()
执行get()
;然后再次执行get()
以查找下一个(更低或更高)节点。由于像2这样的常量会从big-O表示法中删除,所以它再次只是O(log n)。
答案 2 :(得分:0)
它没有在文档中指定,但实现 - 至少对于OpenJDK 8 - 是O(log n)。
TreeSet使用TreeMap进行操作(将set的元素存储为map的键),特别是lower()delegates straight to TreeMap::lowerKey(m
字段被输入为NavigableMap,但是如果你看一下构造函数,你会看到它总是TreeMap。)
TreeMap::lowerKey实际上归结为对getLowerEntry的调用,该调用从根开始,然后找到适当的条目;这是任何二叉搜索树中的O(log n)(例如TreeMap使用的红黑树)。
TreeSet :: higher()使用类似的委托,并具有相同的性能特征。
答案 3 :(得分:0)
在Java TreeSet和TreeMap中是一个红黑(平衡)二叉搜索树(BST)。当您正在搜索(方法:lower()
和higher()
实际上正在搜索)时,红黑BST时间复杂度将为2 log N.
因此两种方法的时间复杂度为O(log N)。