基数排序的思想是先将要排序的序列进行划分,分成几个桶.(比如说,整数可以按照0-9分成10个桶,单词可以按照a-z分成26个桶). 从元素的最低位开始,一轮循环下来,根据元素的最低位进行一轮的分桶排序.下一轮循环则考察元素的次低位,依次类推,直到完成.
基数排序需要借助队列来做额外的辅助存储空间.利用队列的先进先出的性质,使用队列来做为容器,分成几个桶,就有几个队列.每个元素根据当前考察位进入相应的队列,待一轮循环完成后,每个元素出队列重新生成一个序列顺序,开始下一轮的入队列. 最后,所有元素会被移动到第一个队列中,并且排列有序.此时排序算法完成.
时间复杂度: O(2*m*n) m为分桶的个数,进出队列分别需要m*n
空间复杂度:O(m*n) m为分桶的个数
算法稳定性: 稳定
需要额外辅助存储空间
该算法没有使用模板,不同数据类型分桶的原则不同,如果涉及浮点数,对小数点的处理会比较复杂,且应用场景不大,因此代码实现仅仅以整数为例
void radixSort(unsigned int* const sortArray);
template <typename T, unsigned int size>
void Sort<T, size>::radixSort(unsigned int* const sortArray)
{
LinkQueue<unsigned int, QUEUE_SIZE> *baseList[10];
baseList[0] = new LinkQueue<unsigned int, QUEUE_SIZE>();
baseList[1] = new LinkQueue<unsigned int, QUEUE_SIZE>();
baseList[2] = new LinkQueue<unsigned int, QUEUE_SIZE>();
baseList[3] = new LinkQueue<unsigned int, QUEUE_SIZE>();
baseList[4] = new LinkQueue<unsigned int, QUEUE_SIZE>();
baseList[5] = new LinkQueue<unsigned int, QUEUE_SIZE>();
baseList[6] = new LinkQueue<unsigned int, QUEUE_SIZE>();
baseList[7] = new LinkQueue<unsigned int, QUEUE_SIZE>();
baseList[8] = new LinkQueue<unsigned int, QUEUE_SIZE>();
baseList[9] = new LinkQueue<unsigned int, QUEUE_SIZE>();
//Assume the max length of a number is 10
int mod = 10;
int divValue = 1;
for (int i = 0; i < 10; i++)
{
if (0 == i)
{
}
else
{
divValue = divValue * 10;
}
for (int j = 0; j < size; j++)
{
unsigned int value = (sortArray[j]/divValue) % mod;
baseList[value]->enQueue(sortArray[j]);
}
int index = 0;
for (int k = 0; k < 10; k++) //Means 10 array
{
unsigned int dequeueValue;
while (!baseList[k]->isEmpty())
{
baseList[k]->deQueue(dequeueValue);
sortArray[index] = dequeueValue;
++index;
}
}
}
for (int i = 0; i < 10; i++)
{
if (NULL != baseList[i])
{
delete baseList[i];
baseList[i] = NULL;
}
}
}