十大排序之计数排序、桶排序、基数排序(详解)

文章目录

  • 🐒个人主页
  • 🏅算法思维框架
    • 📖前言:
  • 🎀计数排序 时间复杂度O(n+k)
      • 🎇1. 算法步骤思想
      • 🎇2.动画实现
      • 🎇 3.代码实现
  • 🎀桶排序
      • 🎇1. 算法步骤思想
      • 🎇2、示意图
      • 🎇3.代码实现
  • 🎀基数排序 (RadixSort)
      • 🏨 基数排序 vs 计数排序 vs 桶排序
      • 🎇1. LSD算法步骤思想(按低位到高位排序)
      • 🎇 3.代码实现

🐒个人主页

🏅算法思维框架

📖前言:

本篇博客主要以介绍十大排序算法中的计数排序桶排序以及基数排序,有详细的图解、动画演示、良好的代码注释,帮助加深对这些算法的理解,进行查漏补缺~

🎀计数排序 时间复杂度O(n+k)

当输入的元素是 n 个 0 到 k 之间的整数时,它的运行时间是 O(n + k)。计数排序不是比较排序,排序的速度快于任何比较排序算法。
计数排序需要拿一个辅助数组来统计待排序数组中元素的数量,再将统计的结果从小到大回填到待排序数组中。

🎇1. 算法步骤思想

(1)找出待排序的数组中最大的元素
(2)统计数组中每个值为i的元素出现的次数,存入数组C的第i项
(3)对所有的计数累加(从C中的第一个元素开始,每一项和前一项相加)
(4)反向填充目标数组:将每个元素i放在新数组的第C(i)项,每放一个元素就将C(i)减去1

在这里插入图片描述
在这里插入图片描述

🎇2.动画实现

在这里插入图片描述

🎇 3.代码实现

    //使用前提:arr【】中的元素介于【0,k】 k值不要太大,// 思路启示:如果元素值介于【-1000,1000】,可以创建一个【0,2000】的辅助数组下标0 对应 -1000平移一下,来统计。回填时再-1000就行了public void sort(int[] arr){if(arr==null||arr.length<2){return;}//利用哈希数组temp[]进行排序,将arr[]中的值作为temp[]的键进行存储,统计其出现的数量int maxVal=arr[0];for (int i = 1; i <arr.length ; i++) {//获取arr[]数组中的最大值maxVal=maxVal<arr[i]?arr[i]:maxVal;}int[] temp=new int[maxVal+1];//哈希数组--统计数量for (int i : arr) {temp[i]+=1;}//进行排序int index=0;for (int i = 0; i <temp.length ; i++) {int count=temp[i];if(count!=0){while (count>0){arr[index++]=i;count--;}}}}

🎀桶排序

桶排序是计数排序的升级版。它利用了函数的映射关系,高效与否的关键就在于这个映射函数的确定。为了使桶排序更加高效,我们需要做到这两点:

• 在额外空间充足的情况下,尽量增大桶的数量
• 使用的映射函数能够将输入的 N个数据均匀的分配到 K 个桶中

同时,对于桶中元素的排序,选择何种比较排序算法对于性能的影响至关重要。

  1. 什么时候最快? 当输入的数据可以均匀的分配到每一个桶中。
  2. 什么时候最慢? 当输入的数据被分配到了同一个桶中。

🎇1. 算法步骤思想

确定桶的个数,以及哪个元素放到哪一个桶里:
假设对介于[0,100)的元素进行排序,要分成十个桶,
【0-9】【10-19】【20-29】…【90-99】
对每一个桶单独排序,因为每个桶里面数据很少,所以排序很快

🎇2、示意图

在这里插入图片描述
🪀桶排序详解

