2013-02-07 7 views
7

TreeSetの部分ビューのsize()の時間の複雑さは何ですか?JavaのTreeSet部分ビューのsize()の複雑さは何ですか?

レッツは、私が設定するための乱数を追加している(と私はduplicities気にしない)と言う:

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()通話のための複雑さが何であるかをwoderingだ:

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()); 
     } 
    } 

AFAIK複雑度tree.headSet(t),tree.tailSet(f)およびtree.subSet(f, t)はO(1g N)であり、set.size()はO(1)であるが、上記の方法は約size()である。私は、Kが選択されたサブセットのサイズであるO(K)というような悪い気持ちを持っています。

もし私がti = indexOf(f)を得ることができれば、それは正確に私が必要とするものよりもO(lg N)を言うことができるので、それは十分であろうセット内のある要素のインデックスを見つけるための回避策があるかもしれません。

答えて

9

それは(OracleのJDK 1.7.0_13)このように実装されているTreeMap.NavigableSubMap.EntrySetView.size()を呼ぶ可能性があるためsize()の複雑さは、O(N)あるように見える:

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; 
} 
+0

あなたは一つのことを明確にしてくださいもらえますか? メソッドiterator()は、実際にはO(log N)のツリーのイテレータ<>を返します。それは、基準(fromStart()/ toEnd())によってツリーの一部だけに触れます。 私が理解しているように、headSet()が作成されているとき、実際には要素のセットは作成されません。これは、基準を持つラッパーを作成するだけです。 私は間違っていますか?おかげさまで –

+0

私はしばらくしてその質問に戻りました...あなたは正しいです - それはラッパーを作成しますが、反復( 'while'ループ)はサイズKのサブセットについてはまだO(K)です。 – Betlista

関連する問題