排序算法_基数排序

【基数排序】

基数排序,又称桶排序扩展。属于稳定性排序算法(相同数据在排序过程中前后关系不变)。以{53,3,542,748,14,214}为例:

 

 核心思想是:将所有待比较数值统一为同样的数位长度,数位较短的数前面补零。然后,从最低位开始,依次进行一次排序。这样从最低位排序一直到最高位排序完成以后,数列就变成一个有序序列。

代码实现:(这里我们不实现负数的排序)

package cn.dataStructureAndAlgorithm.demo.sort;

import java.util.Arrays;

public class 基数排序_RadixSort {
    public static void main(String[] args) {
        int data[]=new int[]{8,4,5,7,1,3,6,2};
        radixSort(data);
        System.out.println(Arrays.toString(data));
    }
    public static void radixSort(int data[]){
        //获取数据中最大数
        int max=data[0];
        for (int i=1;i<data.length;i++){
            if (max<data[i]){
                max=data[i];
            }
        }
        //获取最大数位数,该位数即基数排序的轮数
        int maxSize=(max+"").length();//巧妙算法
        //制造桶数组
        int[][] bucket=new int[10][data.length];//有可能数据某位全相同,使用没办法只能用data.length
        //制造桶计数数组:记录桶中的数据个数
        int[] bucketElementCounts=new int[10];
        //开始基数排序
        for (int i=0,n=1;i<maxSize;i++,n*=10){//循环最高位数次
            for (int j=0;j<data.length;j++){//每轮将所有数据都入桶一次
                int digit=data[j]/n%10;//求得数据每轮的数位值
                bucket[digit][bucketElementCounts[digit]]=data[j];//将数据放入到对应的桶中
                bucketElementCounts[digit]++;//计数
            }
            //把桶中数据按顺序放回原数组
            int index=0;//用于操作原数组
            for (int k=0;k<10;k++) {
                //第k个桶中有数据,就开始放
                if (bucketElementCounts[k] != 0) {
                    //按照桶计数数组中记录的个数,遍历第k个桶
                    for (int j = 0; j < bucketElementCounts[k]; j++) {
                        data[index++] = bucket[k][j];//将第k个桶中的全部数据依次放入原数组中
                    }
                }
                //一轮处理完成,要把桶计数数组清空
                bucketElementCounts[k] = 0;
            }
        }

    }
}

基数排序速度测试:以8000000个【0~8000000】的随机整数为数组,进行速度测试(数据以我电脑为准,本次测速与希尔移位式,快排,归并比较,并将数据量*1000)

希尔移位式式耗时:2s          快速排序耗时:907ms            归并排序耗时:1s                   基数排序耗时:487ms

基数排序虽然快,但其产生的内存消耗巨大,80000000的数据量将产生3.3G的内存消耗,是典型的拿空间换时间的算法

优化一:占内存的主要原因在于,以上代码的数据存储结构使用的是数组,而数组的问题在于长度没法改变,为了应付极端状况的出现(某一位数全相同),就必须将数组的以固定长度创建。当待排序的数据超长时,数组也跟着增大。解决方法在于修改数据存储结构,使之应需而变。将其存储结构修改为动态数组,链表这是一种减小内存占用的方法。

优化二:以上代码是基于十进制基数来设计的桶,可否以二进制数据进行桶设计,这样贴近计算机底层,就可以通过移位操作符>>这一种高效率运算来计算2的乘方问题。进一步优化代码

可以参考【这个博客】深入研究。

 

至此,恭喜你获得【排序小王子】称号

 

排序算法中还剩下最后一个 堆排序算法 ,在学习了二叉树基础知识与二叉树顺序存储之后,会提到

 


其他的排序算法有点复杂难懂,我将其另行整理了,可以点击下面的链接进入查找

【排序算法_冒泡排序,选择排序,插入排序】

【排序算法_希尔排序】

【排序算法_快速排序】

【排序算法_归并排序】

排序算法_堆排序,该算法需要学习树的知识,可以在下面的目录链接中,自行查找

【数据结构与算法整理总结目录 :>】<-- 宝藏在此(doge)  

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值