【算法导论例程——基数排序】基数排序(radix_sort)可以被称为是计数排序的升级版,他的原理是基于以前的卡片式排序方法,这里把要排序的每个整数看作是一张卡片,把整数的各位数字看作是卡片上的关键字,在进行计数排序时,我们逐位扫描整数的各位数字,并以该数字为关键字进行整体的排序,从低位到高位,在排序时我们可以借助结构体进行辅助,基数排序本身提供思路,它使用的是较为稳定的技术排序作为核心的排序算法,这样保证算法时间复杂度为o(d*(n + k)),其中d为整数的位数。
对于使用计数排序的写法,自己写完后发现,对于位数较低的数字,有个问题就是当他们的某一列都是0时,按照计数排序会把他们按照逆序排列,对于这样的情况,我们应该采用上一次排序是产生的顺序,这就增添了写代码的困难性,之后去查阅资料,看到了这篇文章(点击打开链接)给出的写法,真的是把“基数”体现的淋漓尽致,并且对空间的节约程度很。
以下是自己的代码,对于如何处理还是没想好,先贴上。
#include
typedef struct radix
{
int num;
int base;
int sort;
}rad;
void radix_sort(rad a[], int length, int d);
int main()
{
rad a[1000] = { 0 };
int i = 0, d = 0, n = 0;
printf("请输入待排序数组的规模:");
scanf("%d", &n);
printf("请输入待排序数组中最大数字的位数:");
scanf("%d", &d);
while (n--)
{
scanf("%d", &a[i].num);
a[i].sort = i;
a[i++].base = a[i].num % 10;
} radix_sort(a, i, d);
return 0;
}void radix_sort(rad a[], int length, int d)
{
int b[1000] = { 0 }, c[10] = { 0 }, i = 0, temp = 0;
while (d--)
{
for (i = 0;
i < 10;
i++)
c[i] = 0;
for (i = 0;
i < length;
i++)
c[a[i].base] ++;
for (i = 1;
i < 10;
i++)
c[i] += c[i - 1];
for (i = 0;
i < length;
i++)
{
if (c[a[i].base] - c[a[i].base - 1] > 1)
{
//不知怎么处理
}
b[c[a[i].base]] = a[i].num;
c[a[i].base]--;
temp = a[i].num / 10;
a[i].base = temp % 10;
}
for (i = 0;
i < length;
i++)
{
a[i].num = b[i + 1];
a[i].sort = i;
}
}
for (i = 1;
i <= length;
i++)
printf("%d,", b[i]);
}
推荐阅读
- 集合的全排列(Java实现)
- 算法导论学习笔记——2.3.1分治法——习题2-4逆序对数
- 拓展欧几里得算法详解
- 算法导论程序15-计数排序(Python)
- 算法导论 — 8.3 基数排序
- 算法导论程序16--基数排序(Python)
- 算法导论 基数排序
- RSA模重复平方算法小示例
- 【算法导论之四】计数排序
- 算法导论计数排序实现