排序算法 基数排序

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_36511401/article/details/102655101

一、基数排序

1、介绍。

        基数排序(radix sort)属于“分配式排序”(distribution sort),又称“桶子法”(bucket sort)或bin sort,顾名思义,它是透过键值的部份资讯,将要排序的元素分配至某些“桶”中,藉以达到排序的作用,基数排序法是属于稳定性的排序,其时间复杂度为O (nlog(r)m),其中r为所采取的基数,而m为堆数,在某些时候,基数排序法的效率高于其它的稳定性排序法

        基数排序是稳定排序,需要额外内存,空间复杂度O(n*k)。时间复杂度,最佳情况:O(n*k)  最差情况:O(n*k)  平均情况:O(n*k)。

2、步骤。

    (1)第一趟桶排序将数字的个位数分配到桶子里面去,然后回收起来,此时数组元素的所有个位数都已经排好顺序了
    (2)第二趟桶排序将数字的十位数分别分配到桶子里面去,然后回收起来,此时数组元素的所有个位数和十位数都已经排好顺序了(如果没有十位数、则补0)
    (3)第三趟桶排序将数字的百位数分别分配到桶子里面去,然后回收起来,此时数组元素的所有个位数和十位数和百位数都已经排好顺序了(如果没有百位数、则补0)
    (4)直至全部数(个、十、百、千位...)排好顺序,那么这个数组就是有序的了。

3、代码。

static class Bucket { //跟main方法在同个类里面
    public int value = -1;
    public Bucket next;//下一次Bucket
    public Bucket last;//最后一个Bucket
}
public static void main(String[] args) {
        System.out.println("------开始------");
        //生成生成两份一模一样的随机数组,其中一组用系统自带的方法进行排序,到时候进行验证。
        final int number = 100000;//100000
        int[] sortArray = new int[number];
        int[] sortArrayCopy = new int[number];
        for (int i = 0; i < sortArray.length; i++) {
            sortArray[i] = (int) (Math.random() * number);
        }
        System.arraycopy(sortArray, 0, sortArrayCopy, 0, number);//数组复制
        Arrays.sort(sortArrayCopy);

        //开始排序
        long startTime = System.currentTimeMillis();
        radixSort(sortArray);//基数排序
        System.out.println("花费时间:" + (System.currentTimeMillis() - startTime));

        //跟系统排序之后数组进行比较,查看是否排序成功。
        if (Arrays.equals(sortArray, sortArrayCopy)) {
            System.out.println("排序成功");
        } else {
            System.out.println("排序失败");
        }
        System.out.println("------结束------");
    }
private static void radixSort(int[] array) {
    //找出array的最大值
    int max = array[0], min = array[0];
    for (int i = 1; i < array.length; i++) {
        if (array[i] > max) {
            max = array[i];
        }
    }
    //算出最大值的位数
    int maxDigit = 0;
    while (max != 0) {
        max /= 10;
        maxDigit++;
    }
    int mod = 10, div = 1;
    //
    for (int i = 0; i < maxDigit; i++, mod *= 10, div *= 10) {
        //初始化
        Bucket[] bucketArray = new Bucket[10];
        for (int k = 0; k < bucketArray.length; k++) {
            bucketArray[k] = new Bucket();
            bucketArray[k].last = bucketArray[k];//默认链表尾为自己
        }
        //装入bucketArray中
        for (int j = 0; j < array.length; j++) {
            int num = (array[j] % mod) / div;
            //从链表的表尾插入
            Bucket bucket = new Bucket();
            bucket.value = array[j];
            bucketArray[num].last.next = bucket;//bucket接在链表尾
            bucketArray[num].last=bucket;//bucket变成链表尾
        }
        //从bucketArray中取值,对重新排序
        int index = 0;
        for (int j = 0; j < bucketArray.length; j++) {
            Bucket pre = bucketArray[j];//上一个
            while (pre.next != null) {
                Bucket now = pre.next;
                array[index++] = now.value;
                pre = now;
            }
        }
    }
}

4.结果。

猜你喜欢

转载自blog.csdn.net/qq_36511401/article/details/102655101