31項 ソートの選択肢を知っておこう

ソートの選択肢を知っておこう



partial_sortは、比較関数によってソートされたN個の要素をコンテナの先頭に配置します。

bool qualityCompare(const Widget &lhs, const Widget &rhs)
{
    ...    //lhsの品質がrhsより高いかどうかを返す
}
...

partial_sort( widgets.begin(),      //widgetsの先頭から順番に
              widgets.begin() + 20, //20個の最高品質の
              widgets.end(),        //要素を入れる
              qualityCompare );

nth_elementは、比較関数によって得られるN個の要素を、順序を規定せずコンテナの先頭に配置します。

nth_element(  widgets.begin(),      //widgetsの先頭から順番を気にせず
              widgets.begin() + 20, //20個の最高品質の
              widgets.end(),        //要素を入れる
              qualityCompare );

通常のsort、partial_sort、nth_elementは不安定です。不安定というのは、等価な値を持つ要素の並び順が決まっていないということです。


安定的(等価な値を持つ要素の並び順は格納されていた順番になる)なソートを行うときは、stable_sortを使います。


条件に合うものをすべて先頭に持ってくるには、partitionを使います。

bool hasAcceptableQuality(const Widget &lhs, const Widget &rhs)
{
    ...    //条件に合うかかどうかを返す
}
...

vector<Widget>::iterator goodEnd = 
    partition( widgets.begin(),       //hasAcceptableQualityを満たす要素を先頭に移動
               widgets.end(),         //戻り値は、hasAcceptableQualityを満たさない最初の要素への反復子
               hasAcceptableQuality); 

partitionは不安定です。partition_stableは安定的なので、等価な要素の位置関係を保持します。


sort、stable_sort、partical_sort、nth_elementの各アルゴリズムランダムアクセス反復子を必要とするため、vector、string、deque、配列にしか使えません。
listをソートするときは、list::sortを使います。list::sortは安定的です。
listにpartical_sortやnth_elementを使いたいときは、listのデータをランダムアクセス反復子を持つコンテナに移動してからアルゴリズムを使う方法、list::iteratorのコンテナにアルゴリズムを使ったあと反復子でアクセスする方法、ソートされた反復子のコンテナでlistの要素を希望する位置にspliceする方法などがあります。
partitionとstable_partitionはすべての標準シーケンスコンテナで使用できます。