2016-12-30 16 views
0
void countingsort(int arr[], int n, int exp) 
{ 

    int count[10] = {0}; 
    int* output = new int[n]; 
    for (int i = 0; i < n; i++) 
     count[(arr[i]/exp) % 10]++; 
    for (int i = 1; i < 10; i++) 
     count[i] += count[i - 1]; 

    for (int i = n - 1; i >= 0; i--)//Why is array traversed from end? 
    { 
     output[count[(arr[i]/exp) % 10] - 1] = arr[i]; 
     count[(arr[i]/exp) % 10]--; 
    } 
    for (int i = 0; i < n; i++) 
     arr[i] = output[i]; 
} 

void radixsort(int arr[], int n) 
{ 
    int m = getMax(arr, n); 
    for (int exp = 1; m/exp > 0; exp *= 10) 
     countingsort(arr, n, exp); 
} 

カウントソート機能では、なぜカウント配列が最後からトラバースされているのかわかりません。私たちが最初からそれを横断すれば、それはどのような違いになりますか?基数ソート。配列が最後まで横断するのはなぜですか?

+0

何が起こっているかを見るために、逆向きに移動しようとしましたか?また、あなたは恐ろしいメモリリークを持っています。 – DeiDei

+0

ええ、私は逆に横断しました。 countsort関数がexp = 10の2回目に呼び出されると、問題のforループは終了しません。私の価値は決して更新されません、なぜ私は理解しません。そして、はい、私は出力を削除することを忘れていた。 –

+0

各数字 'd'の場合、' count [d] 'は' d番目のバケットの最後の未使用位置を示します(正確には最後の1つです)。それぞれのバケットは右から左に塗りつぶされていて、始まりに終わります(ループの中で、 'count [d]'はインクリメントされるのではなく、どのように減分されるのか注意してください)。そのため、以前に部分的にソートされたデータは、以前に確立された部分的な順序を保持するために、後方に向かって訪問される必要があります。 –

答えて

0

カウントは終了インデックスに変換されるため、配列は後方にトラバースされます。カウントが開始インデックスに変換され、配列が前方に横断される例:

void countingsort(int arr[], int n, int exp) 
{ 
    int count[10] = {0}; 
    int* output = new int[n]; 
    for (int i = 0; i < n; i++) 
     count[(arr[i]/exp) % 10]++; 
    int sum = 0, tmp;    // convert counts to starting indices 
    for (int i = 0; i < 10; i++){ 
     tmp = count[i]; 
     count[i] = sum; 
     sum += tmp; 
    } 

    for (int i = 0; i < n ; i++) // traverse from beginning 
    { 
     output[count[(arr[i]/exp) % 10]] = arr[i]; 
     count[(arr[i]/exp) % 10]++; // -- => ++ 
    } 
    for (int i = 0; i < n; i++) 
     arr[i] = output[i]; 
    delete[] output; 
} 
0

あなたはそれをカウントした後に位置

..., u, ..., v, ..., w, ... 

で発生している特定のキーKのために、あなたはこれらのことを判断すると言います、要素は、位置

..., count[K]-2, count[K]-1, count[K], ... 

に行くと、あなたは順番count[K]に保存し、count[K]-1、は(それがcountingsortへの以前の呼び出しによって確立された順序を、保持する)安定で、ご注文wの要素を格納する必要性を得るために

vu、すなわちトラバースしなければなりません配列を後方に移動します。

+0

しかし、もし私が配列の前方をたどるとどうなりますか?それが以前に確立された注文を妨害する方法は、私が理解しようとしているものです。 –

関連する問題