之前用队列实现了基数排序,后来我想了想,结合桶排的思路,计数排序的思路,我觉得根本不需要队列,用队列太麻烦了,结合别人的代码部分,加上自己的理解,在这里讲解一下:数组是如何模拟基数排序的分配和收集过程的?
#include<stdio.h>
#include<malloc.h>
int getdigit(int x,int d) //取每个数的各个位上的数字
{
while(--d)
{
x/=10;
}
return x%10;
}
void Print_Array(int a[],int n) //打印操作
{
int i;
for(i=0;i<n;++i)
printf("%d ",a[i]);
printf("\n");
}
int Maxdigit(int a[],int n) //获取待排序列中位数最多为多少,用以确定分配收集的次数
{
int i,max=-1,flag;
for(i=0;i<n;i++)
{
int temp=a[i];
flag=0;
while(temp)
{
flag++;
temp/=10;
}
if(flag>max)
max=flag;
}
return max;
}
void LSD_radix_sort(int arr[],int begin,int end,int d) //LSD(从最低位开始分配收集)
{
const int radix=10;
int count[radix],i,j;
int *bucket=(int*)malloc((end-begin+1)*sizeof(int)); //所有桶的空间开辟
for(int k=1;k<=d;++k) //总共d次分配操作 //按照分配标准依次进行排序过程
{
for(i=0;i<radix;i++) //置空(初始化操作)---为位数不够的数进行补0操作
count[i]=0; <span style="font-family: Arial, Helvetica, sans-serif;">//统计各个桶中所盛数据个数</span>
for(i=begin;i<=end;i++)
{ <span style="font-family: Arial, Helvetica, sans-serif;">//统计每次分配后各个桶所需要的存储空间大小</span>
count[getdigit(arr[i],k)]++;
}
//count[i]表示第i个桶的右边界索引(即存放的极限下标)
for(i=1;i<radix;i++)
{ //这样第count[i]就表示前i个桶所存有的数据个数值(也就是个数)
count[i]=count[i]+count[i-1]; //count[i]表示收集每个桶后bucket[]所存有的上边界
} <span style="font-family: Arial, Helvetica, sans-serif;">//把数据依次装入桶(注意装入时候的分配技巧)</span><span style="font-family: Arial, Helvetica, sans-serif;"> </span>
for(i=end;i>=begin;--i) //这里要从右向左扫描,确保是先进先出(先入桶的先出来)
{
j=getdigit(arr[i],k); //求出关键字的第k位的数字, 例如:675的第3位是6
bucket[count[j]-1]=arr[i]; //放入对应的桶中(说是放入桶,实则是收集过程,两个过程合而为一了),count[j]-1就是这个数在bucket[]中应该存放的位置
--count[j]; //收集好一个数后,相应桶中的个数就要减一
} //这整个循环的目的是将各个桶中的分配数据进行收集(但要避免被覆盖,所以出现了上述的代码)
/*
举个例子说明一下: 假设你5号桶中分配的数据个数为3个,3次都是count[5],根据我们上一层循环count[i]的含义就知道,这样每次的count[j]-1都是不一样的,这样就不会被覆盖了,你要是不懂,我也没办法 */
for(i=begin,j=0;i<=end;++i,++j)
{
arr[i]=bucket[j]; //从各个桶中收集数据(收集过程)
}
}
free(bucket);
}
int main()
{
int a[10000],n,i;
printf("请输入待排序列的个数\n");
scanf("%d",&n);
printf("请输入待排的序列:\n");
for(i=0;i<n;i++)
scanf("%d",&a[i]);
int digits=Maxdigit(a,n);
LSD_radix_sort(a,0,n-1,digits);
printf("基数排序结果如下:\n");
Print_Array(a,n);
return 0;
}
知道了LSD是这样子的,那么你能弄出MSD是怎样的代码吗?自己动手试<span style="font-family: Arial, Helvetica, sans-serif;">试,真正理解了就很简单哦~</span>