一)算法介绍
计数排序是一种非比较排序算法,也是一种利用了空间换时间的排序算法。
优势:在对一定范围内的整数排序时,时间复杂度为Ο(n+k)(其中k是整数的范围),快于任何比较排序算法。
局限性:
1、只适合整型数据。
2、数组中的元素都必须大于0。
3、不适合空间较小的场景。
二)算法原理
基本原理:
第一步:找出数据中的最大值max和最小值min。
第二步:设定一个基数值,方便存储和获取,一般为0-min;
第三步:申请一个(max-min+1)长度的空间。
第四步:把数据按照一定的规则,放置到申请的空间中,相当于排序。
第五步:从申请的空间中,把数据一个个复制到源数据中。
算法步骤图解:
源数据:int[] nums = {4, 3, 7, 6, 7, 3, 9, 6, 9};
第一步:先找出数据中最大值和最小值,max=9、min=3.;
第二步:设定一个基数值,方便存储和获取,一般为int base=0-min;
第三步:申请一个(max-min+1)长度的空间,如:int[] bucket = new int[max - min + 1];
第四步:把数组中的元素一个个放到bucket数组中,bucket数组中统计了每个数出现的次数。
第五步:再从bucket中把元素一个个重新复制到源数据的数组中。
算法排序效果图:
算法复杂度:
最差情况:T(n) = O(n+k)
最好情况:T(n) = O(n+k)
当输入的元素是n 个0到k之间的整数时,它的运行时间是 O(n + k),其中k是整数的范围。
三)算法源码
步骤简介:先循环查找出数据的最大值和最小值,设定一个基数值,利用基数值把数据一个个存放到申请的bucket空间中,最后再把数据重新复制到源数组中。
/**
* 计数排序
* @param nums
* @return
*/
public static int[] countingSort(int[] nums) {
if (nums == null) {
return null;
}
int base;
int min = nums[0]; // 假设第0个元素为最小值
int max = nums[0]; // 假设第0个元素为最大值
for (int i = 1; i < nums.length; i++) {
if (nums[i] > max) { // 找出数组中最大值
max = nums[i];
}
if (nums[i] < min) { // 找出数组中最小值
min = nums[i];
}
}
base = 0 - min;
// 统计数组中每个元素出现的次数
int[] bucket = new int[max - min + 1];
for (int i = 0; i < nums.length; i++) {
bucket[nums[i] + base]++;
}
// 把数据重新复制到源数组中
int index = 0, i = 0;
while (index < nums.length) {
if (bucket[i] != 0) {
nums[index++] = i - base;
bucket[i]--;
} else {
i++;
}
}
// 返回
return nums;
}
识别二维码关注个人微信公众号
本章完结,待续、欢迎转载!
本文说明:该文章属于原创,如需转载,请标明文章转载来源!