算法入门6-计数排序

一、原理

  计数排序的原理是,统计数组中每个数出现的次数,那么,数组中每个数排序后的位置,就是比它小的数的出现次数累加和。

​  计数排序于1954年由 Harold H. Seward 提出,它的优势在于在对一定范围内的整数排序时,它的复杂度为Ο(n+k)(其中k是整数的范围),快于任何比较排序算法。

​  当然,这是一种非基于比较的排序算法,它只能适用于数值型的数组。对于非数值型的数组,则不能使用。

​  而且,它的实现是一种牺牲空间换取时间的做法,当数值范围很大时,也并不适用计数排序。

二、实现过程

​  1、获取数组中的最大值,创建一个容量为最大值+1的计数数组;

​  2、遍历原数组,给计数数组对应位置上数值+1,得到每个数出现的次数;

​  3、对计数数组做累加和,累加和的结果,其实就是排序后的位置索引

​  4、遍历原数组,将累加和的结果作为新数组的位置索引,依次将值赋值到新数组,并且,每取出一个值,就在计数数组对应位置-1。

​  图示:

在这里插入图片描述

​  java实现代码:

// 计数排序
public class CountSort {

    public static void main(String[] args) {
        Integer[] arr = DataStore.getData();
        String source = "";
        for(int i = 0; i < arr.length; i++) {
            source += arr[i] + " ";
        }
        System.out.println("原数组:" + source);
        int[] sortArr = CountSort.sort(arr);
        String res = "";
        for(int i = 0; i < sortArr.length; i++) {
            res += sortArr[i] + " ";
        }
        System.out.println("排序后:" + res);
    }

    // 计数排序
    public static int[] sort(Integer[] arr) {
        int max = CountSort.getMax(arr);
        return CountSort.count(arr, max);
    }

    // 获取数组中最大值
    public static int getMax(Integer[] arr) {
        int max = 0;
        for(int i = 0; i < arr.length; i++) {
            if(arr[i] > max) {
               max = arr[i];
            }
        }
        return max;
    }

    // 计数出现频次,并累加计数得到排序索引
    public static int[] count(Integer[] arr, int max) {
        // 计数数组,容量大小为原数组的最大值+1,每个位置上的值已被默认初始化为0
        int[] countArr = new int[max + 1];
        // 辅助数组,存放排序后的数组值
        int[] helpArr = new int[arr.length];
        // 遍历原数组,给计数数组对应位置数值+1,得到每个数出现的次数
        for(int i = 0; i < arr.length; i++) {
            countArr[arr[i]] += 1;
        }
        // 对计数数组做累加和,累加和的结果,其实就是排序后的位置索引
        for(int i = 1; i < countArr.length; i++) {
            countArr[i] += countArr[i - 1];
        }
        // 遍历原数组,将累加和的结果作为新数组的位置索引,依次将值赋值到新数组
        // 每取出一个值,就在计数数组对应位置-1
        for(int i =  0; i < arr.length; i++) {
            helpArr[countArr[arr[i]] - 1] = arr[i];
            countArr[arr[i]]--;
        }
        return helpArr;
    }
}

​  DataStore工具类

public class DataStore {

    // 随机获取10个整数
    public static Integer[] getData() {
        List<Integer> list = new ArrayList<Integer>();
        for(int i = 0; i < 10; i++) {
            double d = Math.random();
            list.add((int)(d*10));
        }
        Integer[] arrays = new Integer[list.size()];
        list.toArray(arrays);
        return arrays;
    }
}

​  输出:

​  原数组:4 6 5 4 2 3 2 0 6 9

​  排序后:0 2 2 3 4 4 5 6 6 9

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值