排序算法(6)----计数排序

不知道为什么,突然编辑器不支持颜色丰富的intellij IDEA直接复制了,博主有点沮丧,因此我先用图片的形式展示并分析,然后在最后会将全部代码呈上

排序思想:在一个数组中,对于每一个数据,都统计有多少个数字小于它,就能反应出它当前所在的位置

比如 [0,1,1,2] 这个数组中,'0'就有0个元素小于它,'2'就有3个元素小于它,而对于'1',则有2个元素小于它.

从以下方面不断进步着:

  1. 基础代码
  2. 一次改进,将排序适配范围扩大
  3. 二次改进,更舒服的使用这个算法
  4. 全部代码
一.基础代码



二.一次改进,将排序适配范围扩大



在这里,将适配范围增加,但是遗憾的是依旧只能对正整数进行排序
三.二次改进,更舒服的使用这个算法



四.全部代码
package com.sort;

/**
 * 计数排序
 * 对于每一个数据,统计整个数组中有多少小于它的数,这样就可以确定它的位置.
 * 比如 : 比它小的有17个,那么它就应该在第18位上
 */
public class CountingSort {
    public static int[] countingSort_1(int[] arr) {
        //找到整个数组中的最大值
        int max = arr[0];
        for (int anArr : arr) {
            if (max < anArr) {
                max = anArr;
            }
        }
        int[] result = new int[arr.length]; //作为排序完成的数组
        int[] temp = new int[max + 1];  //用于保存临时数据
        // 这里将 temp 的下标作为待排数组中的数值,而它对应的元素作为这个数值在数组中的频数
        for (int i = 0; i < arr.length; i++) {
            temp[arr[i]] = temp[arr[i]] + 1;
        }
        // 更新 temp 数组,将它存储的元素表示为:有多少元素小于(或等于)当前下标的值
        for (int i = 1; i <= max; i++) {
            temp[i] += temp[i - 1];
        }
        //将结果输出到 result[] 中
        for (int i = arr.length - 1; i >= 0; i--) {
            result[temp[arr[i]] - 1] = arr[i];
            temp[arr[i]] = temp[arr[i]] - 1;

        }
        return result;
    }

    /*改进1:
     * 观察上述代码,很明显能得到,上面真正能够执行的情况仅能排序的区间是 [ 1 , max ]
     * 局限性很大,因此这里进行改进
     * 改进后的排序算法可以排序的区间是 [ min , max ]
     */
    //传递进来两个参数,说明排序区间为 [ min , max ]
    public static int[] countingSort_2(int[] arr, int min, int max) {
        //已经得到了整个数组中的最大值 max
        int[] result = new int[arr.length]; //作为排序完成的数组
        int[] temp = new int[max - min + 1];  //用于保存临时数据
        // 这里将 temp 的下标作为待排数组中的数值,而它对应的元素作为这个数值在数组中的频数
        for (int i = 0; i < arr.length; i++) {
            temp[arr[i] - min] = temp[arr[i] - min] + 1;
        }
        // 更新 temp 数组,将它存储的元素表示为:有多少元素小于(或等于)当前下标的值
        for (int i = 1; i <= max - min; i++) {
            temp[i] += temp[i - 1];
        }
        //将结果输出到 result[] 中
        for (int i = arr.length - 1; i >= 0; i--) {
            result[temp[arr[i] - min] - 1] = arr[i];
            temp[arr[i] - min] = temp[arr[i] - min] - 1;
        }
        return result;
    }

    /*改进2:
     * 这次改进的不是代码本身,而是操作习惯.
     * 一般而言,当我想调用一个数组对他进行排序的时候,通常不会而且不想知道它的最小值和最大值,
     * 因此找到最小值和最大值的这一步需要我们用代码实现
     *
     * 改进之后,可以直接传入数组进行排序
     */
    public static int[] countingSort_3(int[] arr) {
        int min = arr[0], max = arr[0];
        for (int anArr : arr) {
            if (anArr > max) {
                max = anArr;
            } else if (anArr < min) {
                min = anArr;
            }
        }
        return countingSort_2(arr, min, max);
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

呆萌的代Ma

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值