TreeMap操作的时间复杂度--subMap,headMap,tailMap

时间:2013-01-12 06:04:55

标签: java list treemap

有没有人知道TreeMap操作的时间复杂度,如 - subMap,headMap。的tailMap。

get,put等操作的时间复杂度为O(logn)。 但是javadoc并没有说明上述操作的复杂性。

最糟糕的情况复杂性我可以想到O(n),因为如果集合包含最后一个元素,它将遍历整个列表。 我们可以证实吗?

2 个答案:

答案 0 :(得分:12)

对于那些拥有源代码的问题非常有用,因为有足够的IDE支持,您只需浏览实现即可。在查看TreeMap的源代码时,可以看到,所有三种方法都使用constructor of 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)

您可以随时browse the source code online,但我真的建议您获取源文件并将其链接到您选择的IDE。

答案 1 :(得分:2)

我能够浏览TreeMap的来源以获得详细的实施。

如果你详细了解它们如何实际获得subMap的源代码,那就是这样......

如果您看到NavigableSubMap的大小方法

  public int size() {
        return (fromStart && toEnd) ? m.size() : entrySet().size();
    }

多次调用中的entrySet()实现最终调用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;
}

我想从创建的子图中获取实际的地图;时间复杂度大于O(1)。