基数排序
一、算法描述
以整形为例,将整形10进制按每位拆分,然后从低位到高位依次比较各个位。主要分为两个过程:
(1)分配,先从个位开始,根据位值(0-9)分别放到0~9号桶中(比如53,个位为3,则放入3号桶中)
(2)收集,再将放置在0~9号桶中的数据按顺序放到数组中
重复(1)(2)过程,从个位到最高位(比如32位无符号整形最大数4294967296,最高位10位)
以[2, 13, 35, 99, 5, 10, 64, 28, 17, 6]为例,具体过程如下:
由于该数组中最大值只有2位,因此只需要进行两次分配与收集过程。
(1)个位的分配与收集
分配:
0: 10
1:
2: 2
3: 13
4: 64
5: 35,5
6: 6
7: 17
8: 28
9: 99
收集:
10 2 13 64 35 5 6 17 28 99
(2)百位的分配与收集
分配:
0: 2,5,6
1: 10,13,17
2: 28
3: 35
4:
5:
6: 64
7:
8:
9: 99
收集:
2 5 6 10 13 17 28 35 64 99
在数据中最高位为2,进行了两次分配、收集过程后,变成有序数组。
二、算法分析
/*
找到num的从低到高的第pos位的数据
num: 一个整型数据
pos: 表示要获得的整型的第pos位数据
*/
int getNumInPos(int num, int pos)
{
int temp = 1;
for(int i = 0; i < pos - 1; i++)
temp *= 10;
return (num/temp)%10;
}
/*
找到数组中最大元素的位数
a[]: 输入数组
n: 数组元素个数
返回最大元素的位数
*/
int findMaxDigit(int a[], int n)
{
// 查找最大元素
int max_num = a[0];
for(int i = 1; i < n; i++)
{
if(max_num < a[i])
max_num = a[i];
}
// 判断最大元素的位数
int digit = 0;
while(max_num != 0)
{
max_num = max_num/10;
digit++;
}
return digit;
}
/*
基数排序
a[]: 输入数组
n: 数组元素个数
*/
// 整型排序
#define RADIX_INT 10
void radixSort(int a[], int n)
{
// 分别为0-9的序列空间
int *radixArrays[RADIX_INT];
for(int i = 0; i < RADIX_INT; i++)
{
radixArrays[i] = (int *)malloc(sizeof(int)*(n + 1));
// index为0处记录这组数据的个数
radixArrays[i][0] = 0;
}
// 求出数组中最大元素的位数
int digit = findMaxDigit(a, n);
// 从最低位到最高位
for(int pos = 1; pos <= digit; pos++)
{
// 分配过程
for(int i = 0; i < n; i++)
{
int num = getNumInPos(a[i], pos);
int index = ++radixArrays[num][0];
radixArrays[num][index] = a[i];
}
// 收集过程
for(int i = 0, j = 0; i < RADIX_INT; i++)
{
for(int k = 1; k <= radixArrays[i][0]; k++)
{
a[j++] = radixArrays[i][k];
}
// 复位
radixArrays[i][0] = 0;
}
}
}