基数排序

      基数排序是一种与之前几种排序不同的排序方法,之前的排序是基于关键字排序算法。基数排序属于分配式排序,而且基数排序是稳定排序。以下是基数排序的步骤:假设在一个数组为例,数据中的数据项均小于1000(位数最多是三维)。

1 先对数组中所有的数据项个位进行排序,个位数字0~9,从小到大的顺序进行存放(不比较其他位数字大小),结果存放在一个缓存二维数组里面。

2 在步骤1的基础之上继续对数据项的十位进行排序(数据项不改变步骤1的顺序),继续存放缓存数组中。

3 在步骤2的基础之上继续对百位数字大小进行排序,只考虑百位数字大小,但是需要不改变步骤2的大致顺序。

4 通过以上三个步骤后,将数据从缓存二维数组中复制到原来数组中。

      基数排序中采用二维数组作为缓存数组的好处在于二维数组的第一维可以存放前一个步骤的各个位上的数字(0~9),第二维是存放具体数据项。

以上步骤可以下图表示:

这里写图片描述

       下面是常见的采用二维数组作为缓存数据进行基数排序的代码:

//改进的基数排序算法
    public static void basicSortAdvanced(int[] number,int numLength)
    {
        int k=0;
        int n=1;
        int m=1;
        int[][] temp=new int[10][number.length];
        int[] order=new int[10];
        while(m<=numLength)
        {
            for(int i=0;i<number.length;i++)
            {
                int tempVal=(number[i]/n)%10;//根据n不同获取每个位数对应的数字 n=1表示个位数字 可能是0~9
                //用以下二维数组表示的好处是直接根据位数对应的数字0~9确定高维地址 这样就自动形成大小关系
                temp[tempVal][order[tempVal]]=number[i];//二维数组表示 按位数对应数字的大小进行排列并进行存储
                order[tempVal]++;//地址增加 继续存储
                //也可直接优化为
                //temp[tempVal][order[tempVal]++]=number[i];

            }
            //将二维数组存储转化为一维数组存储,还原数据
            for(int i=0;i<number.length;i++)
            {
                if(order[i]!=0)
                {
                    for(int j=0;j<order[i];j++)
                    {
                        number[k]=temp[i][j];
                        k++;
                    }
                    order[i]=0;
                }
            }
            n*=10;//数据位前移
            k=0;//恢复number索引初值
            m++;//控制下一个循环 

        }
    }

关于基数排序的难点

      一开始写基数排序时候对于解决保持之前的顺序时,采用二维数组能够巧妙解决这个问题,尝试使用链表以及多个数组解决此问题,但是会引入多个数据结构,会占用较多内存。此处引入二维数组效率较高。

下面是随机数组创建:

int[] array=null;
    LinkedList<Integer> link=new LinkedList<Integer>();
    public BasicNumberSort(int n)
    {
        System.out.println("排序之前数组是:");
        array=new int[n];
        for(int i=0;i<n;i++)
        {
            array[i]=(int)(Math.random()*1000);
            System.out.print(array[i]+" ");

        }
        System.out.println();
    }

测试以及结果:

BasicNumberSort a=new BasicNumberSort(10);
basicSortAdvanced(array, 3);
System.out.println("排序之后数组是:");
show();
排序之前数组是:
161 671 90 606 288 603 368 313 217 525 
排序之后数组是:
90 161 217 288 313 368 525 603 606 671 

关于基数排序的效率

      基数排序,这里的基数是以10为单位,对数据项的各个位进行排序。在基数排序过程中会有较多的复制次数,10个数据项会产生20次复制。复制的次数与数据项的个数成正比,O(N)。这个效率较高,但是随着数据项的个数增多,此时算法的执行效率会降低到O(N*logN),这个效率与快速排序算法相同。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值