Имея 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
бит, я делаю сдвиг вправо на 32 - currentDigit - shift
разрядов, а затем применяю операцию И к получить shift
наименее значащих битов, а это именно те биты, которые мне нужны.
Вторая проблема связана с рекурсией. Я не думаю, что я рекурсирую по нужным группам, но в связи с тем, что я понятия не имею, правильно ли на самом деле решена первая проблема, я не могу сказать больше об этом в данный момент.
любые отзывы по этому поводу будут оценены.
заранее спасибо.
РЕДАКТИРОВАТЬ: добавлена основная функция, чтобы показать, как вызывается моя функция счисления.
int buckets = new int[...];
), последующий цикл инициализации и в конечном итогеdelete[] buckets;
, если вы использовалиstd::vector<int> buckets(...);
. Кроме того, это сделало бы ваш код безопасным для исключений, и вы получили бы дополнительные проверки операций индекса за пределами границ. Я не помню, чтобы когда-либо использовал новый массив в C++, лучше использовать обычный вектор. - person Ulrich Eckhardt   schedule 26.02.2015