排序之计数排序

简介: 排序之计数排序

꒰˃͈꒵˂͈꒱ write in front ꒰˃͈꒵˂͈꒱

ʕ̯•͡˔•̯᷅ʔ大家好,我是xiaoxie.希望你看完之后,有不足之处请多多谅解,让我们一起共同进步૮₍❀ᴗ͈ . ᴗ͈ აxiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客

本文由xiaoxieʕ̯•͡˔•̯᷅ʔ 原创 CSDN 如需转载还请通知˶⍤⃝˶

个人主页xiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客

系列专栏:xiaoxie的JAVA系列专栏——CSDN博客●'ᴗ'σσணღ*

我的目标:"团团等我💪( ◡̀_◡́ ҂)"

( ⸝⸝⸝›ᴥ‹⸝⸝⸝ )欢迎各位→点赞👍 + 收藏⭐️ + 留言📝+关注(互三必回)!

一.计数排序概念

计数排序是一种非比较性的排序算法,它的基本思想是通过统计一个数组中每个元素出现的次数,然后根据这个统计信息将数组中的元素按照顺序排列这个方法待排序数组的范围不是很大且元素都是非负整数的情况下,具有较高的排序效率。

1.过程

1.找出待排序的数组中最大和最小的元素

2.统计数组中每个值为i的元素出现的次数,存入数组C的第i项

3.对所有的计数累加(从C中的第一个元素开始,每一项和前一项相加)

4.反向填充目标数组:将每个元素i放在新数组的第C(i)项,每放一个元素就将C(i)减去1

2.图解过程

如下图,A为待排序的数组,C记录A中各个值的数目。

将C[i]转换为值小于等于i的元素个数。

为数组A从后向前的每个元素找到对应的B中的位置,每次从A中复制一个元素到B中,C中相应的计数减一。

当A中的元素都复制到B中后,B就是排序好的结果,如图所示

3.代码

1.Java版本

  public static void countSort(int[] array) {
        //1.求最值 -> O(n)
        int min = array[0];
        int max = array[0];
        for (int i = 1; i < array.length; i++) {
            if(min > array[i]) {
                min = array[i];
            }
            if(max < array[i]) {
                max = array[i];
            }
        }
        //2、定义计数数组 进行初始化   -> O(n)
        int[] count = new int[max-min+1];
 
        for (int i = 0; i < array.length; i++) {
            int index = array[i]-min;
            count[index]++;
        }
 
        //3、遍历计数数组   -> O(max-min) :max-min-》范围
        int k = 0;//表示array数组的下标
        for (int i = 0; i < count.length; i++) {
            while (count[i] != 0) {
                array[k] = i + min;
                k++;
                count[i]--;
            }
        }
    }

2.C++版本

#include <iostream>
using namespace std;
 
void countSort(int array[], int n) {
    // 1. 求最值 -> O(n)
    int min = array[0];
    int max = array[0];
    for (int i = 1; i < n; i++) {
        if (min > array[i]) {
            min = array[i];
        }
        if (max < array[i]) {
            max = array[i];
        }
    }
 
    // 2、定义计数数组 进行初始化   -> O(n)
    int count[max - min + 1] = {0};
 
    for (int i = 0; i < n; i++) {
        int index = array[i] - min;
        count[index]++;
    }
 
    // 3、遍历计数数组   -> O(max - min)
    int k = 0; // 表示array数组的下标
    for (int i = 0; i < count.size(); i++) {
        while (count[i] != 0) {
            array[k] = i + min;
            k++;
            count[i]--;
        }
    }
}
 

4.时间复杂度

计数排序的时间复杂度为O(n+k),其中n是待排序数组的大小,k是待排序数组中的最大值减最小值加1(即数组的取值范围)。计数排序的时间复杂度是线性的,不受待排序数组的分布情况的影响。但是,计数排序只适用于整数排序且取值范围不大的情况,对于较大范围的整数排序,计数排序的空间复杂度会较高不适用于大规模数据的排序

5.空间复杂度

计数排序的空间复杂度为 O(k),其中 k 是输入数组中不同数值的最大值与最小值之差加一,即 k = max - min + 1。在上述代码实现中,用于存储计数的数组 count 的大小就是 max - min + 1

另外,在实际实现中,如果输入数组非常大而数值范围相对较小,空间复杂度上的这个 k 可能远小于 n(输入数组的长度),因此相比于原数组大小 n,计数排序的空间需求可能较低。但如果数值范围与数组长度相近或更大时(即 k ≈ n 或 k > n),则空间复杂度接近于 O(n)

6.稳定性

稳定的排序

感谢你的阅读

 

 

 


相关文章
leetcode-72:编辑距离
leetcode-72:编辑距离
93 0
|
人工智能 编解码 自然语言处理
AI文生图模型DALL·E 3
8月更文挑战第15天
|
人工智能 网络协议 Android开发
国内首个!高通量以太网协议标准正式发布
近日,在CCF全国高性能计算学术年会上,阿里云、中国科学院计算技术研究所等40余家机构举办发布会,联合发布国内首个高通量以太网ETH+协议标准,可实现集合通信性能30%的提升。
905 7
|
机器学习/深度学习 算法 关系型数据库
【博士每天一篇文献-实验】Is a Modular Architecture Enough?
本文探讨了模块化架构在机器学习中的有效性,通过实验展示了模块化系统在特定任务中通过专业化显著提升性能的潜力,并提出了评估模块化架构性能的新指标,同时指出了当前系统在泛化和性能上的局限性。
72 2
【博士每天一篇文献-实验】Is a Modular Architecture Enough?
zookeeper查看版本的一些基本信息
zookeeper查看版本的一些基本信息
900 0
|
人工智能 Go
Go 等待协程完成
Go 等待协程完成
71 0
|
XML 小程序 JavaScript
小程序页面传值
本文介绍了微信小程序中父子页面的传值方法。父页面向子页面传值可通过绑定事件跳转,使用`data-`属性传递参数,然后在子页面的`onLoad`中接收。子页面向父页面传值则通过用户选择内容后调用父页面的方法,利用`getCurrentPages()`获取父页面实例,进而修改父页面的数据。
157 2
|
存储 自然语言处理 语音技术
Transformers 4.37 中文文档(七十八)(2)
Transformers 4.37 中文文档(七十八)
68 0
|
前端开发 JavaScript 程序员
手摸手教你使用WebSocket[其实WebSocket也不难]
前言 在本篇文章之前,WebSocket很多人听说过,没见过,没用过,以为是个很高大上的技术,实际上这个技术并不神秘,可以说是个很容易就能掌握的技术,希望在看完本文之后,马上把文中的栗子拿出来自己试一试,实践出真知。 WebSocket解决了什么问题: 客户端(浏览器)和服务器端进行通信,只能由客户端发起ajax请求,才能进行通信,服务器端无法主动向客户端推送信息。 当出现类似体育赛事、聊天室、实时位置之类的场景时,客户端要获取服务器端的变化,就只能通过轮询(定时请求)来了解服务器端有没有新的信息变化。
800 1
|
负载均衡 算法 Java
SDK并发调用优化方案
SDK并发调用优化方案