计数排序+桶排序+基数排序 详讲(思路+图解+代码详解)

文章目录

  • 计数排序+桶排序+基数排序
    • 一、计数排序
          • 概念:
          • 写法一:
          • 写法二:
    • 二、桶排序
        • 概念
        • 代码
    • 三、基数排序
      • 概念
      • 1.LSD排序法(最低位优先法)
      • 2.MSD排序法(最高位优先法)
    • 基数排序VS基数排序VS桶排序


计数排序+桶排序+基数排序


一、计数排序

在这里插入图片描述

  • 时间复杂度:
  • 空间复杂度:
  • 稳定性:稳定
概念:
  • 非基于比较的排序

  • 计数排序又称为鸽巢原理,是对哈希直接定址法的变形应用

    1.统计相同元素出现的个数

    2.根据统计的结果将序列回收到原来的序列中

  • 计数排序使用的场景:给出指定范围内的数据进行排序

  • 使用场景:一组集中在某个范围内的数据

写法一:
  • 通过遍历计数数组,循环输出计数数组存的次数

在这里插入图片描述

  • 1.遍历数组找到最小值最大值
  • 2.根据最大最小值,申请一个计数数组
  • 3.遍历待排数组进行计数
  • 4.遍历计数数组进行输出
 /*** 计数排序*无法保证稳定* @param array*/public static void countSort2(int[] array) {//1.遍历数组找到最大值和最小值int MAX = array[0];int MIN = array[0];for (int i = 1; i < array.length; i++) {if (array[i] > MAX) {MAX = array[i];}if (array[i] < MIN) {MIN = array[i];}}//2.根据最大最小值,申请一个计数数组int len = MAX - MIN + 1;//长度int[] count = new int[len];//3. 遍历待排数组进行计数for (int i = 0; i < array.length; i++) {count[array[i] - MIN]++;}//4.遍历计数数组进行输出int index = 0;//array数组新的下标for (int i = 0; i < count.length; i++) {while (count[i] > 0) {array[index] = i + MIN;//+最小值,求出真正的数count[i]--;index++;}}}
写法二:
  • 写定数组的大小,用临时数组存储结构
  • 计算每个元素在排序后的数组中的最终位置
  • 根据计数数组将元素放到临时数组b中,实现排序
  • 从后往前,根据原来数组的内容,在计数数组中找到要填写在b数组中的位置,
  • 计数数组记录的不再是数字出现是次数,而是应该在数组中存放的位置下标

在这里插入图片描述

 /*** 计数排序*稳定* @param array*/public static void countSort(int[] array) {int len = array.length;final int MAX = 256;//常量确定数组大小int[] c = new int[MAX];//计数数组int[] b = new int[MAX];//临时数组,存放结果//统计每个元素的出现次,进行计数for (int i = 0; i < len; i++) {c[array[i]]++;// 将a[i]作为索引,对应计数数组c中的位置加1}// 计算每个元素在排序后的数组中的最终位置for (int i = 1; i < MAX; i++) {c[i] += c[i - 1];// 计数数组中每个元素的值等于它前面所有元素的值之和}// 根据计数数组将元素放到临时数组b中,实现排序for (int i = len - 1; i >= 0; i--) {b[c[array[i]] - 1] = array[i];// 将a[i]放入临时数组b中的正确位置c[array[i]]--;// 对应计数数组c中的位置减1,确保相同元素能够放在正确的位置}// 将临时数组b中的元素复制回原数组a,完成排序for (int i = 0; i < len; i++) {array[i] = b[i];}}

二、桶排序

概念

划分多个范围相同的区间,每个子区间自排序,最后合并

  • 桶排序是计数排序的扩展版本,计数排序:每个桶只存储单一键值

  • 桶排序: 每个桶存储一定范围的数值,确定桶的个数和范围

  • 将待排序数组中的元素映射到各个对应的桶中,对每个桶进行排序

  • 最后将非空桶中的元素逐个放入原序列中

在这里插入图片描述

代码
    public static void bucketSort(int[] array){// 计算最大值与最小值int max = Integer.MIN_VALUE;int min = Integer.MAX_VALUE;for(int i = 0; i < array.length; i++){max = Math.max(max, array[i]);min = Math.min(min, array[i]);}// 计算桶的数量int bucketNum = (max - min) / array.length + 1;ArrayList<ArrayList<Integer>> bucketArr = new ArrayList<>(bucketNum);for(int i = 0; i < bucketNum; i++){bucketArr.add(new ArrayList<Integer>());}// 将每个元素放入桶for(int i = 0; i < array.length; i++){int num = (array[i] - min) / (array.length);bucketArr.get(num).add(array[i]);}// 对每个桶进行排序for(int i = 0; i < bucketArr.size(); i++){Collections.sort(bucketArr.get(i));}// 将桶中的元素赋值到原序列int index = 0;for(int i = 0; i < bucketArr.size(); i++){for(int j = 0; j < bucketArr.get(i).size(); j++){array[index++] = bucketArr.get(i).get(j);}}}

三、基数排序

概念

  • 基数排序是一种非比较型整数排序算法

  • 将整数按位数切割成不同的数字,然后按每个位数分别比较

  • 使用场景:按位分割进行排序,适用于大数据范围排序,打破了计数排序的限制

  • 稳定性:稳定

  • 按位分割技巧:arr[i] / digit % 10,其中digit为10^n。

在这里插入图片描述

1.LSD排序法(最低位优先法)

  • 从最低位向最高位依次按位进行计数排序。

  • 进出的次数和最大值的位数有关

  • 桶可以用队列来表示

  • 数组的每个元素都是队列

在这里插入图片描述

  • 1.先遍历找到最大值
  • 2.求出最高位

在这里插入图片描述

    public static void radixSortR(int[] array) {//10进制数,有10个桶,每个桶最多存array.length个数int[][] bucket = new int[10][array.length];//桶里面要存的具体数值int[] bucketElementCounts = new int[10];//用来计算,统计每个桶所存的元素的个数,每个桶对应一个元素//1.求出最大数int MAX = array[0];for (int i = 1; i < array.length; i++) {if (array[i] > MAX) {MAX = array[i];}}//求最大值的位数,先变成字符串,求字符串长度int MAXCount = (MAX + "").length();//最大位数的个数,进行几次计数排序for (int i = 0; i < MAXCount; i++) {//i代表第几次排序//放进桶中for (int k = 0; k < array.length; k++) {//k相当于遍历待排数值//array[k] /(int) Math.pow(10, i)%10 求出每次要比较位的数//求的是个位,并且是对应趟数的个位int value = (array[k] / (int) Math.pow(10, i)) % 10;//根据求出的位数,找到对应桶,放到对应桶的位置bucket[value][bucketElementCounts[value]] = array[k];//不管value 为多少,bucketElementCounts[value]的值都为0//相当于存到对应桶的0位bucket[value][0]bucketElementCounts[value]++; //从0->1//对应桶的技术数组开始计数}//取出每个桶中的元素,赋值给数组int index = 0;//array新的下标for (int k = 0; k < bucketElementCounts.length; k++) {//遍历每个桶if (bucketElementCounts[k] != 0) {//桶里有元素for (int j = 0; j < bucketElementCounts[k]; j++) {//比那里每个桶的元素array[index] = bucket[k][j];index++;}}bucketElementCounts[k] =0;//每个桶遍历完后,清空每个桶的元素;}}}

2.MSD排序法(最高位优先法)

在这里插入图片描述

  • 从最高位向最低位依次按位进行排序。
  • 按位递归分组收集
  • 1.查询最大值,获取最高位的基数
  • 2.按位分组,存入桶中
  • 3.组内元素数量>1,下一位递归分组
  • 4.组内元素数量=1.收集元素
   /*** 基数排序--MSD--递归* @param array*/public static void radixSortMSD(int[] array) {//1.求出最大数int MAX = array[0];for (int i = 1; i < array.length; i++) {if (array[i] > MAX) {MAX = array[i];}}//求最大值的位数,先变成字符串,求字符串长度int MAXCount = (MAX + "").length();// 计算最大值的基数int radix = new Double(Math.pow(10, MAXCount - 1)).intValue();int[] arr = msdSort(array, radix);System.out.println(Arrays.toString(arr));}public static int[] msdSort(int[] arr, int radix){// 递归分组到个位,退出if (radix <= 0) {return arr;}// 分组计数器int[] groupCounter = new int[10];// 分组桶int[][] groupBucket = new int[10][arr.length];for (int i = 0; i < arr.length; i++) {// 找分组桶位置int position = arr[i] / radix % 10;// 将元素存入分组groupBucket[position][groupCounter[position]] = arr[i];// 当前分组计数加1groupCounter[position]++;}int index = 0;int[] sortArr = new int[arr.length];// 遍历分组计数器for (int i = 0; i < groupCounter.length; i++) {// 组内元素数量>1,递归分组if (groupCounter[i] > 1) {int[] copyArr = Arrays.copyOf(groupBucket[i], groupCounter[i]);// 递归分组int[] tmp = msdSort(copyArr, radix / 10);// 收集递归分组后的元素for (int j = 0; j < tmp.length; j++) {sortArr[index++] = tmp[j];}} else if (groupCounter[i] == 1) {// 收集组内元素数量=1的元素sortArr[index++] = groupBucket[i][0];}}return sortArr;}

基数排序VS基数排序VS桶排序

  • 都是非比较型排序

  • 三种排序算法都利用了桶的概念

    1.计数排序:每个桶只存储单一键值;

    2.基数排序:根据键值的每位数字来分配桶

    3.桶排序: 每个桶存储一定范围的数值;

点击移步博客主页,欢迎光临~

偷cyk的图

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

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

相关文章

内容营销频频出圈,这些品牌号做对了什么?

小红书拥有大量的年轻用户&#xff0c;通过运营品牌号既能降低投放成本&#xff0c;又能更好地连接消费者和品牌&#xff0c;在平台完成一站式闭环营销。 今天就借助几个成功案例&#xff0c;来分析下他们是如何搭建官方账号&#xff0c;通过内容运营吸引更多用户&#xff0c;实…

一款专为POS机设计的芯片解决方案

一、基本概述 HCM8003设计用于磁条读卡器系统。它会从F/2F恢复时钟和数据信号磁产生的数据流头HCM8003将用于数据速率从200到15000比特每秒。 二、典型电路 内部数据的采集和跟踪这个范围是自动的。可以应用于POS机终端设备、磁卡门禁系统、身份识别等场合。 三、引脚定义 四…

redis的主从复制,哨兵模式

1.主从复制 主从复制&#xff1a;主从复制是redis实现高可用的基础&#xff0c;哨兵模式和集群都是在主从复制的基础之上实现高可用 主从复制实现数据的多机备份&#xff0c;以及读写分离&#xff08;主服务器负责写&#xff0c;从服务器只能读&#xff09; 缺陷&#xff1a…

PyTorch基本操作和工作流程

1. PyTorch基础 张量&#xff08;Tensors&#xff09;&#xff1a; 学习 PyTorch 中表示数据的基本单元。了解如何创建、操作和使用张量。 自动微分&#xff08;Autograd&#xff09;&#xff1a; 了解 PyTorch 的自动微分机制&#xff0c;这是训练神经网络的核心。 模型定义…

Android registerForActivityResults使用详解以及实现原理

registerForActivityResult 使用用途是监听Activity结果。 以下是使用样例 //需要传递Request用于解析Intent和解析上个Activity返回的结果 val launchdata = registerForActivityResult<PickVisualMediaRequest, Uri?>(ActivityResultContracts.PickVisualMedia()) {…

中国人工智能系列白皮书 AIGC

https://www.caai.cn/index.php?s/home/article/detail/id/3188.html

【git】使用ssh

前言 git之前一直使用https&#xff0c;因为很方便随时随地都可以用。最近把代码托管到GitHub&#xff0c;使用https就使用不了。后面听同事说GitHub使用ssh是没问题的&#xff0c;就想着尝试一下。 git ssh配置 设置用户名和邮箱 git config --global use.name username g…

OpenCV实现图像噪声、去噪基本方法

一、噪声分类 1、高斯噪声 指服从高斯分布&#xff08;正态分布&#xff09;的一类噪声&#xff0c;其产生的主要原因是由于相机在拍摄时视场较暗且亮度不均匀造成的&#xff0c;同时相机长时间工作使得温度过高也会引起高斯噪声&#xff0c;另外电路元器件白身噪声和互相影响…

acwing算法基础之数学知识--求组合数基础版

目录 1 基础知识2 模板3 工程化 1 基础知识 &#xff08;一&#xff09; 组合数 C n k C_n^k Cnk​的计算公式&#xff0c; C n k n ⋅ ( n − 1 ) ⋯ ( n − k 1 ) 1 ⋅ 2 ⋯ k C_n^k\frac{n\cdot(n-1)\cdots(n-k1)}{1\cdot 2\cdots k} Cnk​1⋅2⋯kn⋅(n−1)⋯(n−k1)​ …

laravel-admin导出excel全部,表中无id列导出失败

laravel-admin导出excel时&#xff0c;导出全部数据&#xff0c;但是表中没有id字段&#xff0c;然后就无法导出excel&#xff1b; 就直接显示 一开始我也很着急&#xff0c;弄了半天还是不行&#xff0c;然后重写还是有问题 最后发现底层代码排序是按照id排序的orderBy(id, a…

Unity地面交互效果——6、地形动态顶点置换和曲面细分

回到目录 Unity置换贴图局部距离曲面细分 大家好&#xff0c;我是阿赵。   这篇文章是我无聊的时候做了一个demo&#xff0c;觉得挺有趣&#xff0c;于是就发上来。这里面包含了4个内容&#xff1a;置换贴图、顶点偏移、局部曲面细分&#xff0c;曲面细分按距离调整强度。 …

JVS低代码表单设计:数据联动详解(多级数据级、数据回显等)

在这信息化时代&#xff0c;表单作为数据的收集和展示工具&#xff0c;已经渗透到不同的角落。JVS低代码对表单的设计和操作进行了不断的优化和创新。其中&#xff0c;联动回显作为一项重要的功能&#xff0c;无论是多级数据级联控制、组件的联动控制&#xff0c;还是多表的数据…

【0基础学Java第三课】-- 运算符

3. 运算符 3.1 什么是运算符3.2 算术运算符3.2.1 **基本四则运算符&#xff1a;加减乘除模( - * / %&#xff09;**3.2.2 增量运算符 - * %3.2.3 自增/自减运算符 -- 3.3 关系运算符3.4逻辑运算符(重点)3.4.1 逻辑与 &&3.4.2 逻辑 ||3.4.3逻辑非 !3.4.4 短路求值 3.5 …

DBS note4:Buffer Management

目录 1、介绍 2、缓冲池 3、处理页面请求 4、LRU替换和时钟策略 1&#xff09;顺序扫描性能 - LRU 5、最近最常使用替换策略&#xff08;MRU Replacement&#xff09; 1&#xff09;Sequential Scanning Performance - MRU 6、练习题 1&#xff09;判断真假 2&#xf…

华清远见嵌入式学习——网络编程——作业4

作业要求&#xff1a;①使用IO多路复用中的select函数实现TCP并发服务器客户端 ②使用IO多路复用中的poll函数实现TCP并发服务器的服务器端 一、 代码 #include <myhead.h>#define SERPORT 8888 //服务器端口号 #define SERIP "192.168.114.113"…

Samsung下origen中uboot的配置与编译

uboot的特点&#xff1a; n代码结构清晰 n 支持丰富的处理器与开发板&#xff0c;易于移植 n 支持丰富的用户命令 n 支持丰富的网络协议 n 支持丰富的文件系统 n 支持丰富的设备驱动 n 更新活跃、用户较多、资料丰富 n 开放源代码 n 较高的稳定性 n 不具有通用性&#xff08;不…

JavaScript编程基础 – 布尔值(Booleans)

JavaScript编程基础 – 布尔值(Booleans) Javascript Programming Essentials – Booleans 一个JavaScript布尔值包含两个值中的一个&#xff0c;即 true 或者 false。 本文简要介绍JavaScript布尔值的具体应用&#xff0c;以及可能作为对象的布尔值等。 1. 布尔值(Booleans)…

Go语言超全详解(入门级)

文章目录 1. Go语言的出现2. go版本的hello world3. 数据类型3.0 定义变量3.0.1 如果变量没有初始化3.0.2 如果变量没有指定类型3.0.3 :符号3.0.4 多变量声明3.0.5 匿名变量3.0.6 变量作用域 3.1 基本类型3.2 指针3.2.1 指针声明和初始化3.2.2 空指针 3.3 数组3.3.1 声明数组3.…

java+mysql的校园兼职微信小程序(附源码 调试 文档)

校园兼职微信小程序 摘要一、引言二、国内外研究现状三、系统设计四、系统实现与界面展示五、源码获取 摘要 本文详述了一个基于Java和MySQL数据库技术的校园兼职微信小程序的毕业设计。系统主要分为三种用户角色&#xff1a;管理员、学生用户和商家用户。管理员拥有学生管理、…