基数排序
基数排序不是比较排序。用max表示输入数据中最大的数据,用k表示max的长度(代表其值的字符序串的长度),那么基数排序将执行k次循环,每次循环都比较这k位数据中的某一位,并按照该位数据大小排序,其结果是:该位相同的数据连续地存放到一块(在同一个桶中),该位不相同的数据是有序的(不同的桶中的数据是有序的)。循环深度增长的方向可以是从数据最低位数字向最高位数字方向,也可以反过来。
对于int类型数据,我们一般从低位往高位排序;对于字符串类型,从两个方向排序都很方便。
算法描述:
输入:元素个数n和数组a。
输出:数组a的元素按升序排列。
步骤:开辟数组b[n],用于保存每次循环之后的结果;
开辟bucket_aux[10];辅助的
开辟bucket[10],用于保存每一个桶(总共10个桶)的地址范围;
开辟变量 i,max,exp;
max <- a的最大元素
exp <- 1;
while max/exp > 0
每个桶都初始化为0
for i <- 0 to n-1
bucket[a[i]/exp%10]++;/* 记住每个桶中的元素个数 */
for i <- 0 to 9
bucket_aux[i] <- bucket[i]; /*暂存到 bucket_aux */
for i <- 1 to 9
bucket[i]+=bucket[i-1]; /* 每个桶的地址上限 */
for i <- 0 to 9
bucket[i]-=bucket_aux[i]; /* 每个桶的起始地址 */
for i <- 0 to n-1 /*扫描数组a,将每个元素放到桶中的相应位置*/
b[bucket[a[i]/exp%10]++] = a[i];
for i <- 0 to n-1
a[i] <- b[i];
exp *= 10;
输出数组a;
时间复杂度:O(n)
基数排序不是比较排序。用max表示输入数据中最大的数据,用k表示max的长度(代表其值的字符序串的长度),那么基数排序将执行k次循环,每次循环都比较这k位数据中的某一位,并按照该位数据大小排序,其结果是:该位相同的数据连续地存放到一块(在同一个桶中),该位不相同的数据是有序的(不同的桶中的数据是有序的)。循环深度增长的方向可以是从数据最低位数字向最高位数字方向,也可以反过来。
对于int类型数据,我们一般从低位往高位排序;对于字符串类型,从两个方向排序都很方便。
算法描述:
输入:元素个数n和数组a。
输出:数组a的元素按升序排列。
步骤:开辟数组b[n],用于保存每次循环之后的结果;
开辟bucket_aux[10];辅助的
开辟bucket[10],用于保存每一个桶(总共10个桶)的地址范围;
开辟变量 i,max,exp;
max <- a的最大元素
exp <- 1;
while max/exp > 0
每个桶都初始化为0
for i <- 0 to n-1
bucket[a[i]/exp%10]++;/* 记住每个桶中的元素个数 */
for i <- 0 to 9
bucket_aux[i] <- bucket[i]; /*暂存到 bucket_aux */
for i <- 1 to 9
bucket[i]+=bucket[i-1]; /* 每个桶的地址上限 */
for i <- 0 to 9
bucket[i]-=bucket_aux[i]; /* 每个桶的起始地址 */
for i <- 0 to n-1 /*扫描数组a,将每个元素放到桶中的相应位置*/
b[bucket[a[i]/exp%10]++] = a[i];
for i <- 0 to n-1
a[i] <- b[i];
exp *= 10;
输出数组a;
时间复杂度:O(n)
空间复杂度:O(n)
C语言实现如下:
/* radixsort.c */
#include <stdio.h>
#include <assert.h>
#include <stdlib.h> /* malloc(), free() */
#include <string.h> /* memset(), memcpy() */
#define DEBUG1
void radixsort (int a[], int n){
int * b;
int bucket[10], bucket_aux[10];
int i;
int exp;
int max;
b = (int *) malloc (sizeof (int) * n);
assert (NULL!=b);
/* find the maximal element of array a */
for (i=1,max=a[0]; i<n; i++){
if (max<a[i]){
max=a[i];
}
}
/* loop for k times, k is the length of max */
exp=1;
while (max/exp){
/* initialize buckets */
memset (bucket, 0, 10*sizeof (int));
/* record the number of items for each bucket */
for (i=0; i<n; i++){
bucket[a[i]/exp%10]++;
}
/* copy buckets to an auxiliary array */
memcpy (bucket_aux, bucket, 10*sizeof (int));
/* the address upper bound for each bucket */
for (i=1; i<10; i++){
bucket[i]+=bucket[i-1];
}
/* the address least bound for each bucket */
for (i=0; i<10; i++){
bucket[i]-=bucket_aux[i];
}
/* put each element of array a into its bucket */
for (i=0; i<n; i++){
b[bucket[a[i]/exp%10]++]=a[i];
}
/* get the number return to a */
for (i=0; i<n; i++){
a[i]=b[i];
}
exp*=10;
}
if (b){
free (b);
}
}
int main(int argc, char *argv[]){
int i,n,*a;
#ifdef DEBUG1
FILE * filein = freopen ("out.txt", "r", stdin);
#endif
scanf ("%d",&n);
assert (n>0);
a = (int *) malloc (sizeof (int) * n);
assert(NULL!=a);
for (i=0; i<n; i++){
scanf ("%d", &a[i]);
}
for (i=0; i<n; i++){
printf ("%d\t", a[i]);
if (9==i%10){
puts ("");
}
}
puts ("");
radixsort (a,n);
puts ("after radixsorting.");
for (i=0; i<n; i++){
printf ("%d\t", a[i]);
if (9==i%10){
puts ("");
}
}
puts ("");
#ifdef DEBUG1
fclose (filein);
#endif
if (a){
free (a);
}
return 0;
}
/* a more brief implementation from Wikipedia */
void radixsort (int a[], int n){
int * b;
int bucket[10];
int i;
int exp;
int max;
b = (int *) malloc (sizeof (int) * n);
assert (NULL!=b);
/* find the maximal element of array a */
for (i=1,max=a[0]; i<n; i++){
if (max<a[i]){
max=a[i];
}
}
/* loop for k times, k is the length of max */
exp=1;
while (max/exp){
/* initialize buckets */
memset (bucket, 0, 10*sizeof (int));
/* record the number of items for each bucket */
for (i=0; i<n; i++){
bucket[a[i]/exp%10]++;
}
/* the address upper bound for each bucket */
for (i=1; i<10; i++){
bucket[i]+=bucket[i-1];
}
/* put each element of array a into its bucket */
for (i=n-1; i>=0; i--){
b[--bucket[a[i]/exp%10]]=a[i];
}
/* get the number return to a */
for (i=0; i<n; i++){
a[i]=b[i];
}
exp*=10;
}
if (b){
free (b);
}
}
25032 9848 21392 6018 29677 2069 10455 25237 1595 31186
25032 21392 10455 1595 31186 29677 25237 9848 6018 2069
6018 25032 25237 9848 10455 2069 29677 31186 21392 1595
6018 25032 2069 31186 25237 21392 10455 1595 29677 9848
10455 31186 21392 1595 2069 25032 25237 6018 29677 9848
1595 2069 6018 9848 10455 21392 25032 25237 29677 31186
after radixsorting.
1595 2069 6018 9848 10455 21392 25032 25237 29677 31186