web-dev-qa-db-ja.com

C ++ STLのセットとハッシュセットの違いは何ですか?

いつどちらを選ぶべきですか?適切なSTLコンテナーを使用するために推奨するポインターはありますか?

24
kal

hash_setは、C++標準の一部ではない拡張機能です。ルックアップはsetのO(log n)ではなくO(1)にする必要があります。そのため、ほとんどの状況でより高速になります。

コンテナーを反復処理すると、別の違いが見られます。 setはコンテンツをソート順に配信しますが、hash_setは基本的にランダムです(Lou Francoに感謝)。

編集:C++標準へのC++ 11の更新が導入されました unordered_sethash_setではなく推奨されます。パフォーマンスは類似しており、規格によって保証されています。名前の「順不同」は、それを反復すると特定の順序で結果が生成されないことを強調しています。

33
Mark Ransom

stl::setは、バイナリ検索ツリーとして実装されます。 hashsetはハッシュテーブルとして実装されます。

ここでの主な問題は、多くの人々がstl::setそれはO(1)のルックアップを持つハッシュテーブルであると考えていますが、そうではありません。本当にO(log(n))ルックアップ用です。それ以外は、バイナリツリーとハッシュテーブルを読んで、データ構造をよりよく理解してください。

15
Alex

もう1つ覚えておかなければならないのは、hash_setではハッシュ関数を指定する必要があるのに対し、セットには比較関数( '<')のみが必要であり、定義が簡単である(ネイティブ型に対して事前定義されている)ことです。

3
ronys

Hash_setは、ほとんどO(1)演算)を持つハッシュテーブルによって実装されますが、セットは、ある種のツリー(AVL、赤黒など)によって実装されます。 O(log n)操作ですが、並べ替えられています。

編集:私は木はO(n)であると書いていた。それは完全に間違っています。

1
Alex Gaynor

質問の他の部分にはまだ誰も回答していないと思います。

Hash_setまたはunordered_setを使用する理由は、通常O(1)ルックアップ時間です。実装によっては、ハッシュをより大きなハッシュ配列にコピーする必要がある場合があるため、 、またはハッシュバケットに何千ものエントリが含まれる場合があります。

セットを使用する理由は、セットの最大または最小のメンバーが必要な場合が多いためです。ハッシュには順序がないため、最小のアイテムをすばやく見つける方法はありません。ツリーには順序があるため、最大または最小は非常に高速です。単純なツリーのO(log n)、O(1)それが最後へのポインタを保持している場合。

1
Zan Lynx