Временная сложность операций TreeMap-subMap, headMap, tailMap
кто - нибудь знает временную сложность операций TreeMap, таких как-subMap, headMap. tailMap.
временная сложность операций, таких как get, put, равна O(logn). Но javadoc не говорит много о сложности для вышеуказанных операций.
худший случай сложности я могу думать о O (n), так как он будет проходить через весь список, если набор включает последний элемент. Мы можем это подтвердить?
2 ответов
для тех вопросов, имеющих исходный код под рукой очень полезно, как с достаточной поддержкой IDE вы можете просто просмотреть реализацию. При взгляде на исходный код TreeMap видно, что все три метода построить новую карту, с помощью конструктор AscendingSubMap:
public NavigableMap<K,V> subMap(K fromKey, boolean fromInclusive,
K toKey, boolean toInclusive) {
return new AscendingSubMap(this,
false, fromKey, fromInclusive,
false, toKey, toInclusive);
}
который больше ничего не делает, чтобы передать параметры с помощью супер конструктора классу NavigableSubMap
:
super(m, fromStart, lo, loInclusive, toEnd, hi, hiInclusive);
таким образом, все три метода основаны на следующем конструкторе:
NavigableSubMap(TreeMap<K,V> m,
boolean fromStart, K lo, boolean loInclusive,
boolean toEnd, K hi, boolean hiInclusive) {
if (!fromStart && !toEnd) {
if (m.compare(lo, hi) > 0)
throw new IllegalArgumentException("fromKey > toKey");
} else {
if (!fromStart) // type check
m.compare(lo, lo);
if (!toEnd)
m.compare(hi, hi);
}
this.m = m;
this.fromStart = fromStart;
this.lo = lo;
this.loInclusive = loInclusive;
this.toEnd = toEnd;
this.hi = hi;
this.hiInclusive = hiInclusive;
}
все, что я вижу здесь-это обращения к compare
по причинам проверки типа и утверждения. Следовательно, это должно быть в значительной степени O (1).
вы всегда можете просмотр исходного кода в интернете, но я действительно рекомендую получить исходные файлы и связать их с вашей IDE по выбору.
я смог просмотреть источник TreeMap чтобы получить подробную реализацию.
Если вы подробно расскажете об исходном коде о том, как они на самом деле получают подкарту, это что-то вроде этого...
Если вы видите метод размера NavigableSubMap
public int size() {
return (fromStart && toEnd) ? m.size() : entrySet().size();
}
реализация entrySet () в нескольких вызовах final вызывает функцию getCeilingEntry ()
final Entry<K,V> getCeilingEntry(K key) {
Entry<K,V> p = root;
while (p != null) {
int cmp = compare(key, p.key);
if (cmp < 0) {
if (p.left != null)
p = p.left;
else
return p;
} else if (cmp > 0) {
if (p.right != null) {
p = p.right;
} else {
Entry<K,V> parent = p.parent;
Entry<K,V> ch = p;
while (parent != null && ch == parent.right) {
ch = parent;
parent = parent.parent;
}
return parent;
}
} else
return p;
}
return null;
}
поэтому я думаю, чтобы получить фактическую карту из созданной submap; временная сложность больше, чем O(1).