なぜこれが私にとって頭を包むのがとても難しいのか分かりません。 Wikiページ、および(バケットに関して)基数ソートアルゴリズムがどのように機能するかを理解しようとする擬似コード(および実際のコード)を調べました。
ここで間違ったことを調べていますか?バケットの並べ替えを検討する必要がありますか?誰かが私にそれがどのように機能するかについての馬鹿げたバージョンを教えてもらえますか?参考のために、推定が基数ソートを実行するコードブロックを次に示します。
// Sort 'size' number of integers starting at 'input' according to the 'digit'th digit
// For the parameter 'digit', 0 denotes the least significant digit and increases as significance does
void radixSort(int* input, int size, int digit)
{
if (size == 0)
return;
int[10] buckets; // assuming decimal numbers
// Sort the array in place while keeping track of bucket starting indices.
// If bucket[i] is meant to be empty (no numbers with i at the specified digit),
// then let bucket[i+1] = bucket[i]
for (int i = 0; i < 10; ++i)
{
radixSort(input + buckets[i], buckets[i+1] - buckets[i], digit+1);
}
}
また、非再帰的なソリューションも見てきました。
void radixsort(int *a, int arraySize)
{
int i, bucket[sortsize], maxVal = 0, digitPosition =1 ;
for(i = 0; i < arraySize; i++) {
if(a[i] > maxVal) maxVal = a[i];
}
int pass = 1;
while(maxVal/digitPosition > 0) {
// reset counter
int digitCount[10] = {0};
// count pos-th digits (keys)
for(i = 0; i < arraySize; i++)
digitCount[a[i]/digitPosition%10]++;
// accumulated count
for(i = 1; i < 10; i++)
digitCount[i] += digitCount[i-1];
// To keep the order, start from back side
for(i = arraySize - 1; i >= 0; i--)
bucket[--digitCount[a[i]/digitPosition%10]] = a[i];
for(i = 0; i < arraySize; i++)
a[i] = bucket[i];
cout << "pass #" << pass++ << ": ";
digitPosition *= 10;
}
}
特に、この行は私にトラブルを与えています。私はペンと紙でそれを歩いてみましたが、これが何をしているのかまだわかりません:
// To keep the order, start from back side
for(i = arraySize - 1; i >= 0; i--)
bucket[--digitCount[a[i]/digitPosition%10]] = a[i];
数学では、基数は10進数が10を基数とする基数を意味します。
5, 213, 55, 21, 2334, 31, 20, 430
簡単にするために、ソートに10進数(= 10)を使用するとします。次に、番号を単位で分けてから、それらを再び組み合わせます。次に、数を10で区切り、それらを再び組み合わせます。その後、すべての数字が並べ替えられるまで、数百ずつ続けます。ループするたびに、リストを左から右に読むだけです。数字をバケットに分割していることも想像できます。これは5, 213, 55, 21, 2334, 31, 20, 430
を使用した図です
単位で区切る:
ゼロ:20、430
1:21、31
2つ:
スリー:213
fours:2334
ファイブ:5、55
一緒に戻る:20、430、21、31、213、2334、5、55
それらを元に戻すには、最初にzeroes
バケットを読み、次にones
バケットを読み、それからnines
バケットを読むまで続けます。
10で区切る:
ゼロ:05
もの:213
2:20、21
threes:430、31、2334、
四つんばい:
ファイブ:55
一緒に戻る:5、213、20、21、430、31、2334、55
数百で区切る:
ゼロ:005、020、021、031、055
もの:
2:213
スリー:2334
fours:430
ファイブ:
一緒に戻る:5、20、21、31、55、213、2334、430
数千で区切る:
ゼロ:0005、0020、0021、0031、0031、0055、0213、0430
もの:
2:2334
スリー:
四つんばい:
ファイブ:
一緒に戻る:5、20、21、31、55、213、430、2334
カードのデッキを考えてください。最初にスーツで4つの山に並べ替えます。次に、これら4つの山を重ねて、ランクに基づいて13個の山に分類します。それらをまとめると、ソートされたデッキができました。
これがクイックソートの基本的な流れです。
1回目のパスの場合:カウントソートを使用して、最下位桁(1の位)に基づいて配列をソートします。元のリストでは435が835未満で発生したため、435が835未満であることに注意してください。
2回目のパス:では、カウントソートを使用して、次の桁(10桁)に基づいて配列をソートします。前のリストでは608が704未満で発生したため、ここでは608が704未満であることに注意してください。(835、435)および(751、453)も同様です。
3番目のパスの場合:カウントソートを使用して、最上位桁(100桁)に基づいて配列をソートします。前のリストでは435が453未満で発生したため、ここでは435が453未満であることに注意してください。(608、690)および(704、751)も同様です。
詳細については、 codingeekでこのブログを参照し、明確に理解することができます 。