いつどちらを選ぶべきですか?適切なSTLコンテナーを使用するために推奨するポインターはありますか?
hash_set
は、C++標準の一部ではない拡張機能です。ルックアップはset
のO(log n)ではなくO(1)にする必要があります。そのため、ほとんどの状況でより高速になります。
コンテナーを反復処理すると、別の違いが見られます。 set
はコンテンツをソート順に配信しますが、hash_set
は基本的にランダムです(Lou Francoに感謝)。
編集:C++標準へのC++ 11の更新が導入されました unordered_set
hash_set
ではなく推奨されます。パフォーマンスは類似しており、規格によって保証されています。名前の「順不同」は、それを反復すると特定の順序で結果が生成されないことを強調しています。
stl::set
は、バイナリ検索ツリーとして実装されます。 hashset
はハッシュテーブルとして実装されます。
ここでの主な問題は、多くの人々がstl::set
それはO(1)のルックアップを持つハッシュテーブルであると考えていますが、そうではありません。本当にO(log(n))ルックアップ用です。それ以外は、バイナリツリーとハッシュテーブルを読んで、データ構造をよりよく理解してください。
もう1つ覚えておかなければならないのは、hash_setではハッシュ関数を指定する必要があるのに対し、セットには比較関数( '<')のみが必要であり、定義が簡単である(ネイティブ型に対して事前定義されている)ことです。
Hash_setは、ほとんどO(1)演算)を持つハッシュテーブルによって実装されますが、セットは、ある種のツリー(AVL、赤黒など)によって実装されます。 O(log n)操作ですが、並べ替えられています。
編集:私は木はO(n)であると書いていた。それは完全に間違っています。
質問の他の部分にはまだ誰も回答していないと思います。
Hash_setまたはunordered_setを使用する理由は、通常O(1)ルックアップ時間です。実装によっては、ハッシュをより大きなハッシュ配列にコピーする必要がある場合があるため、 、またはハッシュバケットに何千ものエントリが含まれる場合があります。
セットを使用する理由は、セットの最大または最小のメンバーが必要な場合が多いためです。ハッシュには順序がないため、最小のアイテムをすばやく見つける方法はありません。ツリーには順序があるため、最大または最小は非常に高速です。単純なツリーのO(log n)、O(1)それが最後へのポインタを保持している場合。