一文搞懂数据结构 之 基数排序

基数排序:

        Radix sort 是一种非比较型 整数排序算法,其原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。由于整数也可以表达字符串(比如名字或日期)和特定格式的浮点数,所以基数排序也不是只能使用于整数。

基数排序原理:

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

基数排序结束条件:

        第一个桶存满了,就表示排完了。

约定:

        借助一个二维数组,二维数组的下标作为桶标识,一维数组(桶)的首元素作为该一维数组(桶)内存储了多少元素。

排序步骤演示:

        dataset = [4, 13, 23, 10, 5, 11, 0, 27, 24, 18, 2, 16]

        bucket[10][dataset.len+1]
对每个元素的最低位进行分割:int val = dataset[i] % 10

        

valbucket[val] = dataset[i]
04bucket[4] = [1,4]
13bucket[3] = [1,13]
23bucket[3] = [2,13,23]
30bucket[0] = [1,0]
45bucket[5] = [1,5]
51bucket[1] = [1,11]
60bucket[0] = [2,0,0]
77bucket[7] = [1,27]
84bucket[4] = [2,4,24]
98bucket[8] = [1,18]

10

2bucket[2] = [1,2]
116bucket[6] = [1,16]

        从bucket[k range 0,10] 中 取出一维数组中的所有元素,并放回dataset

                

bucket[0][2,0,0]
bucket[1][1,11]
bucket[2][1,2]
bucket[3][2,13,23]
bucket[4][2,4,24]
bucket[5][1,5]
bucket[6][1,16]
bucket[7][1,27]
bucket[8][1,18]
bucket[9][0]

                 每个bucket 的首个元素都只代表这个bucket 中有多少个元素,不是用户数据,所以不要取错了。应该从第二个元素(下标1)开始取回元素

        dataset = [0, 0, 11,2,13,23,4,24,5,16,27,18]

这是第一遍,下一边将 int val = dataset[i] % 10 改成取十位数字,如果高位没有数就填0

例如:4 没有十位,就改为04 % 100 / 10

直到第0 号桶填满为止。

/**
 * 基数排序
 */
public class RadixSort {
    public static void sort(int[] dataset){
        // 定义一个临时存储的
        int[][] radixBuckets = new int[10][dataset.length+1];
        // 约定,每个 bucket 的第一个数据标识桶使用容量
        int level = 1;
        while (!firstBucketIsFull(radixBuckets)){
            // 清空桶
            for (int i = 0;i<radixBuckets.length;i++){
                // 让桶尾指回即可。不是真正意义上的消除桶中数据。只是读不到了而已。
                radixBuckets[i][0] = 0;
            }
            for (int i= 0;i<dataset.length;i++){
                // 取出取出每轮对应的裁剪数
                int dv =(dataset[i]/level) % 10;
                // 桶尾
                int end = radixBuckets[dv][0]+1;
                // 从桶尾放入元素
                radixBuckets[dv][end] = dataset[i];
                // 桶尾 +1
                radixBuckets[dv][0] = end;
            }
            // 将桶中数据写回 dataset
            int index = 0;
            for (int k = 0;k<radixBuckets.length;k++){
                int[] bucket = radixBuckets[k];
                for (int i = 1;i<=bucket[0];i++){
                    dataset[index++] = bucket[i];
                }
            }
            level = level * 10;
        }
    }
    static boolean firstBucketIsFull(int[][] radixBuckets){
        if (radixBuckets[0][0] == radixBuckets[0].length-1){
            return true;
        }
        return false;
    }
}

以上智能排序正数,如果要排序据中有负数,可以再增加一个临时数组,里面是负数桶,最后合并两个临时数据就行了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值