递归地实现Radix排序 - 如何在结尾打印元素?

时间:2016-12-25 18:28:11

标签: java arrays sorting recursion radix-sort

注意:

我已经在这个程序before上问了一个具体的问题,但现在我陷入了最后一步,我想最好为它打开一个新线程。

说明

我需要实现一个程序,以递归方式对0到99999之间的数字进行排序(这基本上是Radix排序)。该过程本身有点简单:用户键入一个包含main方法中的数字的数组。然后,main方法调用sort-method,我在其中创建一个名为'space'的二维数组,其中包含10行和1列。然后,我将数组中的每个数字除以数字,在第一次运行中为10.000。因此,例如,23456/10000 = 2,3456 = 2(在java中),因此,程序将此数字放在空格[2] [0]中,因此在第二行中。然后,我们取整行并扩展它,这是在putInBucket方法中完成的。我们这样做是为了确保我们可以将另一个数字放入同一行。

我们对'numbers'数组中的每个数字执行此操作。然后,我们想要使用这些行并按照相同的原则再次对它们进行排序,但现在我们来看看第二个数字。我们想要从左到右,而不是从右到左。所以,如果我们的第二行看起来像这样

[23456,24567],

我们想要比较3和4.为了做到这一点,我们在每次递归调用中计算数字/ 10。如果数字为0,则无需再排序。

递归调用本身适用于从0到9的行,我们在此之前输入不同的数字,现在将它们放在不同的行中再次对它们进行排序。

问题:

我认为该程序可以完成它应该做的事情。不幸的是,我不知道如何正确打印结果。例如,在下面的代码中,我尝试在main方法中打印出存储桶,但它只给出了我刚刚输入的数组,因此不能正确。

我需要从第9行中的所有元素开始,如果这行包含多个数字,我必须按照递归调用中的结果对它们进行排序。

有没有人知道如何正确实现这一点?提前谢谢!

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 个答案:

答案 0 :(得分:2)

在sort中,正在更新本地空间实例,但它正在返回未更新的输入参数编号。

我认为空间应该初始化为空间[10] [0],因为可能还有一行空间没有任何数据。

你确定这应该是一个向右(最低位数字)基数排序的权利吗?通常这是通过迭代完成的(只需将空间复制回每个外环上的数字)。基数从左到右排序(最重要的数字首先)通常使用递归完成。

Bijay Gurung的排序()可以稍微简化一下。评论中注明的变化:

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; 
}

答案 1 :(得分:1)

正如我在answer中向您之前提出的问题所示,您需要返回已排序的numbers。您可以通过space从最小到最大的数字来获得已排序的数字。

  int k = 0;

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

为此,您可能需要跟踪每个数字(len[i]变量)的桶的长度。

完整的解决方案是:

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;

}