c++sortingradix-sort

Redix sort issue


I have a task of making radix sort without 2d array or list "from scratch".

This is my code that works fine... untill you introduce numbers with 4 mor more digits.

int* radix( int n, int* a, int k) {

int m=10,temp;
int count[10],dest[n],*b=a;

for(int i=0;i<k;i++){
    for(int j=0;j<m;j++)   {count[j]=0;}
    for(int j=0; j<n;j++) {count[((b[j]%((int)pow(10,i+1)))-(b[j]%((int)pow(10,i))))/(int)pow(10,i)]++;}
    for(int j=m-1;j>=0;j--) {
        temp=0;
        for(int l=0;l<j;l++)     {temp+=count[l];}
        count[j]=temp;
    }

    for(int j=0; j<n;j++){
        temp=((b[j]%((int)pow(10,i+1)))-(b[j]%((int)pow(10,i))))/(int)pow(10,i);
        dest[count[temp]]=b[j];
        count[temp]++;
    }

    for(int j=0;j<n;j++){ b[j]=dest[j];}
    for(int j=0;j<n;j++){ cout<<b[j]<<' ';}
    cout<<endl<<endl;
}



return b;

}

error occurs at dest[count[temp]]=b[j]; near the end. I suspect that problems arise becose of relativly complex radix isolation.

I am too stuck in my head and dont see a possible solution.Plese help!


Solution

  • I changed the code to allocate dest[], but otherwise it seems to be working as is, with Visual Studio. Note that the code would require modification to work with negative elements. For example, if range is -9999 to +9999, then add 9999 to all elements, treat the elements as unsigned integers, and do one more radix sort pass for the most significant digit (0 or 1). Subtract 9999 from all elements after radix sort is done.

    void radix( int n, int* a, int k)
    {
    int m=10,temp;
    int count[10], *b=a;
    int *dest = new int[n];
    
      for (int i = 0; i < k; i++) {
        for (int j = 0; j < m; j++) { count[j] = 0; }
        for (int j = 0; j < n; j++) { count[((b[j] % ((int)pow(10, i + 1))) - (b[j] % ((int)pow(10, i)))) / (int)pow(10, i)]++; }
        for (int j = m - 1; j >= 0; j--) {
            temp = 0;
            for (int l = 0; l < j; l++) { temp += count[l]; }
            count[j] = temp;
        }
    
        for (int j = 0; j < n; j++) {
            temp = ((b[j] % ((int)pow(10, i + 1))) - (b[j] % ((int)pow(10, i)))) / (int)pow(10, i);
            dest[count[temp]] = b[j];
            count[temp]++;
        }
    
        for (int j = 0; j < n; j++) { b[j] = dest[j]; }
      }
      delete[] dest;
    }
    

    Classic implementation:

    void radix(int n, int* a, int k)
    {
        int cnt[11];                        // size is +1
        int i,j;
        int p=1;                            // powers of 10
        unsigned *src = (unsigned *)a;      // source = a
        unsigned *dst = new unsigned[n];    // allocate dest array
        for(i=0; i<k; i++){
            for(j=0; j<11; j++)             // clear cnt[]
                cnt[j]=0;
            for(j=0; j<n; j++)              // set counts
                cnt[1+(src[j]/p)%10]++;     //  at (1+digit)
            for(j=2; j<10; j++)             // convert counts to indexes
                cnt[j] += cnt[j-1];
            for(j=0; j<n; j++)              // radix sort pass
                dst[cnt[(src[j]/p)%10]++] = src[j];
            p *= 10;                        // setup for next digit
            std::swap(src, dst);            // swap src, dst
        }
        if(k&1){                            // if odd number of passes
            for(j=0; j<n; j++)              //  copy src to dst
                dst[j] = src[j];
            std::swap(src, dst);            //  swap src, dst
        }
        delete [] dst;
    }