基数排序
第一步
假设原来有一串数值如下所示:
73, 22, 93, 43, 55, 14, 28, 65, 39, 81
首先根据个位数的数值,在走访数值时将它们分配至编号0到9的桶子中:
0
1 81
2 22
3 73 93 43
4 14
5 55 65
6
7
8 28
9 39
第二步
接下来将这些桶子中的数值重新串接起来,成为以下的数列:
81, 22, 73, 93, 43, 14, 55, 65, 28, 39
接着再进行一次分配,这次是根据十位数来分配:
0
1 14
2 22 28
3 39
4 43
5 55
6 65
7 73
8 81
9 93
第三步
接下来将这些桶子中的数值重新串接起来,成为以下的数列:
14, 22, 28, 39, 43, 55, 65, 73, 81, 93
这时候整个数列已经排序完毕;如果排序的对象有三位数以上,则持续进行以上的动作直至最高位数为止。
LSD的基数排序适用于位数小的数列,如果位数多的话,使用MSD的效率会比较好。MSD的方式与LSD相反,是由高位数为基底开始进行分配,但在分配之后并不马上合并回一个数组中,而是在每个“桶子”中建立“子桶”,将每个桶子中的数值按照下一数位的值分配到“子桶”中。在进行完最低位数的分配后再合并回单一的数组中。
#include <stdlib.h>
#include <math.h>
int main()
{
//a数组为原数组,b数组是a的替身数组:为了把变化后的数组赋值给a数组;
//c数组是计数数组,d数组是a数组每个数值的最后一位,n是数组的长度;
void radixsort(int a[], int b[], int c[], int d[], int n);
int a[100], b[100], c[10], d[100], n, m, max = 0, i, j;
printf("Please enter the number of digits you want to enter:");
scanf_s("%d", &n);
printf("please input %d numbers to radixsort:\n", n);
for (i = 0; i < n; i++)
scanf_s("%d", &a[i]);
for (i = 0; i < n; i++)
if (max < a[i]) max = a[i];//求最大值
for (i = 0; max > 0; i++)//计算最大值是几位数
max = max / 10;
m = i;
for (i = 0; i < m; i++)//执行最大值的位数的那么多次循环,如最大为123,则执行3次循环
{
//i=0时,是把每一个值的个位给d数组,i=1时,是把每一个值的十位给d数组以此类推
for (j = 0; j < n; j++)
d[j] = ((int)(a[j] / pow(10, i))) % 10;
radixsort(a, b, c, d, n);//个位执行一次,十位执行一次,直到执行到最大值的位数
}
printf("Radixsort:\n");
for (i = 0; i < n; i++)
printf("%d ", b[i]);//打印出数组
printf("\n");
system("pause");
return 0;
}
void radixsort(int a[], int b[], int c[], int d[], int n)
{
int i, j, k = 0;
for (i = 0; i <= 9; i++)//每次执行计数时要对计数数组c进行清零
c[i] = 0;
for (i = 0; i < n; i++)//开始计数,d[i]在0~9之间;
c[d[i]]++;
//每进行一次就会把c[i]的数清零,意思是把末尾为i的数首先赋值给了b数组
for (i = 0; i <=9;i++)
{
if (c[i] == 0)//保证循环安全
continue;
for (j = 0; j < n; j++)
if (d[j] == i)//如果相等说明a[j]的末尾数字=i,即把a[j]赋值给b数组
{
b[k++] = a[j];//k是用来计数b数组的
c[i]--;
if (c[i] == 0)//节省循环次数和保证循环安全
break;
}
}
for (i = 0; i < n; i++)//最后把变化后的a数组赋值给a数组,也就是把b数组赋值给a数组
a[i] = b[i];
}
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main()
{
//a数组为原数组,b数组是a的替身数组:为了把变化后的数组赋值给a数组;
//c数组是计数数组,d数组是a数组每个数值的最后一位,n是数组的长度;
void radixsort(int a[], int b[], int c[], int d[], int n);
int a[100], b[100], c[10], d[100], n, m, max = 0, i, j;
printf("Please enter the number of digits you want to enter:");
scanf_s("%d", &n);
printf("please input %d numbers to radixsort:\n", n);
for (i = 0; i < n; i++)
scanf_s("%d", &a[i]);
for (i = 0; i < n; i++)
if (max < a[i]) max = a[i];//求最大值
for (i = 0; max > 0; i++)//计算最大值是几位数
max = max / 10;
m = i;
for (i = 0; i < m; i++)//执行最大值的位数的那么多次循环,如最大为123,则执行3次循环
{
//i=0时,是把每一个值的个位给d数组,i=1时,是把每一个值的十位给d数组以此类推
for (j = 0; j < n; j++)
d[j] = ((int)(a[j] / pow(10, i))) % 10;
radixsort(a, b, c, d, n);//个位执行一次,十位执行一次,直到执行到最大值的位数
}
printf("Radixsort:\n");
for (i = 0; i < n; i++)
printf("%d ", b[i]);//打印出数组
printf("\n");
system("pause");
return 0;
}
void radixsort(int a[], int b[], int c[], int d[], int n)
{
int i, j, k = 0;
for (i = 0; i <= 9; i++)//每次执行计数时要对计数数组c进行清零
c[i] = 0;
for (i = 0; i < n; i++)//开始计数,d[i]在0~9之间;
c[d[i]]++;
//每进行一次就会把c[i]的数清零,意思是把末尾为i的数首先赋值给了b数组
for (i = 0; i <=9;i++)
{
if (c[i] == 0)//保证循环安全
continue;
for (j = 0; j < n; j++)
if (d[j] == i)//如果相等说明a[j]的末尾数字=i,即把a[j]赋值给b数组
{
b[k++] = a[j];//k是用来计数b数组的
c[i]--;
if (c[i] == 0)//节省循环次数和保证循环安全
break;
}
}
for (i = 0; i < n; i++)//最后把变化后的a数组赋值给a数组,也就是把b数组赋值给a数组
a[i] = b[i];
}