所以我有一个问题,这个方法应该通过使用计数排序对整数数组进行排序。问题是结果数组有一个额外的元素,零。如果原始数组的元素为零(或几个),那么它很好,但如果原始数组没有任何零元素,则结果从零开始。
e.g。 int input[] = { 2, 1, 4 };
结果 - > Sorted Array : [0, 1, 2, 4]
为什么会这样?
public class CauntingSort {
public static int max(int[] A)
{
int maxValue = A[0];
for(int i = 0; i < A.length; i++)
if(maxValue < A[i])
maxValue = A[i];
return maxValue;
}
public static int[] createCountersArray(int[] A)
{
int maxValue = max(A) + 1;
int[] Result = new int[A.length + 1];
int[] Count = new int[maxValue];
for (int i = 0; i < A.length; i++) {
int x = Count[A[i]];
x++;
Count[A[i]] = x;
}
for (int i = 1; i < Count.length; i++) {
Count[i] = Count[i] + Count[i - 1];
}
for (int i = A.length -1; i >= 0; i--) {
int x = Count[A[i]];
Result[x] = A[i];
x--;
Count[A[i]] = x;
}
return Result;
}
}
答案 0 :(得分:0)
int maxValue = max(A) + 1;
返回A + 1的最高值,因此具有new int [maxValue]的新数组的大小为5;
数组结果的长度为A.lenght + 1,即4 + 1 = 5;
第一个0是int的预定值,如果它是? extends Object它将为null。
答案 1 :(得分:0)
您正在使用int[] Result = new int[A.length + 1];
,这使得数组的位置更大。但是如果你避免使用它,你就会遇到IndexOutOfBounds
异常,因为在使用x--
访问数组之前你应该x
,所以你的代码应该改变类似于:
public static int[] createCountersArray(int[] A)
{
int maxValue = max(A) + 1;
int[] Result = new int[A.length];
int[] Count = new int[maxValue];
for (int i = 0; i < A.length; i++) {
int x = Count[A[i]];
x++;
Count[A[i]] = x;
}
for (int i = 1; i < Count.length; i++) {
Count[i] = Count[i] + Count[i - 1];
}
for (int i = A.length -1; i >= 0; i--) {
int x = Count[A[i]];
x--;
Result[x] = A[i];
Count[A[i]] = x;
}
return Result;
}
在这里:tio.run
答案 2 :(得分:0)
结果中的前导0是实例化数组时分配给该元素的初始值。永远不会修改该初始值,因为填充结果的循环仅写入与正累积计数相对应的元素。
例如,考虑对单元素数组进行排序。该元素的Count
将为1,因此您将在结果数组的索引1处写入元素的值,而保持索引0不变。
基本上,这是一个一个一个错误。您可以通过更改
来修复它Result[x] = A[i];
到
Result[x - 1] = A[i];
但是,这里的部分问题是例程中的错误部分难以跟踪或分析(对于人类而言)。毫无疑问,它相对有效;尽管如此,快速,破碎的代码并不比缓慢的工作代码更好。这是一个更容易推理的替代方案:
int nextResult = 0;
for (int i = 0; i < Count.length; i++) {
for (int j = 0; j < Count[i]; j++) {
Result[nextResult] = i;
nextResult++;
}
}
当然,您还希望避免声明Result
数组大于数组A
。