首页 > 其他分享 >计数排序就是这么容易

计数排序就是这么容易

时间:2023-05-08 11:33:05浏览次数:32  
标签:int 元素 整数 计数 数组 容易 排序

计数排序就是这么容易_计数排序


文章目录

  • 前言
  • 1.计数排序(Counting Sort)
  • 1.1.计数排序(Counting Sort)
  • 2.原理
  • 2.1.步骤
  • 2.2.实例题目
  • 3.代码
  • 3.1.代码
  • 4.扩展阅读
  • 4.1.局限性


前言

声明:参考来源互联网,有任何争议可以留言。站在前人的肩上,我们才能看的更远。

本教程纯手打,致力于最实用教程,不需要什么奖励,只希望多多转发支持。
欢迎来我公众号,希望可以结识你,也可以催更,微信搜索:JavaPub

有任何问题都可以来谈谈 !

计数排序就是这么容易_计数排序_02

计数排序是比较容易的排序算法,但是对数量级较小的整数排序很实用。

1.计数排序(Counting Sort)

1.1.计数排序(Counting Sort)

计数排序是一个非基于比较的排序算法,该算法于1954年由 Harold H. Seward 提出。它的优势在于在对一定范围内的整数排序时,它的复杂度为 Ο(n+k)(其中k是整数的范围),快于任何比较排序算法。当然这是一种牺牲空间换取时间的做法,而且当 O(k)>O(n*log(n)) 的时候其效率反而不如基于比较的排序(基于比较的排序的时间复杂度在理论上的下限是O(n*log(n)), 如 归并排序,堆排序)

例如:计数排序是用来排序0到100之间的数字的最好的算法,但是它不适合按字母顺序排序人名。但是,计数排序可以用在基数排序中的算法来排序数据范围很大的数组。

  • 计数排序是一个简单的排序算法,看下边原理很容易理解。

2.原理

2.1.步骤

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

计数排序就是这么容易_排序算法_03

如果有疑问,看下边一个例子

2.2.实例题目

题目:数组里有20个随机数,取值范围为从0到10,要求用最快的速度把这20个整数从小到大进行排序。

无论是归并排序,冒泡排序还是快速排序等等,都是基于元素之间的比较来进行排序的。但是有一种特殊的排序算法叫计数排序,这种排序算法不是基于元素比较,而是利用 数组下标 来确定元素的正确位置。

通过计数排序特性分析题目,我们知道整数的取值范围是从0到10,那么这些整数的值肯定是在0到10这11个数里面。于是我们可以建立一个长度为11的数组,数组下标从0到10,元素初始值全为0,如下所示:

计数排序就是这么容易_计数排序_04

先假设20个随机整数的值是: 9, 3, 5, 4, 9, 1, 2, 7, 8,1,3, 6, 5, 3, 4, 0, 10, 9, 7, 9

  • 让我们先遍历这个无序的随机数组,每一个整数按照其值对号入座,对应数组下标的元素进行 加1 操作。

比如第一个整数是 9,那么数组下标为 9 的元素加 1:

计数排序就是这么容易_计数排序_05

  • 第二个整数是3,那么数组下标为 3 的元素加 1:

计数排序就是这么容易_排序算法_06

  • 继续遍历数列并修改数组…

最终,数列遍历完毕时,数组的状态如下:

计数排序就是这么容易_计数排序_07

数组中的每一个值,代表了数列中对应整数的出现次数。

有了这个统计结果,排序就很简单了,直接遍历数组,输出数组元素的下标值,元素的值是几,就输出几次:

0, 1, 1, 2, 3, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, 9, 9, 9, 9, 10

这就是计数排序的基本过程,它适用于一定范围的整数排序。在取值范围不是很大的情况下,它的性能在某些情况甚至快过那些O(nlogn)的排序,例如快速排序、归并排序。

3.代码

3.1.代码

@Test
public void sortJavaPub(){
	int [] array = {2,1,5,3,4};
	//1.得到数列的最大值
	int max = array[0];
	for (int i = 1; i < array.length; i++) {
		if (array[i] > max)
			max = array[i];
	}
	//2.根据数列的最大值确定统计数组的长度
	int[] coutArray = new int[max + 1];
	//3.遍历数列,填充统计数组
	for(int i = 0; i < array.length; i++)
		coutArray[array[i]]++;

	//4.遍历统计数组,输出结果
	int index = 0;
	int[] sortedArray = new int[array.length];
	for (int i = 0; i < coutArray.length; i++) {
		for (int j = 0; j < coutArray[i]; j++) {
			sortedArray[index++] = i;
		}
	}
	System.out.println(Arrays.toString(sortedArray));
}

