一、算法原理
基数排序(Radix sort)是用在卡片排序机上的算法,是一种非比较的排序算法。基数排序对十进制数的每一位进行排序,与直观感受不同的是,先按最低有效位进行排序,然后收集;再按次低位排序,再收集;依此类推,直到按最高位进行排序收集之后,数组整体完成排序。为了确保基数排序的正确性,每一位的排序算法必须是稳定的(例如,若a=b,排序后a与b的顺序不发生改变)。
二、算法描述
- 首先,找到数组中的最大数,并确定其十进制位数d;
- 然后,从最低位开始取每个位组成Radix数组,对这个数组进行计数排序,每一位的取值范围在[0…k]内;
- 按照Radix排序的顺序,将原数组排序
- 直到按最高位排完序之后,原数组整体排序完成
三、算法复杂度
- 时间复杂度:T(n) = O(d*n)
- 空间复杂度:O(n),即需要额外辅助空间,与原数组规模成正比
void CountSort(int A[], int length, int d); //函数原型
//基数排序,A是待排序数组,d是A中元素的最大十进制位数
void RadixSort(int A[], int length, int d)
{
if(A == NULL || d <= 0)
{
printf("Input error!\n");
return;
}
//从最低位开始,每一位应用计数排序
for(int i = 1; i <= d; ++i)
{
CountSort(A, length, i); //采用计数排序,按照每一位进行排序
}
}
//计数排序,数组A的值在0~9范围内,d是待排序的十进制位数,数组B存放排序后的数组
void CountSort(int A[], int length, int d)
{
//建立辅助数组Ad[],存放A每一个元素的第d位数
int Ad[length];
int dd = 1;
for(int i = 1; i < d; i++)
{
dd *= 10;
}
for(int i = 0; i < length; i++)
{
if(d == 1)
{
Ad[i] = A[i] % 10;
}
else
{
Ad[i] = (A[i]/dd) % 10;
}
}
//初始化B和C数组
int B[length];
for(int i = 0; i < length; i++)
B[i] = 0;
int C[10];
for(int i = 0; i < 10; i++)
{
C[i] = 0;
}
//C数组对Ad数组中元素进行计数
for(int j = 0; j < length; j++)
{
C[Ad[j]]++;
}
//将C数组计数次数每一项与前一项累加
for(int i = 1; i <= 9; i++)
{
C[i] = C[i-1] + C[i];
}
//在B数组中保存排序好的数组
for(int j = length - 1; j >= 0; j--)
{
B[C[Ad[j]]-1] = A[j];
C[Ad[j]]--;
}
//将A数组更新为排序后的数组
for(int i = 0; i < length; i++)
{
A[i] = B[i];
}
}