Rogue Wave バナー
前へマニュアルの先頭へ目次索引次へ

7.3 プログラム例: 基数ソート

基数ソートアルゴリズムは、list および deque の他のコンテナとの組み合わせの良い例です。基数ソートでは、dequevector がハッシュテーブルのように操作されます。


注: 完全な基数ソートプログラムは radix.cpp ファイルにあります。

基数ソートは、正の整数値リストの順序付けを行う手法です。値は、桁位置を右から左へと順に並べられます。これは、ソートされた桁位置によってバケットのインデックスが指定される場合、値をバケットに挿入することで実行することができます。すべての桁位置が検証されると、リストが必ずソートされます。

表 11 に、624 852 426 987 269 146 415 301 730 78 593 というリストのソートで実行された 4 つのステップの間に、各バケットで検出された値のシーケンスを示します。パス 1 では、1 の桁が順序付けられます。パス 2 では、前のパスで設定された相対位置を保持しながら、10 の桁が順序付けられます。パス 3 では、再び前のパスで設定された相対位置を保持しながら、100 の桁が順序付けられます。3 つのパスの結果が、順序付けられたリストとなります。

表 11 -- 基数ソートによる各バケットの値のシーケンス

バケット パス 1 パス 2 パス 3
0
730
301
78
1
301
415
146
2
852
624, 426
269
3
593
730
301
4
624
146
415, 426
5
415
852
593
6
426, 146
269
624
7
987
78
730
8
78
987
852
9
269
593
987

基数ソートのアルゴリズムは単純です。while ループは、さまざまなパスで循環させるために使用されます。変数 divisor の値は、現在検証されている桁を示します。ブール型のフラグは実行の停止を指定するために使用されます。while ループが実行されるたびに、dequevector が宣言されます。while ループ内にこの構造の宣言を配置することによって、各ステップを空にするために再初期化が行われます。ループが実行されるたびに、各値に対して関数 copyIntoBuckets() を実行することによって、list の値が適切なバケットにコピーされます。値は一度バケットに分散され、蓄積によって list に戻されます。

ここでの関数 accumulate() の使用は、通常とは多少異なります。作成されるスカラー値が list そのものとなります。蓄積の初期値は、list の先頭を示す反復子です。各バケットは、次の 2 項関数で処理されます。

ここで残った唯一の問題は、関数 copyIntoBuckets() の定義です。ここでの問題は、挿入される要素だけを関数の引数としなくてはならないことですが、同時に bucketsdivisorflag の 3 つの値へアクセスする必要があります。他の関数内での関数の定義を許可する言語では、解が while ループ内の局所関数として copyIntoBuckets() に定義されます。しかし、C++ には、このような機能はありません。代わりに、適切な値への参照で初期化できるように、クラス定義を作成する必要があります。このクラスの括弧演算子は、基数ソートプログラムでの関数 for_each() 呼び出しとして使用されるようになります。



前へマニュアルの先頭へ目次索引次へ
Copyright (c) 1998, Rogue Wave Software, Inc.
このマニュアルに関する誤りのご指摘やご質問は、電子メールにてお送りください。
OEM リリース, 1998 年 6 月