返回结果:

[1, 2, 3, 4, 5]

4.扩展阅读

4.1.局限性

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

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

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

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

标签:int,元素,整数,计数,数组,容易,排序
From: https://blog.51cto.com/wangshiyu/6253299

相关文章

  • C# DataGridView自定义排序
    privatevoiddgvScanFai_SortCompare(objectsender,DataGridViewSortCompareEventArgse){if(e.Column.Name=="Time"){stringcellValue1=e.CellValue1.ToString();stringcellValu......
  • draggable 组件使用(拖拽排序及拖拽交换功能 swap)
    一、template里<draggable v-model="myArray" group="people" @start="drag=true" @end="drag=false"> <divv-for="elementinmyArray":key="element.id">{{element.name}}</......
  • Axure 9的中继器排序问题
    问题如图所示,有一个下拉列表,可按价格排序、销量排序、综合排序,具体事件交互已经在Axure9中制作完毕,并且,逻辑已经检查无误了,但是呢,在浏览器预览,选择条件排序时,却始终无法使得数据变动排序解决可能有如下原因:所需要排序的条件可能存在非数值(如,中文什么的),将数据修正即可......
  • 冒泡排序
    voidbubble_sort(intarr[],intsz)//这里的arr[]传递的是首地址{ inti=0;for(i=0;i<sz-1;i++)//一共进行多少趟 {intj=0;for(j=0;j<sz-1-i;j++)//每一趟进行多少次冒泡排序 { if(arr[j]>arr[j+1])//如果判定条件成立将上一个数值赋值给下一个数值{ int......
  • 6 排列与组合:排序、排位、排
    计算排位数目如要算出n个独立对象的排名方式的确切数目,可按下式进行计算:n!=n×(n-1)x(n-2)x…×3×2×1圆形排位如果有个对象需要进行圆形排位,则可能的排位数目按下式进行计算:(n-1)!按类型排位练习:排列排列是指从一个较大(n个)对象群体中取出一定数目(r个)对象进行排......
  • 数学建模论文排版(公式自动排序)
    本文为学习清风数学建模排版的公式编号部分的笔记配套资料可以在微信公众号《数学建模学习交流》后台发送“论文排版”免费获取。步骤先插入一个“无边框“,“格式居中”表格如图(表格工具——布局——查看网格线),并随便在第一列输入公式,第二列输入(),并将光标放到括号里然后插入—......
  • 算法 | 快速排序详解
    1快速排序基本思想从待排序记录序列中选取一个记录(随机选取)作为基点,其关键字设为key,然后将其余关键字小于key的记录移到前面,而将关键字大于key的记录移到后面,结果将待排序记录序列分为两个子表,最后将关键字key的记录插入到分界线的位置。这个过程称为一趟快速排序。经过这一趟......
  • 【二分查找】LeetCode 33. 搜索旋转排序数组思路
    题目链接33.搜索旋转排序数组思路思路都在注释里代码classSolution{publicintsearch(int[]nums,inttarget){intlen=nums.length;if(len==0){return-1;}intleft=0,right=len-1;//1.......
  • mysql 查询根据外部数据排序
    1、FIELD函数FIELD是一个MySQL函数,用于返回一个或多个表达式在列表中的位置。它可以用于对查询结果进行排序或筛选。2、根据外部数据排序在MySQL中,可以使用ORDERBYFIELD()函数根据外部数据对查询结果进行排序。FIELD()函数可以接受一个或多个参数,并返回第一个参数在......
  • 合并k个已排序的链表
    描述合并k 个升序的链表并将结果作为一个升序的链表返回其头节点。 数据范围:节点总数 0≤n≤5000,每个节点的val满足∣val∣<=1000要求:时间复杂度 O(nlogn) 示例输入:[{1,2},{1,4,5},{6}]返回值:{1,1,2,4,5,6} 算法思想1、将k个链表两两进行合并(采用顺......