icode icode
首页
  • Android学习

    • 📁基础内容
    • 📺AndroidCore
    • 🎨Android-UI
    • 🏖️Components
    • 📊Fragment
    • 🔗网络操作
    • 🔏异步机制
    • 📦数据存储
    • 🗃️Gradle
  • 学习笔记

    • 『框架』笔记
    • 『Kotlin』笔记
    • 《Vue》笔记
    • 《Git》学习笔记
    • 『Bug踩坑记录』
  • ListView
  • RecyclerView
  • ViewPager
  • Java笔记

    • 🟠JavaSE
    • 🟢JavaWeb
    • 🔴JavaEE
    • ⚪JavaTopic
    • 🍳设计模式
  • 计算机基础

    • 📌计算机网络
    • 🔍数据结构
    • 📦数据库
    • 💻OS
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
  • 关于

    • 📫关于我
  • 收藏

    • 网站
    • 资源
    • Vue资源
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

iqqcode

保持对技术的探索实践与热爱
首页
  • Android学习

    • 📁基础内容
    • 📺AndroidCore
    • 🎨Android-UI
    • 🏖️Components
    • 📊Fragment
    • 🔗网络操作
    • 🔏异步机制
    • 📦数据存储
    • 🗃️Gradle
  • 学习笔记

    • 『框架』笔记
    • 『Kotlin』笔记
    • 《Vue》笔记
    • 《Git》学习笔记
    • 『Bug踩坑记录』
  • ListView
  • RecyclerView
  • ViewPager
  • Java笔记

    • 🟠JavaSE
    • 🟢JavaWeb
    • 🔴JavaEE
    • ⚪JavaTopic
    • 🍳设计模式
  • 计算机基础

    • 📌计算机网络
    • 🔍数据结构
    • 📦数据库
    • 💻OS
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
  • 关于

    • 📫关于我
  • 收藏

    • 网站
    • 资源
    • Vue资源
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 排序算法

    • 被排序算法吊打系列
    • 冒泡排序,你需要了解的三种优化
    • 选择排序
    • 插入排序
    • 希尔排序
    • 归并排序
    • 快速排序
    • 堆排序
    • 二分查找
    • 计数排序
      • 基数排序
      • 休眠排序
    • 线性表

    • 树

    • 数据结构
    • 排序算法
    iqqcode
    2021-06-17
    目录

    计数排序

    # 1. 排序思想

    image-20200804111051877 image-20200804110502364 image-20200804110443979 image-20200804110558023

    # 2. 代码逻辑

    不稳定排序

    /**
     * 不稳定排序
     * @param arr
     * @return
     */
    public static int[] sort(int[] arr) {
        // 得到数列的最大值和最小值,并算出差值
        int min = arr[0], max = arr[arr.length - 1];
        for (int i = 0; i < arr.length; i++) {
            if(arr[i] > max)
                max = arr[i];
            if (arr[i] < min) {
                min = arr[i];
            }
        }
        
        int[] count = new int[max - min + 1];
        for (int i = 0; i < arr.length; i++) {
            count[arr[i] - min]++;
        }
        
        int[] result = new int[arr.length];
        for (int i = 0, j = 0; i < count.length; i++) {
            while (count[i]-- > 0) {
                result[j++] = i;
            }
        }
        return result;
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29

    稳定排序

    /**
     * 稳定排序
     * @param arr
     * @return
     */
    public static int[] sort_stable(int[] arr) {
        // 1.得到数列的最大值和最小值
        int min = arr[0], max = arr[arr.length - 1];
        for (int i = 0; i < arr.length; i++) {
            if(arr[i] > max)
                max = arr[i];
            if (arr[i] < min) {
                min = arr[i];
            }
        }
        
        // 2.创建统计数组并统计对应元素个数
        int[] count = new int[max - min + 1];
        for (int i = 0; i < arr.length; i++) {
            count[arr[i] - min]++;
        }
        
        // 3.统计数组做变形,后面的元素等于前面的元素之和
        int sum = 0;
        for (int i = 0; i < count.length; i++) {
            sum += count[i];
            count[i] = sum;
        }
        
        // 4.倒序遍历原始数列,从统计数组找到正确位置,输出到结果数组
        int[] result = new int[arr.length];
        for (int i = arr.length - 1; i > 0; i--) {
            result[count[arr[i] - min] - 1] = arr[i];
            count[arr[i] - min]--;
        }
        return result;
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37

    # 3. 复杂度

    原始数列的规模是N,最大最小整数的差值是M,你说说计数排序的时间复杂度和空间复杂度是多少?

    【时间复杂度】

    • 代码第1,2,4步都涉及到遍历原始数列,运算量都是N;

    • 第3步遍历统计数列,运算量是M;

    • 所以总体运算量是 3N+M,去掉系数,时间复杂度是0(N+M)

    【空间复杂度】

    • 不考虑结果数组,只考虑统计数组大小的话,空间复杂度是O(M)

    # 4. 适用范围

    1.当数列最大最小值差距过大时,并不适用计数排序

    比如给定20个随机整数,范围在0到1亿之间,这时候如果使用计数排序,需要创建长度1亿的数组。不但严重浪费空间,而且时间复杂度也随之升高

    需求 A,为一组给定的手机号排序:

    18914021920

    13223132981

    13566632981

    13660891039

    13361323035

    ........

    ........

    按照计数排序的思路,我们要根据手机号的取值范围,创建一个空数组。

    11 位手机号有多少种组合?恐怕要建立一个大得不可想象的数组,才能装下所有可能出现的 11 位手机号!


    2.当数列元素不是整数,并不适用计数排序

    如果数列中的元素都是小数,比如25.213,或是0.00000001这样子,则无法创建对应的统计数组。这样显然无法进行计数排序。

    需求 B,为一组英文单词排序:

    banana

    apple

    orange

    peach

    cherry

    ........

    ........

    计数排序适合的场景是对整数做排序,如果遇到英文单词,就无能为力了

    编辑 (opens new window)
    上次更新: 2021/06/27, 10:49:09
    二分查找
    基数排序

    ← 二分查找 基数排序→

    最近更新
    01
    匿名内部类
    10-08
    02
    函数式接口
    10-08
    03
    ARouter-Kotlin踩坑
    10-05
    更多文章>
    Theme by Vdoing | Copyright © 2021-2023 iqqcode | MIT License | 备案号-京ICP备2021028793号
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式
    ×