Implementing Radix sort recursively - how to print the elements at the end?

2.8k Views Asked by At

Note:

I already asked a specific question on this programm before, but now I'm stuck at the very last step and I guess it might be better to open a new thread for it.

Description:

I'm required to implement a programm that sorts numbers ranging from 0 to 99999 recursively (this is basically Radix sort). The process itself is kinda simpel: The user types in an array that contains those numbers in the main method. Then, the main method calls for the sort-method where I create a two-dimensional array named 'space' with 10 rows and 1 column. Then, I divide every number in the array by the digit, which would be 10.000 in the first run. So, for example, 23456 / 10000 = 2,3456 = 2 (in java), hence, the programm puts this number in space[2][0], so in the second row. Then, we take this entire row and extend it, which is done in the putInBucket-method. We do this in order to make sure that we can put another number into the same row.

We do this for every number that is inside the 'numbers'-array. Then, we want to work with these rows and sort them again by the same principle, but now we take a look at the second digit. We want to do this from left to right, not from right to left. So, if our second row would look like this

[23456, 24567],

we'd want to compare the 3 and the 4. In order to do so, we calculate digit / 10 in each recursive call. If the digit is 0, there is nothing to sort anymore.

The recursive call itself works with the rows from 0 to 9 where we put in the different numbers before and now sorts them again by putting them in different rows.

Question:

I think the programm does what it is supposed to do. Unfortunately, I don't know how to print the result properly. For example, in the code below, I tried to print out the bucket in the main method, but it only gives me exactly the array that I just typed in, so that can't be right.

I need to start with all the elements in the row 9, and if this row contains more than one number, I'd have to sort them by the results I got in the recursive call.

Does anyone have an idea how to implement this properly? Thanks in advance!

public static int[] sort(int[] numbers, int digit) {

  if (numbers.length <= 1 || digits == 0)
    return numbers;

  int[][]space = new int[10][1];
  int i, j = 0;

  for (j = 0; j < numbers.length; j++) {
    i = numbers[j] / digit % 10;
    space[i][0] = numbers[j];
    space[i] = putInBucket(space[i], numbers[j]);
  }

  digit = digit / 10;

  for (i = 0; i < 9; i++) {
    sort(space[i], digit); 
  }

  return numbers

}

private static int[] putInBucket(int[] bucket, int number) {

  int[] bucket_new = new int[bucket.length+1];

  for (int i = 1; i < bucket_new.length; i++) {
    bucket_new[i] = bucket[i-1];
  }

  return bucket_new;

}

public static void main (String [] argv) {

  int[] numbers = IO.readInts("Numbers: ");
  int digit = 10000;
  int[] bucket = sort(numbers, digit); 

  for (int i = 0; i < bucket.length; i++) {
    System.out.println(bucket[i]);

}
2

There are 2 best solutions below

2
On BEST ANSWER

As I demonstrated in my answer to your previous question, you need to return the sorted numbers. You get the sorted numbers by going through space from the smallest to the largest digits.

  int k = 0;

  for (i = 0; i < 10; i++) {
      for (j = 0; j < len[i]; j++) {
          numbers[k] = space[i][j];
          k++;
      }
  }

For that, you would probably need to keep track of the lengths of the buckets for each digit (the len[i] variable).

The full solution would be:

public static int[] sort(int[] numbers, int digit) {

     if (numbers.length == 0 || digit <= 0)
           return numbers;

     int[][]space = new int[10][1];
     int[] len = new int[10];
     int i, j = 0;

      for (j = 0; j < numbers.length; j++) {
            i = (numbers[j] / digit) % 10;
            len[i]++;
            space[i] = putInBucket(space[i], numbers[j]);
      }


      for (i = 0; i < 10; i++) {
          int[] bucket = new int[len[i]];
          for (int k = 0; k < len[i]; k++) 
              bucket[k] = space[i][k];
          space[i] = sort(bucket, digit / 10); 
      }

      int k = 0;

      for (i = 0; i < 10; i++) {
          for (j = 0; j < len[i]; j++) {
              numbers[k] = space[i][j];
              k++;
          }
      }

      return numbers; 

}

private static int[] putInBucket(int[] bucket, int number) {

    int[] bucket_new = new int[bucket.length+1];


    for (int i = 1; i < bucket_new.length; i++) {
        bucket_new[i] = bucket[i-1];
    }
    bucket_new[0] = number;

    return bucket_new;

}
5
On

In sort, the local instance of space is being updated, but it's returning the input parameter numbers, which isn't being updated.

I'm thinking space should be initialized as space[10][0], since it possible that one more rows of space won't have any data.

Are you sure this is supposed to be a right to left (least significant digit first) radix sort? Normally that's done via iteration (just copy space back into numbers on each outer loop). Radix sort left to right (most significant digit first) is often done using recursion.

Bijay Gurung's sort() can be somewhat simplified. Changes noted in comments:

public static int[] sort(int[] numbers, int digit) {
    if (numbers.length == 0 || digit <= 0)
        return numbers;
    int[][]space = new int[10][0];  // [1] => [0]
    int[] len = new int[10];
    int i, j;
    for (j = 0; j < numbers.length; j++) {
        i = (numbers[j] / digit) % 10;
        len[i]++;
        space[i] = putInBucket(space[i], numbers[j]);
    }
    for (i = 0; i < 10; i++) {
    //  int[] bucket = new int[len[i]];        // deleted
    //  for (int k = 0; k < len[i]; k++)       // deleted
    //      bucket[k] = space[i][k];           // deleted
        space[i] = sort(space[i], digit / 10); // bucket => space[i]
    }
    int k = 0;
    for (i = 0; i < 10; i++) {
        for (j = 0; j < len[i]; j++) {
            numbers[k] = space[i][j];
            k++;
       }
    }
    return numbers; 
}