0

I was given a problem for one of my CS courses where I have to program a LSD radix sort that can sort unsigned integers (+ or -). It is given that the values to be sorted are 32-bit integer values.

The stipulation is that my mask must be a constant value, which is where my question lies. If I am doing an & bitwise operation on a 32-bit integer where each digit is represented by 4 bits (hexadecimal representation) should my mask be 28? (since I would like there to be 28 bits of 1's in binary)

Also if anyone could notices any additional errors, could you please bring attention to them?

#define BITS_PER_PASS 4
#define NUM_PASSES 8
#define NUM_BUCKETS 16
#define MASK 28

int *buckets[NUM_BUCKETS];
int bucket_sizes[NUM_BUCKETS];

void radix_sort( int *values, int n )
{
    int i, j;
    int bucket_index;
    int *p;

    for( i=0; i < NUM_PASSES; i++ )
    {
        for( j=0; j < NUM_BUCKETS; j++ )
        {
            bucket_sizes[j]=0;
        }

        for( j=0; j < n; j++ )
        {
            bucket_index = (values[j] & MASK) >> BITS_PER_PASS*i; //QUESTION
            buckets[j][ bucket_sizes[bucket_index]]=values[j];
            bucket_sizes[bucket_index]++;
        }

        p = values;

        for( j=0; j < NUM_BUCKETS; j++ )
        {
            memcpy((void *)p, (void *)buckets[j], sizeof(int)*bucket_sizes[j]);
            p+=bucket_sizes[j];
        }
    }
}

I would also like to add that all of the defined constants and global variables are mandatory since I was told to use these in my radix sort.

  • 1
    When sorting by nibbles (4 bit values), the mask should be 0xf, but applied after you shift right. bucket_index = (values[j] >> (BITS_PER_PASS*i))&0xf; – rcgldr Oct 24 '15 at 23:49
  • You could also define MASK as ((1< – rcgldr Oct 25 '15 at 00:04
  • this line: `int *buckets[NUM_BUCKETS];` is declaring an array of 16 pointers to integers. defining pointers not where the pointers point. Since this line is in the `file global` space (which is auto initialized to all 0x00), the result is an array of 16 pointers that all contain NULL. – user3629249 Oct 25 '15 at 00:11
  • continued: This line: `buckets[j][ bucket_sizes[bucket_index]]=values[j];` is 1) selecting a null pointer, 2) (not correctly) indexing off where that pointer points (I.E. some index off address 0.) Then write a value to some small offset from address 0. Overall, probably not what you want and almost certain to cause a seg fault event at run time. – user3629249 Oct 25 '15 at 00:13

2 Answers2

1

instead of this:

int *buckets[NUM_BUCKETS];
int bucket_sizes[NUM_BUCKETS];
...
buckets[j][ bucket_sizes[bucket_index]]=values[j];

suggest:

int buckets[NUM_BUCKETS];
int bucket_size[NUM_BUCKETS];
...
buckets[bucket_size[bucket_index]]=values[j];

regarding these lines:

bucket_index = (values[j] & MASK) >> BITS_PER_PASS*i;

I would expect something that extracts 4 bits, something like:

bucket_index = (values[j] >> BITS_PER_PASS*i) & MASK;

where MASK would be 0x0F, because trying to select one of 16 different 'buckets' ( where &0x0F will result in a value in the range 0...15)

user3629249
  • 16,402
  • 1
  • 16
  • 17
  • Thank you very much! This makes a lot of sense and solves my issue. I tried up voting but my account is too new to make it rampant. – Erich Hauck Oct 26 '15 at 18:21
  • You should be able to 'accept' my answer to your question, even with little to no 'reputation'. – user3629249 Oct 27 '15 at 21:25
0

I see you're using an array called bucket_sizes[NUM_BUCKETS] and array of pointers. These could be declared inside the sort function. For 32 bit unsigned integers, NUM_BUCKETS = 32/BITS_PER_PASS.

You also need a second buffer to hold the sorted values, for example, buffer = malloc(n * sizeof(unsigned int); Don't forget to free(buffer) when the sort is done.

The array of pointers should be set as buckets[0] = buffer, buckets[1] = buffer + bucket_sizes[0], buckets[2] = buffer + bucket_sizes[0] + bucket_sizes[1], ... . You can use a local variable to keep track of the sums of bucket sizes. Note that the last bucket_sizes[15] is not used to set the array of pointers.

After each pass swap buffer and values (treating them as pointers). Since it's an even number of passes, (8), the sorted data will end up back in values.

rcgldr
  • 27,407
  • 3
  • 36
  • 61