算法之计数排序

核心思想:通过计算某个数据之前有多少个数据来确定自身的位置,不通过数据之间的相互比较,所以是非比较排序。
原始计数排序:
时间复杂度:O(n+k)k为数据量
缺点:如果数据只有两个,9999,10000,那么会额外创建容量为10000的数组,浪费空间。

    public static int[] countSort1(int[] array) {
        //1.得到数列的最大值
        int max = array[0];
        for (int i = 1; i < array.length; i++) {
            if (array[i] > max) {
                max = array[i];
            }
        }
        //2.根据数列的最大值确定统计数组的长度
        int[] coutArray = new int[max + 1];
        //3.遍历数列,填充统计数组
        for (int i = 0; i < array.length; i++) {
            coutArray[array[i]]++;
        }
        //4.遍历统计数组,输出结果
        int index = 0;
        int[] sortedArray = new int[array.length];
        for (int i = 0; i < coutArray.length; i++) {
            // i此刻代表array中的数据
            for (int j = 0; j < coutArray[i]; j++) {
                sortedArray[index++] = i;
            }
        }

        return sortedArray;
    }

改进之后:只会创建最大值减去最小值长度的数组,节省空间,但只适合数据均匀分布的数据,比如,如果数据是1,10000,仍然会创建容量为10000的数据。


    public static int[] countSort(int[] array) {
        //1.得到数列的最大值与最小值,并算出差值d
        int max = array[0];
        int min = array[0];
        for (int i = 1; i < array.length; i++) {
            if (array[i] > max) {
                max = array[i];
            }
            if (array[i] < min) {
                min = array[i];
            }
        }
        int d = max - min;
        //2.创建统计数组并计算统计对应元素个数,countArray出存储的值是array中数据出现的次数;countArray下标代表的意思是arry中数据排好序的相对位置
        // 比如数组array:95,96,95,99,100,99。,则对应数组countArray,countArray[0]=2;代表95出现了两次,,countArray[1]=1;代表96出现了1次
        // ,countArray[2]=2,代表99出现了2次,countArray[3]=1,代表100出现了1次,
        int[] countArray = new int[d + 1];
        for (int i = 0; i < array.length; i++) {
            // a++的意思是先用后加,所以这一步的意思就是先放进去再给变量增加,给下一轮判断赋值
            countArray[array[i] - min]++;
        }
        //3.统计数组变形,后面的元素等于前面的元素之和
        int sum = 0;
        for (int i = 0; i < countArray.length; i++) {
            // 就是把包括自己在内的之前的数据相加然后再付赋值给自己,意义是确定数组下标为多少的数据在整个数据中应该排多少位,
            sum += countArray[i];
            countArray[i] = sum;
        }
        //4.倒序遍历原始数组,从统计数组找到正确位置,输出到结果数组
        int[] sortedArray = new int[array.length];
        for (int i = array.length - 1; i >= 0; i--) {
            // array[i]指的是原始数组中处于i位置的数值是多少
            //array[i] - min在这里就是array[i]的数值在countArray数组中的下标。
            // countArray[array[i] - min] 指的是变形后的数组countArray下标为array[i] - min的数值是多少,对应array中数据就有多少个。,
            //  sortedArray[countArray[array[i] - min] - 1]就是新数组中,储存 array[i]数据的位置。
            sortedArray[countArray[array[i] - min] - 1] = array[i];
            //  因为countArray【i】代表小于等于i的数据总共出现的次数,我们已经放了一个数据到sortedArray【】中,所以要减一
            countArray[array[i] - min]--;
        }
        return sortedArray;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值