【发布时间】:2015-04-27 21:56:06
【问题描述】:
给定n 32 位整数(假设它们是正数),您希望通过首先查看总位数中最重要的shift 并递归排序由排序整数创建的每个桶来对它们进行排序位。
所以如果shift 是 2,那么您将首先查看每个 32 位整数中的两个最高有效位,然后应用计数排序。最后,从您将获得的组中,您对每个组进行递归,并通过查看第三和第四个最高有效位开始对每个组的数字进行排序。您以递归方式执行此操作。
我的代码如下:
void radix_sortMSD(int start, int end,
int shift, int currentDigit, int input[])
{
if(end <= start+1 || currentDigit>=32) return;
/*
find total amount of buckets
which is basically 2^(shift)
*/
long long int numberOfBuckets = (1UL<<shift);
/*
initialize a temporary array
that will hold the sorted input array
after finding the values of each bucket.
*/
int tmp[end];
/*
Allocate memory for the buckets.
*/
int *buckets = new int[numberOfBuckets + 1];
/*
initialize the buckets,
we don't care about what's
happening in position numberOfBuckets+1
*/
for(int p=0;p<numberOfBuckets + 1;p++)
buckets[p] = 0;
//update the buckets
for (int p = start; p < end; p++)
buckets[((input[p] >> (32 - currentDigit - shift))
& (numberOfBuckets-1)) + 1]++;
//find the accumulative sum
for(int p = 1; p < numberOfBuckets + 1; p++)
buckets[p] += buckets[p-1];
//sort the input array input and store it in array tmp
for (int p = start; p < end; p++){
tmp[buckets[((input[p] >> (32 - currentDigit- shift))
& (numberOfBuckets-1))]++] = input[p];
}
//copy all the elements in array tmp to array input
for(int p = start; p < end; p++)
input[p] = tmp[p];
//recurse on all the groups that have been created
for(int p=0;p<numberOfBuckets;p++){
radix_sortMSD(start+buckets[p],
start+buckets[p+1], shift, currentDigit+shift, input);
}
//free the memory of the buckets
delete[] buckets;
}
int main()
{
int a[] = {1, 3, 2, 1, 4, 8, 4, 3};
int n = sizeof(a)/sizeof(int);
radix_sortMSD(0,n, 2,0,a);
return 0;
}
我只能想象这段代码中有两个问题。
第一个问题是我是否真的在每次迭代中都得到了正确的整数位。我假设如果我在currentDigit 位置,如果currentDigit = 0 这意味着我在我的整数的32 位,那么为了获得下一个shift 位,我右移@987654329 @ 位置,然后我应用 AND 操作来获得 shift 最低有效位,这正是我想要的位。
第二个问题是递归的。我不认为我在正确的组上递归,但由于我不知道第一个问题是否真的得到了正确解决,目前我不能说更多。
我们将不胜感激。
提前谢谢你。
编辑:添加主函数以显示我的基数函数是如何被调用的。
【问题讨论】:
-
如果您替换分配 (
int buckets = new int[...];)、随后的初始化循环和最终的delete[] buckets;(如果您使用std::vector<int> buckets(...);),您可以节省几行输入。此外,它将使您的代码异常安全,并且您将获得针对越界索引操作的可选检查。我不记得曾经在 C++ 中使用过数组 new,一个常规向量是更好的选择。
标签: c++ algorithm sorting recursion radix