基数排序-数组模拟实现

之前用队列实现了基数排序,后来我想了想,结合桶排的思路,计数排序的思路,我觉得根本不需要队列,用队列太麻烦了,结合别人的代码部分,加上自己的理解,在这里讲解一下:数组是如何模拟基数排序的分配和收集过程的?
#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>

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值