您的位置:首页 > 其它

基数排序

2015-05-06 13:55 323 查看
基数排序

基数排序是一种非比较型的排序,适用于整数排序。基本的原理是将数组从个位开始到最高为依次排序,数组达到排序状态。

以数组[21, 66, 867, 9, 13, 87, 56, 121]为例,首先按照个位排序,排序后数组为:
    [21, 121, 13, 66, 56, 867, 87, 9], 再按照十为排序,排序后数组变成:
    [9, 13, 21, 121, 56, 66, 867, 87], 在按照百位排序,排序后数组变成:
    [9, 13, 21, 56, 66, 87, 121, 867], 排序完成。

基数排序时间复杂度是o(k*n), 其中k为数组元素最大位数,n为数组元素个数。

空间复杂度为n,因为需要同样大小的数组作为临时缓存,如果不考虑内存分配的时间,100个小于10000的随机数,
基数排序的时间是是插入排序的一半左右。

template<class T>
static size_t MaxDigit(T *list, size_t size)
{
T maxValue = list[0];
for (size_t i = 1; i < size; ++i)
{
if (maxValue < list[i])
maxValue = list[i];
}

size_t maxDigit = 0;
while (maxValue > 0)
{
++maxDigit;
maxValue = T(maxValue / 10);
}

return maxDigit;
}

template<class T>
static void RadixSort(T *list, size_t size)
{
//T *temp = new T[size]{ 0 };
T temp[100] = { 0 };
memcpy((void*)temp, (void*)list, size*sizeof(T));

const size_t RADIX = 10;
size_t counter[RADIX] = { 0 };

size_t seed = 1;
size_t maxDigit = MaxDigit(list, size);
for (size_t i = 1; i <= maxDigit; ++i)
{
memset((void*)counter, 0, 10 * sizeof(T));

for (size_t j = 0; j < size; ++j)
{
size_t n = size_t(list[j] / seed) % RADIX;
++counter
;
}

for (size_t j = 1; j < RADIX; ++j)
{
counter[j] = counter[j - 1] + counter[j];
}

for (int j = size-1; j >= 0; --j)
{
size_t n = size_t(list[j] / seed) % RADIX;
temp[counter
- 1] = list[j];
--counter
;
}

memcpy((void*)list, (void*)temp, size*sizeof(T));

seed *= RADIX;
}

//delete [] temp;
//temp = NULL;
}

static void RadixSortTest()
{
const int size = SortDefaultSize;
int list[size] = { 0 };
FillRandomValue(list, size);
PrintArray(list, size);

Performance *pPerformance = new Performance("RadixSort: ");

RadixSort(list, size);

delete pPerformance;
pPerformance = NULL;

PrintArray(list, size);
}

维基百科-基数排序
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  基数排序