计数排序

2023-05-16

本文内容和代码来自《漫画算法》
之前练习的冒泡排序、鸡尾酒排序、快速排序、堆排序都是基于元素比较和位置元素交换实现的,有一些特殊的排序并不基于元素比较,如计数排序桶排序基数排序
以计数排序来说,这种排序算法是利用数组下标来确定元素的正确位置的。
来看一个例子:
假设有20个随机整数,取值范围0-10,要求用最快的速度把这20个整数从小到大进行排序
建立一个长度为11的数组,下标0-10,元素全为0。
统计数组
假设20个数字如下所示
9,3,5,4,9,1,2,7,8,1,3,6,5,3,4,0,10,9,7,9
下面遍历这个20个元素的数字序列,每一个整数按其值对号入座,同时数组下标的元素进行加1操作。
例如第一个整数是9,那么下标为9的元素加1。
9对号入座
第二个整数是3,那么下标为3的元素加1。
3对号入座
继续遍历并修改数组…
最终当数列修改完毕,数组的状态如下。
最终状态
该数组的每一个下标位置的值代表数列中对应整数出现的次数。有了这个统计结果,排序就很简单了。直接遍历数组,输出数组元素的下标值,元素的值是几,就输出几次。
0 1 1 2 3 3 3 4 4 5 5 6 7 7 8 9 9 9 9 10
显然,现在输出的数列已经是有序的了。
这就是计数排序的基本过程,它适用于一定范围内的整数排序。在取值范围不是很大的情况下,它的性能甚至快过那些时间复杂度为O(nlogn)的排序

后面还有很多图片,就不比着书画了。最主要的还有当有重复数据的时候涉及到的一个顺序的处理。还是看一下原书,更好理解一点。除了重复数据顺序的问题,还有一个就是无需序列不从0开始的情况的处理。
最终的java实现如下

	int[] countSort(int[] arr) {
		// 1.得到数组的最大值、最小值,并算出差值d
		int max = 0, min = 0;
		for (int i = 0; i < arr.length; i++) {
			if (arr[i] > max) {
				max = arr[i];
			}
			if (arr[i] < min) {
				min = arr[i];
			}
		}
		int d = max - min;

		// 2.创建统计数组并统计对应元素的个数
		int[] countArr = new int[d + 1];
		for (int i = 0; i < arr.length; i++) {
			countArr[arr[i] - min]++;
		}
		// 3.统计数组变形,后面的元素等于前面的元素之和
		for (int i = 1; i < countArr.length; i++) {
			countArr[i] += countArr[i - 1];
		}
		// 4.倒序遍历原始数组,从统计数组找到正确的位置,输出到结果数组
		int[] sortedArr = new int[arr.length];
		for (int i = arr.length - 1; i >= 0; i--) {
			sortedArr[countArr[arr[i] - min] - 1] = arr[i];
			countArr[arr[i] - min]--;
		}
		return sortedArr;
	}
	
	@Test
	public void fun1() {
		// int[] arr=new int[]{95,94,91,98,99,90,99,93,91,92};
		int[] arr = new int[] { 49, 38, 65, 97, 76, 13, 27, 49 };
		int[] sortedArr = countSort(arr);
		System.out.println(Arrays.toString(sortedArr));
	}

操作原始数组运算量n,操作统计数列运算量为m
时间复杂度O(n+m)
不考虑结果数组和统计数组,
空间复杂度O(m)
它的时间复杂度是线性级的,然而它的局限性也非常严重
1.当数列最大和最小值差距过大时,并不适合用计数排序
例如给出20个随机整数,范围在0到1亿之间,需要创建1亿个元素的数组,不但严重浪费空间,而且时间复杂度也会随之升高。
2.当数列元素不是整数时,也不适合用计数排序
如果数列中的元素都是小数,如25.213,或0.00 000 001这样的数字,则无法创建对应的统计数组。这样显然无法进行计数排序。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

