我正在尝试理解基数排序。特别是,我无法理解基数函数 - 更具体地说,j和k循环。我不确定究竟发生了什么。从我所看到的,似乎j循环正在设置k循环的索引,以用于形成排序的输出数组。如果有人能帮助解释它背后的逻辑,那就太好了!
// RADIX SORT BEGIN //
// Get the maximum value in arr[]
int getMax(int arr[], int size)
{
int max = arr[0]; // Set max to presumably the first one
int i = 1;
while (i < size)
{
if (arr[i] > max) // We have a new max ladies and gents
max = arr[i];
i++;
}
return max;
}
// Do a sort of arr[] based off the digit represented by exp
void radixing(int arr[], int size, int exponent)
{
int output[size];
int count[10] = {0};
// Tally the amount of numbers whose LSB based off current exponent
// is 0-9, represented by each
// index in the array
for (int i = 0; i < size; i++)
count[ (arr[i]/exponent) % 10 ]++;
for (int j = 1; j < 10; j++)
count[ j ] += count [j - 1];
for (int k = size - 1; k >= 0; k--)
{
output[ count[ (arr[k]/exponent) % 10 ] -1 ] = arr[k];
count[ (arr[k]/exponent) % 10 ]--;
}
// Finalize output into the original array
for (int o = 0; o < size; o++)
arr[o] = output[o];
}
// Main radix sort function
void radixsort(int arr[], int size)
{
// Find the max in the array to know the number of digits to traverse
int max = getMax(arr, size);
// Begin radixing by sorting the arr[] based off every digit until max
// Exponent is 10^i where i starts at 0, the current digit number
for (int exponent = 1; (max / exponent) > 0; exponent = exponent * 10)
radixing(arr, size, exponent);
}
// RADIX SORT END //
答案 0 :(得分:2)
我不会分解算法中的每一步,而是告诉你它打算完成什么,你可以用它来理解它是如何工作的。这看起来像是在进行所谓的LSD基数排序。
如果您曾经使用过卡片分类器(现在很难找到),那么它与此算法的作用相同。我们的想法是从最不重要的数字开始,并向最重要的方向努力。卡片分拣机有10个箱子 - 每个数字一个。将选择一个列(指数),卡将落入正确的箱中,具体取决于它对所选列的数字。
算法正在做的是计算给定指数列中每个数字的记录数,然后按顺序输出那么多记录。实际上,它使用计数来计算输出数组中的偏移量。
现在有了给定列(指数)的记录,它会移动到下一个更高的指数。
编辑:点缀一下。
答案 1 :(得分:1)
j循环将计数转换为每个存储桶的结束索引(1 +索引到最后一个元素)。 k循环基于当前数字将元素从最后一个移动到第一个桶中。该过程从最低有效数字开始,以最高有效数字结束。
另一种方法是将计数转换为起始索引,其中第一个索引== 0,第二个索引==具有'0'数字的元素数,...(具有'9'数字的元素的数量不是'重要但不使用)。排序的基数部分将从头到尾对元素进行排序。
在任何一种情况下,存储桶的大小都是可变的,一个存储桶的末尾是下一个存储桶的开头。当完成基数排序传递时,存储桶之间没有间隙。