Search code examples
c++arraysalgorithmsortingcounting-sort

Decrementing counts of elements in counting sort algorithm


I implemented a counting sort algorithm from pseudocode. In the pseudocode the final loop decrements C[A[j]] after the first pass. This was shifting everything to the right so I debugged and decremented before the first pass to produce the correct results. But I cannot see the reason besides that it works, why I must decrement before and not after.

Here is the result when I decrement after:

10 1 0 6 8 3 2 0 9 4 
0 0 0 1 2 3 4 6 8 9 

And when I decrement before:

10 1 0 6 8 3 2 0 9 4 
0 0 1 2 3 4 6 8 9 10

Obviously since everything was shifted right initially I moved everything left one, but why wouldn't it be in the correct alignment in the first place?

int* counting_sort(int A[], int size, int k)
{
    int* B = new int[size];
    int* C = new int[k+1];
    for(int i = 0; i <= k; i++)
        C[i] = 0;
    for(int j = 0; j < size; j++) {
        C[A[j]]++;
    }
    for(int i = 1; i <= k; i++) {
        C[i] += C[i-1];
    }
    //print(C,k+1);
    for(int j = size-1; j >= 0; j--) {
        B[--C[A[j]]] = A[j];
    }
    delete [] C;
    return B;
}

Solution

  • for(int j = size-1; j >= 0; j--) {
        B[--C[A[j]]] = A[j];
    }
    

    is equivalent to:

    for(int j = size-1; j >= 0; j--) {
        int element = A[j];
        int pos = C[element] - 1; 
        B[pos] = element;
        C[element]--;
    }
    

    Imagine array 1 0 1. Now counts of elements would be following:
    0 - 1 time
    1 - 2 times

    The preparation of positions increments counts by the amount of elements that precede them:
    0 - 1
    1 - 3

    Position of elements in new (sorted) array is now (count - 1):
    position of 0 = 1 - 1 = 0
    position of first 1 = 3 - 1 = 2
    position of second 1 = 2 - 1 = 1

    making it 0 1 1.