计数排序 的相关文章

  • 从零开始学习Linux部署Java web项目

    前言 最近越来越发现需要学习的东西太多了 xff0c 前几天公司服务器出现问题 xff0c 需要对服务器硬件进行维护 xff0c 当然服务器上的服务需要部署到另一个服务器上 这对于我来说是很陌生的 xff0c 虽然这件工作没有让我去做 xf
  • 微信小程序分页加载

    分页加载功能大家遇到的应该会经常遇到 xff0c 应用场景也很多 xff0c 例如微博 xff0c QQ xff0c 微信朋友圈以及新闻类应用 xff0c 都会有分页加载的功能 xff0c 这不仅节省了我们用户的流量 xff0c 还提升了用
  • ReactNative ViewPageAndroid组件详解

    源码传送门 在我们开发Android的时候 xff0c ViewPage这个控件的使用频率还是很高的 xff0c 最简单的就是制作引导页 xff0c 应用程序的主界面等 xff0c 在ReactNative开发中实现该功能的组件是ViewP
  • Android自定义数字键盘

    好久没有写Android的文章了 xff0c 有两三个月多了吧 xff0c 刚开始搞微信小程序 xff0c 后来又开搞ReactNative 现在又兴奋的开搞AI机器学习的东西 xff0c 感觉挺有意思的 xff0c 不过AI与其它的东西相
  • ConstraintLayout基础介绍

    自去年Google I O 大会发布ConstraintLayout至今 xff0c 已有一年多的时间 xff0c 但是并没有普及开来 xff0c 了解过ConstraintLayout布局的人知道 xff0c 它的性能的确提升了不少 在前
  • Gson转换报错com.google.gson.JsonSyntaxException

    转载请标明出处 xff1a http blog csdn net xiejinquan article details 52002196 Gson将jsonobject的字符转化为Bean类或者将jsonarray的字符串转化为List l
  • MTK6580调试IMX132流程分析

    MTK6580调试IMX132流程分析 一开始不了解 MTK 的点亮流程 怎么办呢 1 MTK 开机是 首先是 CameraService 先起来 然后就通过获取 HAL 中的 sensorList 中的信息 CameraManager与C
  • 双线性插值算法

    图像的缩放很好理解 就是图像的放大和缩小 传统的绘画工具中 有一种叫做 放大尺 的绘画工具 xff0c 画家常用它来放大图画 当然 xff0c 在计算机上 xff0c 我们不再需要用放大尺去放大或缩小图像了 xff0c 把这个工作交给程序来
  • JAVA字符串判空的方法

    1 记录自己工作中的问题 xff1a 针对某些字符串进行判空时 xff0c 出现的BUG StringUtils hasText StringUtils hasText null 61 false StringUtils hasText 3
  • 出现次数最多的小写字母

    出现次数最多的小写字母 题目描述 输入一个由小写字母组成的字符串 xff08 字符数量 lt 61 100 xff09 xff0c 输出出现次数最多的小写字母 注意 xff1a 如果有多个小写字母出现的次数一样多 xff0c 则输出ASCI
  • EFCore 从入门到精通-6(详谈查询)

    目录 1 初始准备1 1 工具准备1 2 程序准备1 3 准备数据 2 基础回顾以及探寻2 1 单个查询2 2 查询所有的数据 2 3 筛选和过滤查询2 4 探究原理 3 客户端评估和服务端评估3 1 IEnumerable And IQu
  • 【Android解决方案】在onResume里调用getIntent()得到的是上一次数据

    我有四个媒体分类 xff08 Record xff0c Music xff0c Video xff0c Picture xff09 xff0c 里面除了数据不同 xff0c 界面都是相似的 xff0c 所以我把它们用一个MediaActiv
  • pycharm运行停止快捷键

    运行 shift 43 f10 停止 ctrl 43 f2
  • RecyclerView预加载

    private boolean isLoadingMore 61 false 是否预加载 recyclerView addOnScrollListener new RecyclerView OnScrollListener 64 Overr
  • 自定义右侧弹出dialog并填充状态栏

    DialogUtil xff1a public class DialogUtil private Dialog dialog private View inflate public void showRightDialog Context

