Временная сложность операций 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).