基数排序(radix sort)属于“分配式排序”(distribution sort),又称“桶子法”(bucket sort)或bin sort,顾名思义,它是透过键值的部份资讯,将要排序的元素分配至某些“桶”中,藉以达到排序的作用,基数排序法是属于稳定性的排序,其时间复杂度为O(P(N+B)),其中P是排序的趟数,N是要被排序元素的个数,B是桶数。在某些时候,基数排序法的效率高于其它的稳定性排序法。(引自百度百科)
简单的理解就是按权高低依次排序。比如说有64,8,216,512,27,729,0,1,343,125这10个数排序。我们可以看到最大的数是个三位数,最小的是个个位数。则按权高低排序即从第一趟按个位数比较大小,从小到大排序为:
第二趟十位数比较大小,从小到大排序为:
第三趟百位数比较大小,从小到大排序为:
每趟排序按照基数位大小的不同分别放入相应基数的桶中:
假设有10个桶:
代码实现:
#include<stdio.h>
#include<math.h>
#define N 10
int FindMax(int *p,int n);//find max
int FindMaxRadix(int a);
void RadixSort(int *p,int m,int n);
int main()
{
int num=0,i=0;
int a[N]={64,8,2216,512,27,729,100,1,1343,125};
num=FindMaxRadix(FindMax(a,N));
RadixSort(a,num,N);
for(i=0;i<N;i++)
printf("%d\t",a[i]);
return 0;
}
int FindMax(int *p,int n)
{
int i=0,max;
max=*p;
for(i=0;i<n;i++)
{
if(*(p+i)>max)
max=*(p+i);
}
return max;
}
int FindMaxRadix(int a)
{
int temp=0,count=1;
while(a!=0)
{
temp=a/10;
count++;
a=temp;
}
return count;
}
void RadixSort(int *p,int m,int n)//m是最大位数 n是数组大小
{
int count=0;
int i=0,radix=0,j,k;
int temp=0;
int bucket[10][10]={};
for(i=0;i<m;i++)
{
radix=(int)pow(10,i);
for(j=0;j<n;j++)
{
temp=(*(p+j)/radix)%10;
for(k=0;k<10;k++)
{
if(bucket[temp][k]==0)
{
bucket[temp][k]=*(p+j);
break;
}
}
}
//将桶中的数按排序后的倒回原数组中
k=0;
for(count=0;count<10;count++)
{
for(j=0;j<10;j++)
{
if(bucket[count][j]!=0)
{
if(k==n)
break;
*(p+k)=bucket[count][j];
k++;
bucket[count][j]=0;
}
}
}
}
}
当然,桶式排序的优缺点也是显而易见的。
优点:效率高。
缺点:占用内存大,只能对正整数排序(采用二维数组做桶时)。