一篇文章带你理解什么是桶排序、计数排序、基数排序

本文详细介绍了桶排序、计数排序和基数排序的思路与区别。桶排序是将元素按值区间划分到不同的桶内,然后对每个桶进行排序。计数排序是一种特殊的桶排序,当桶的个数等于最大值与最小值之差加1时,即为计数排序。基数排序则是按数位进行桶划分,适用于大量数据且范围较小的情况。文章还提供了相应的代码实现。
摘要由CSDN通过智能技术生成

文章名字起得有点膨胀了……
具体能不能理解个人为准哈哈哈哈
原先只学了一个基数排序,写博客总结时又看了计数排序,然后又把桶排序也看了…(我还有头发
———————————————————————————————————————

计数排序和基数排序的区别:

  • 首先,基数排序和计数排序都可以看作是桶排序。

  • 计数排序本质上是一种特殊的桶排序,当桶的个数取最大( maxV-minV+1)的时候,就变成了计数排序。

  • 基数排序也是一种桶排序。桶排序是按值区间划分桶,基数排序是按数位来划分;基数排序可以看做是多轮桶排序,每个数位上都进行一轮桶排序。

普通的桶排序用得并不多,用得比较多的是桶排序的特殊例子:计数排序和基数排序

在学计数排序和基数排序之前,我们先了解一下桶排序的思路。

桶排序的思路:
  • 将待排序元素划分到不同的桶。先扫描一遍序列求出最大值 maxV 和最小值 minV ,设桶的个数为 k ,则把区间 [minV,maxV] 均匀划分成 k 个区间,每个区间就是一个桶。将序列中的元素分配到各自的桶。

  • 对每个桶内的元素进行排序。可以选择任意一种排序算法。

  • 将各个桶中的元素合并成一个大的有序序列。

以下图为例子,1.0和0.0为序列求出最大值 maxV 和最小值 minV。我们把区间[0,1]划分成4个区间,每个区间就是一个桶。将序列中的元素分配到各自的桶,再对每个桶内的元素进行排序
因为每一个桶里面还是需要进行排序,所以普通的桶排序用得并不多。

在这里插入图片描述
———————————————————————————————————————
理解完了桶排序,我们再来看计数排序。
文章开头说过:

  • 计数排序可以看作是桶排序。
  • 计数排序本质上是一种特殊的桶排序,当桶的个数取最大( maxV-minV+1)的时候,就变成了计数排序。

知道了这两点我们就很容易理解什么是计数排序

计数排序本质上是一种特殊的桶排序,当桶的个数最大的时候,就是计数排序。

计数排序的简单介绍:

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

需要注意计数排序适合用在一些 量大范围少 的问题中:

举个例子:
把一个城市的人员年龄进行排序(人的年龄范围少,而人员的数量大)

计数排序的思路:

1 首先创建一个长度为 原数组最大值- 原数组最小值+1 的新数组。
2 遍历原始数组,以元素数组的值放在与新数组下标对应的位置,并将该下标的计数器增1。
3 遍历一遍新数组,按顺序把值放回原始值。

举个例子, nums=[2, 1, 3, 1, 5] , 首先扫描一遍获取最小值和最大值, maxValue=5 , minValue=1 ,于是开一个长度为5的新数组 counter ,

  1. 分配。统计每个元素出现的频率,得到 counter=[2, 1, 1, 0, 1] ,例如 counter[0] 表示值 1 出现了2次,counter[1]表示值 2出现1次,以此类推。
  2. 收集。 counter[0]=2 表示 1 出现了2次,那就向原始数组写入2个1, counter[1]=1 表示 2 出现了1次,那就向原始数组写入一个2,依次类推,最终原始数组变为 [1,1,2,3,5] ,排序好了。

计数排序的思路图解:

需要注意计数排序局限性比较大,只限于对整数进行排序

下面代码实现

/**
	 *  arr[] 需排序数组
	 *  min 数组最小值 
	 *  max 数组最大值
	 */
public static void countingSort(int[] arr, int min, int max) {
   
		int[] count = new int[max - min + 1];// 创建新数组count
		for (int number : arr) {
   //遍历arr数组,取出值给变量number
	/*
	 * 比如{ 2, 1, 3, 1, 5 }数组
	 * 2要放在数新组第2个位置,即在count[2-1]加1
	 * 1要放在数新组第1个位置,即在count[1-1]加1
	 * 以此类推
	 * 
	 */
			count[number-min]++;
		}
		int z = 0;//计算器
		for (int i = min; i <= max; i++
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值