🎇3.代码实现

 public void sort(int[] arr){if(arr==null||arr.length<2){return;}//思路:假设对介于[0,100)的元素进行排序,要分成十个桶,【0~9】【10~19】【20~29】...【90~99】List<Integer>[] bucket=new ArrayList[10];for (int i = 0; i <bucket.length ; i++) {bucket[i]=new ArrayList<>();//生成桶}//将元素放入桶内Arrays.stream(arr).boxed().forEach(item->{bucket[item/10].add(item);});//对每个桶进行排序,由于每个桶的元素很少,故排序很快,这里可以使用任意的排序算法,我先使用内置的库函数来代替任意排序算法了int index=0;//将元素存入arr的下标for (int i = 0; i <bucket.length ; i++) {Collections.sort(bucket[i]);//对每个桶进行排序//放入arr数组中for (int item : bucket[i]) {//拿到这个桶arr[index++]=item;}}}

🎀基数排序 (RadixSort)

原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。基数排序的方式可以采用 LSD(Least significant digital)或MSD(Most significant digital),LSD的排序方式由键值的最右边开始,而MSD则相反,由键值的最左边开始。
(不常用)MSD:先从高位开始进行排序,在每个关键字上,可采用计数排序
(常用)LSD:先从低位开始进行排序,在每个关键字上,可采用桶排序

🏨 基数排序 vs 计数排序 vs 桶排序

这三种排序算法都利用了桶的概念,但对桶的使用方法上有明显差异:

• 基数排序:根据键值的每位数字来分配桶;
• 计数排序:每个桶只存储单一键值;
• 桶排序:每个桶存储一定范围的数值;

🎇1. LSD算法步骤思想(按低位到高位排序)

分步图示说明:设有数组 array = {53, 3, 542, 748, 14, 214, 154, 63, 616},对其进行基数排序:

在这里插入图片描述

在上图中,首先将所有待比较数字统一为统一位数长度,接着从最低位开始,依次进行排序。

按照个位数进行排序。将结果回填到array[]中
按照十位数进行排序。将结果回填到array[]中
按照百位数进行排序。将结果回填到array[]中
排序后,数列就变成了一个有序序列。

🎇 3.代码实现

   //思路:基数排序是在桶排序的基础上进行了优化:// LSD从低位到高位进行的排序:// 原理是先找到数组最大值的位数,分成10个桶,先按照个位数进行桶排序,再进行回填,再按十位数进行桶排序,进行回填...直到按最高位进行排序,进行回填//【基于LSD排序方式实现的基数排序】public void sort(int[] arr){if(arr==null||arr.length<2){return;}//思路:先获取数组中最大值的个数int max=0;for (int i : arr) {//计算值的位数int digt=(i+"").length();max=max<digt?digt:max;}int dev=1;//获取个位,十位,百位...的上的数字for (int i = 0; i <max ; i++) {//进行桶排序List<Integer>[] bucket=new ArrayList[10];for (int j = 0; j < bucket.length; j++) {bucket[j]=new ArrayList<>();//创建桶}//放入桶进行排序for (int item : arr) {bucket[item/dev%10].add(item);}//进行排序+回填int index=0;for (int j = 0; j <bucket.length ; j++) {Collections.sort(bucket[j]);for (int item : bucket[j]) {arr[index++]=item;}}dev*=10;}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/217117.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

list的总结

目录 1.什么是list 1.1list 的优势和劣势 优势&#xff1a; 劣势&#xff1a; 2.构造函数 2.1 default (1) 2.2 fill (2) 2.3 range (3) 2.4 copy (4) 3.list iterator的使用 3.1. begin() 3.2. end() 3.3迭代器遍历 4. list容量函数 4.1. empty() 4.2. siz…

开源vs闭源,处在大模型洪流中,向何处去?

文章目录 一、开源和闭源的优劣势比较1.1 开源优势1.2 闭源的优势 二、开源和闭源对大模型技术发展的影响2.1 数据共享2.2 算法创新2.3 业务拓展2.4 安全性和隐私2.5 社会责任和伦理 三、开源与闭源的商业模式比较3.1 盈利模式3.2 市场竞争3.3 用户生态3.4 创新速度 四&#xf…

基于厨师算法优化概率神经网络PNN的分类预测 - 附代码

基于厨师算法优化概率神经网络PNN的分类预测 - 附代码 文章目录 基于厨师算法优化概率神经网络PNN的分类预测 - 附代码1.PNN网络概述2.变压器故障诊街系统相关背景2.1 模型建立 3.基于厨师优化的PNN网络5.测试结果6.参考文献7.Matlab代码 摘要&#xff1a;针对PNN神经网络的光滑…

Java Web 学习之路(1) —— 前端篇

文章目录 前言1. JS1.1 引入方式1.2 基础语法1.3 函数1.4 对象1.5 事件监听 2. Vue3. Ajax4. Element5. Nginx 前言 在学习后端前&#xff0c;还需要大致了解下前端的一些知识&#xff0c;所以本篇就先快速把前端的一些知识过一遍。本篇不含过多干货和技术知识&#xff0c;仅仅…

python排序算法_归并排序

什么是归并排序&#xff1a; 归并排序是一种基于分治法的排序算法。它的基本思想是将待排序的序列分成若干个子序列&#xff0c;分别进行排序&#xff0c;然后再将已排序的子序列合并成一个有序的序列。 基本思想&#xff1a; 归并排序是用分治思想&#xff0c;分治模式在每一…

Loadrunner安装大全

目录 一 、下载篇 二、安装篇 三、破解篇 四、Loadrunner支持哪些操作系统&#xff1f; 五、安装Loadrunner需要满足哪些系统要求&#xff1f; 六、安装Loadrunner时是否需要注意什么问题&#xff1f; 七、安装完成后如何验证Loadrunner是否正常工作&#xff1f; 八、如…

网络层(IP协议)

文章目录 网络层IP协议IP协议报头32位源IP地址和目的IP地址:为了解决IP地址不够用的情况 IP地址管理子网掩码特殊IP 路由选择(简介) 网络层 网络层主要负责地址管理和路由选择.代表协议就是IP协议. IP协议 IP协议报头 4位版本: 4: 表示IPv4 ; 6: 表示IPv6 4位首部长度: 描述…

今年的校招薪资真的让人咋舌!

秋招接近尾声&#xff0c;各大公司基本也陆续开奖了。这里整理了部分公司的薪资情况&#xff0c;数据来源于 OfferShow 和牛客网。 ps&#xff1a;爆料薪资的几乎都是 211 和 985 的&#xff0c;并不是刻意只选取学校好的。另外&#xff0c;无法保证数据的严格准确性。 淘天 …

[每周一更]-(第74期):Docker-compose 部署Jenkins容器-英文版及错误纠错

1、前文概要 通过物理机部署Jenkins前文已经讲过&#xff08;地址&#xff1a;[Jenkins] 物理机 安装 Jenkins&#xff09;&#xff0c;也已经公司内部平稳运行若干年&#xff0c;考虑到容器化的使用场景&#xff0c;部分项目都采用容器运行&#xff0c;开始考虑部署容器化的J…

tinyViT论文笔记

论文&#xff1a;https://arxiv.org/abs/2207.10666 GitHub&#xff1a;https://github.com/microsoft/Cream/tree/main/TinyViT 摘要 在计算机视觉任务中&#xff0c;视觉ViT由于其优秀的模型能力已经引起了极大关注。但是&#xff0c;由于大多数ViT模型的参数量巨大&#x…

zlmediakit实现rtsp流服务器

本次实现是将内存中的H264数据经过zlmediakit实现为rtsp流。 我是用的是CAPI的方式&#xff0c;将zlmediakit作为一个sdk嵌入到自己的程序中而不是作为一个独立的进进程服务。 1.编译完成zkmedialit后会得到bin include lib三个文件夹如图 其中bin中的MediaServer是作为独立的…

在新疆乌鲁木齐的汽车托运

在新疆乌鲁木齐要托运的宝! 看过来了 找汽车托运公司了 连夜吐血给你们整理了攻略!! ⬇️以下&#xff1a; 1 网上搜索 可以在搜索引擎或专业的货运平台上搜索相关的汽车托运公司信息。在网站上可以了解到公司的服务范围、托运价格、运输时效等信息&#xff0c;也可以参考其他车…