八大排序算法有:冒泡排序、插入排序、选择排序、快速排序、希尔排序、堆排序、归并排序、基数排序。前面七种网上都有很多例子,但是最后一种基数排序却很少看到,所以我总结了一下,并且自己写了一个简单的实现。
基数排序是一种分配排序,其基本思想是:排序过程无须比较关键字,而是通过“分配”和“收集”过程来实现排序。它们的时间复杂度可达到线性O(n)。基数排序所做的事情,是对N位分别进行排序。从直觉上来看,人们可能会觉得应该首先按最高有效位进行排序,不过这点与我们的直觉相反,基数排序首先对最低有效位数字进行排序。如果我们每次比较r bits,则需要进行b/r趟,每趟进行计数排序需要O(n+2^r),则总的时间复杂度为O(b/r(n+2^r))。
理论上来说,基数排序的速度是以上几种排序方法中最快的,可以达到O(N),而其它的排序算法最快也只有O(N*logN)。但是,基数排序需要占用额外的空间,而且只支持整数进行排序。
基数排序的演示可以看这里:基数排序
实现代码如下:
#include <stdio.h>
#include <string.h>
int get_index(int num, int dec, int order)
{
int i, j, n;
int index;
int div;
for (i=dec; i>order; i--) {
n = 1;
for (j=0; j<dec-1; j++)
n *= 10;
div = num/n;
num -= div * n;
dec--;
}
n = 1;
for (i=0; i<order-1; i++)
n *= 10;
index = num / n;
return index;
}
void radix_sort(int array[], int len, int dec, int order)
{
int i, j;
int index;
int tmp[len];
int num[10];
memset(num, 0, 10*sizeof(int));
memset(tmp, 0, len*sizeof(int));
if (dec < order)
return;
for (i=0; i<len; i++) {
index = get_index(array[i], dec, order);
num[index]++;
}
for (i=1; i<10; i++)
num[i] += num[i-1];
for (i=len-1; i>=0; i--) {
index = get_index(array[i], dec, order);
j = --num[index];
tmp[j] = array[i];
}
for (i=0; i<len; i++)
array[i] = tmp[i];
printf("the %d time\n", order);
for (i=0; i<30; i++)
printf("%d ", array[i]);
printf("\n");
radix_sort(array, len, dec, order+1);
return;
}
int main(int argc, char *argv[])
{
int i;
int array[30] = {258, 976, 515, 337, 359, 701, 916, 494, 303, 175,
677, 825, 131, 560, 147, 254, 759, 814, 917, 382,
452, 114, 873, 585, 881, 127, 819, 658, 461, 435};
int len = 30;
int dec = 3;
int order = 1;
printf("before\n");
for (i=0; i<30; i++)
printf("%d ", array[i]);
printf("\n");
radix_sort(array, len, dec, order);
printf("final\n");
for (i=0; i<30; i++)
printf("%d ", array[i]);
printf("\n");
return 0;
}