web-dev-qa-db-ja.com

std :: setの繰り返し順序は、C ++仕様に従って常に昇順ですか?

ここで http://www.cplusplus.com/reference/stl/set/ C++のstd :: setは「通常」ツリー(赤黒のもの)として実装されていると読みました。ソートされます。

私は理解できませんでした、それは仕様によってセットの反復順序が常に昇順であることを意味しますか?または、「通常の実装の詳細」だけであり、場合によっては、一部のライブラリ/コンパイラがこの規則に違反する可能性がありますか?

32

C++標準に従って、_std::set_内の要素の反復は、_std::less_またはオプションの比較述語テンプレート引数によって決定されたソート順に進みます。

(また、C++標準では、挿入、ルックアップ、および削除にかかる時間はせいぜいO(lg n)であるため、_std::set_の実行可能な実装の選択肢は、バランスの取れた検索ツリーだけです。赤黒木の使用は標準では義務付けられていません。)

45
Fred Foo

内部的にstd::setはその要素をソートされたツリーとして保存することを意味します。ただし、仕様にはソート順については何も記載されていません。デフォルトでは、std::setstd::lessを使用するため、低から高の順に並べられます。ただし、次のテンプレートパラメータを使用して、並べ替え機能を自由に設定できます。

std::set<valueType, comparissonStruct> myCustomOrderedSet;

たとえば、次のとおりです。

std::set<int, std::greater<int> > myInverseSortedSet;

または

struct cmpStruct {
  bool operator() (int const & lhs, int const & rhs) const
  {
    return lhs > rhs;
  }
};

std::set<int, cmpStruct > myInverseSortedSet;

実際、これらの例は、リンクしたWebサイトでも提供されています。より具体的には: set constructor

21
Darhuuk

デフォルトのコンパレータは少ないため、セットは昇順で並べられます。これを変更するには、別の既存のコンパレータまたはカスタムコンパレータをテンプレート引数として指定できます。

3
Marian Petre

C++ 11 N3337標準ドラフト

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf

23.2.4「連想コンテナ」には次のように書かれています。

1連想コンテナは、キーに基づいたデータの高速検索を提供します。このライブラリは、セット、マルチセット、マップ、マルチマップの4種類の基本的な連想コンテナを提供します。

そして:

10連想コンテナのイテレータの基本的なプロパティは、コンテナの作成に使用された比較によって非降順が定義されているキーの非降順でコンテナを反復処理することです。

soyes、C++標準により順序が保証されます。

これが、たとえばgcc 6.4.0がハッシュマップの代わりにBSTとして実装する理由です。 C++で設定されたSTLの基礎となるデータ構造は何ですか?

これを、C++ 11 unordered_setと比較してください。C++ 11は、以下に示すように、より制限された(自由にソートされたトラバーサルがない)代償を払って、ハッシュマップ実装でより良いパフォーマンスを提供する傾向があります:

仕様により、セットの反復順序は常に昇順です

はい。setの値は、順番に印刷すると常に昇順になります。説明にあるように、通常はRed-Black Tree(RBT)を使用して実装されますが、コンパイラの作成者はこれに違反するオプションがありますが、他の実装は達成するのにリソース効率がよくないため、通常はRBTのテーマに固執しますsetのタスク。

2
Shamim Hafiz