基数排序
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);
}
维基百科-基数排序
基数排序是一种非比较型的排序,适用于整数排序。基本的原理是将数组从个位开始到最高为依次排序,数组达到排序状态。
以数组[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);
}
维基百科-基数排序
相关文章推荐
- 排序——基数排序
- 基数排序
- 算法导论8.3-4习题解答(基数排序)
- 基数排序(C)
- 内部排序系列 之 分配排序与基数排序
- 算法导论第八章——基数排序
- 计数排序、桶排序和基数排序
- 排序算法_基数排序
- 【算法学习】线性时间排序-计数排序、基数排序和桶排序详解与编程实现
- 【算法导论】基数排序
- 计数排序、桶排序和基数排序
- 浅谈C++之冒泡排序、希尔排序、快速排序、插入排序、堆排序、基数排序性能对比分析之后续补充说明(有图有真相)
- 非比较排序 - 基数排序(桶排序)
- HDU 1280 前m大的数 基数排序
- C++实现基数排序
- 基于非比较的排序:计数排序(countSort),桶排序(bucketSort),基数排序(radixSort)
- PHP基数排序(MSD模式)
- Java 排序之 基数排序
- 基数排序
- 基数排序(采用链表)