【问题标题】:What is complexity of size() for TreeSet portion view in JavaJava 中 TreeSet 部分视图的 size() 复杂度是多少
【发布时间】:2013-02-07 11:46:43
【问题描述】:

我想知道 TreeSet 的部分视图 size() 的时间复杂度是多少。

假设我要添加随机数来设置(而且我不关心重复):

    final TreeSet<Integer> tree = new TreeSet<Integer>();
    final Random r = new Random();
    final int N = 1000;
    for ( int i = 0; i < N; i++ ) {
        tree.add( r.nextInt() );
    }

现在我想知道size() 调用的复杂性是:

    final int M = 100;
    for ( int i = 0; i < M; i++ ) {
        final int f = r.nextInt();
        final int t = r.nextInt();
        System.out.println( tree.headSet( t ).size() );
        System.out.println( tree.tailSet( f ).size() );
        if ( f > t ) {
            System.out.println( tree.subSet( t, f ).size() );
        } else {
            System.out.println( tree.subSet( f, t ).size() );
        }
    }

tree.headSet( t )tree.tailSet( f )tree.subSet( f, t ) 的 AFAIK 复杂度是 O(lg N),set.size() 是 O(1),但是上面的 size() 方法呢?我有一种糟糕的感觉,它是 O(K),其中 K 是所选子集的大小。

也许如果有一些解决方法可以找到集合中某个元素的索引就足够了,因为如果我能得到ti = indexOf(f),假设 O(lg N) 比这正是我所需要的。

【问题讨论】:

    标签: java complexity-theory treeset


    【解决方案1】:

    看起来size () 的复杂度是O(N),因为它可能会调用TreeMap.NavigableSubMap.EntrySetView.size (),它是这样实现的(Oracle JDK 1.7.0_13):

    public int size() {
        if (fromStart && toEnd)
            return m.size();
        if (size == -1 || sizeModCount != m.modCount) {
            sizeModCount = m.modCount;
            size = 0;
            Iterator i = iterator();
            while (i.hasNext()) {
                size++;
                i.next();
            }
        }
        return size;
    }
    

    【讨论】:

    • 你能澄清一件事吗?方法 iterator() 实际上会返回树的 Iterator,它是 O(log N)。它只会按标准(fromStart()/toEnd())触及树的一部分。据我了解,在创建 headSet() 时,它实际上并没有创建一组元素。它只是创建一个带有标准的包装器。我错了吗?谢谢。
    • 一段时间后我回到了那个问题......你是对的 - 它只创建一个包装器,但是对于大小 K 的子集,迭代(while 循环)仍然是 O(K)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-26
    • 1970-01-01
    • 2013-12-14
    • 2011-03-24
    • 1970-01-01
    • 2012-02-13
    相关资源
    最近更新 更多