【问题标题】:Implementing Radix sort recursively - how to print the elements at the end?递归实现基数排序 - 如何在最后打印元素?
【发布时间】:2016-12-25 18:28:10
【问题描述】:

注意:

我已经在这个程序before 上提出了一个具体问题,但现在我被困在最后一步,我想为它打开一个新线程可能会更好。

说明:

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

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

[23456, 24567],

我们想要比较 3 和 4。为此,我们在每个递归调用中计算 digit / 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]);

}

【问题讨论】:

    标签: java arrays sorting recursion radix-sort


    【解决方案1】:

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

    我在想空间应该被初始化为空间[10][0],因为多行空间可能没有任何数据。

    您确定这应该是从右到左(最低有效位在前)的基数排序吗?通常这是通过迭代完成的(只需将空间复制回每个外循环上的数字)。基数排序从左到右(最高有效位在前)通常使用递归完成。

    Bijay Gurung 的 sort() 可以稍微简化。 cmets 中记录的更改:

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

    【讨论】:

    • sort 不能是 void 方法,这是他们希望我们这样做的方式。
    • 另外,将空间初始化为 space[10][0] 会给我一个 ArrayOutOfBoundsException。
    • @Julian - putinbucket 需要修复。将 bucket 复制到 bucket.new(可能是零个元素),然后将 number 附加到 bucket_new。如果是从左到右,那么第一级应该是使用digit/10000,下一级是(digit/1000)%10,以此类推。
    • 像 Bijay 实现的那样?
    • 非常感谢!我很感激。 :-)
    【解决方案2】:

    正如我在 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;
    
    }
    

    【讨论】:

    • 非常感谢您的努力! :-)
    • 这对我来说也很有成果。我的(错误的)假设是多维数组的行是固定的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-03
    • 2017-05-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多