随机推荐

  • Android监听横竖屏切换

    偶然在项目中用到播放视频时 xff0c 需要横屏将视频全屏播放 xff0c 所以需要监听屏幕的横竖屏切换事件 ConfigChanges xff0c 用于捕获手机状态的改变 xff0c 当横竖屏切换 xff0c 屏幕尺寸变化 xff0c 弹
  • SVN利用 AS 进行代码对比的方法

    第 1 种 xff1a 如果我们是从 SVN 检出的项目 xff0c 并且想比较本地代码与从 SVN 检出时的代码相比都有那些区别 xff0c 可以按如下步骤操作 如上图所示 xff0c 在代码编辑区 xff0c 右键唤出功能菜单 xff0
  • ADB操作命令详解大全

    ADB 操作命令详解及用法大全 Lucas liu的博客 CSDN博客
  • Android Studio build下面找不见assembleDebug选项解决办法

    在开发Android的AAR库时 xff0c 习惯点击右侧gradle面板的Task任务进行编译 xff0c 如选择assembleDebug或assembleRelease进行编译 xff0c 如下 xff1a 说明 xff1a 其中as
  • android 注销到登陆界面实现

    code class java span class hljs keyword public span span class hljs class span class hljs keyword class span span class
  • 中兴2016校招软件在线笔试题

    面试经验可以参考我的另一篇文章 xff0c 是7月初参加openday面试的 xff0c 文章链接http blog csdn net dandelion1314 article details 47009585 招聘群里有人发的招聘时间安
  • 设置AndroidStudio左侧和右侧的字体

    1 File Settings Appearance amp Behavior Appearance xff0c 右边Override default fonts by not recommended 2 设置代码大小 xff1a File
  • Android下载网络资源文件

    直接上代码 xff1a lt uses permission android name 61 34 android permission WRITE EXTERNAL STORAGE 34 gt lt uses permission and
  • 出现:trying to draw too large(138078000bytes) bitmap:错误时

    这里就不翻译了 xff0c 意思就是说你将高分辨率图片放在了低分辨率文件夹下 例如 xff1a 图片的分辨率是属于xxhdpi的 xff0c 而你将这张图片放在了drawable xhdpi或者比这个还低的文件夹下 xff0c 就会报这个错
  • Android把图片压缩到一定大小并不失真

    本文转载只供参考 一 图片压缩方式 图片按比例大小压缩方法 64 param srcPath xff08 根据路径获取图片并压缩 xff09 64 return public static Bitmap getimage String sr
  • Android 动态设置TextView的位置

    RelativeLayout LayoutParams layoutParams 61 new RelativeLayout LayoutParams 40 40 宽高 layoutParams setMargins int dstX 20
  • 神经网络应用较多的算法,图卷积神经网络应用

    神经网络原理及应用 神经网络原理及应用1 什么是神经网络 xff1f 神经网络是一种模拟动物神经网络行为特征 xff0c 进行分布式并行信息处理的算法 这种网络依靠系统的复杂程度 xff0c 通过调整内部大量节点之间相互连接的关系 xff0
  • Java泛型学习

    纯属个人理解 xff0c 代码参考自视频 用途 xff1a 1 用于集合容器中 xff0c 可以使集合记住存储数据的类型 xff0c 防止频繁转换类型可能导致的ClassCastException 用于javac编译器的类型检查 xff0c
  • Java反射学习

    文字和代码来源于视频 反射 xff0c 通过它我们可以得到一个Java类的全部信息 xff0c 可以调用类的普通方法 xff0c 构造方法 xff0c 对类进行实例化 xff0c 操作类的属性 类中的所有内容 xff1a 属性 构造方法 普
  • 面试题之反转单向链表

    题目为 xff1a 将一个单向链表反转 xff0c 写出算法步骤或代码 懵批了 今学习如下 xff0c 文章代码参考https blog csdn net K346K346 article details 93371829 xff0c 感谢
  • 冒泡排序总结

    本文内容和代码均来自于 漫画算法 xff0c 小灰和大黄的对话 xff0c 非常有趣味的一本书 现理论结合实践 xff0c 做一下测试 span class token keyword private span span class tok
  • net6的Web MVC项目实现限流功能

    原理 xff1a 利用MemoryCache服务组件 xff0c 记录用户最后一次访问接口的时间 xff0c 如果本次访问距离最后一次访问不超过1秒 xff0c 提示用户访问过于频繁 xff0c 否则 xff0c 接口可以正常访问 然后利用
  • 快速排序总结

    文章内容和代码来自 漫画算法 和数据结构教材 现进行一下代码编写练习 1 双边循环法 span class token comment 双边循环法 xff0c 从左右两端分别向中间进行比较和交换数据 递归实现 span span class
  • 堆排序总结

    本文内容来源于 漫画算法 和数据结构教材 这里提到的堆是一个二叉堆 xff0c 本质上是一颗完全二叉树 堆排序只需要一个记录大小的辅助空间 1 java实现 span class token comment 下沉调整 64 param ar
  • 计数排序

    本文内容和代码来自 漫画算法 之前练习的冒泡排序 鸡尾酒排序 快速排序 堆排序都是基于元素比较和位置元素交换实现的 xff0c 有一些特殊的排序并不基于元素比较 xff0c 如计数排序 桶排序 基数排序 以计数排序来说 xff0c 这种排序