图解排序算法:计数排序
Posted 纯文笔记
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了图解排序算法:计数排序相关的知识,希望对你有一定的参考价值。
基本思想
计数排序是一个非基于比较的排序算法,该算法于1954年由 Harold H. Seward 提出。它的优势在于在对一定范围内的整数排序时,它的复杂度为Ο(n+k)(其中k是整数的范围),快于任何比较排序算法。当然这是一种牺牲空间换取时间的做法。
其基本思想是对于给定的输入序列中的每一个元素x,确定该序列中值小于x的元素的个数(此处并非比较各元素的大小,而是通过对元素值的计数和计数值的累加来确定)。一旦有了这个信息,就可以将x直接存放到最终的输出序列的正确位置上。
图解排序
图解说明
根据图解过程发现,我们采用计数排序需要知道一些前提条件。
例如数组中的最大值与最小值。所以写代码时,显然这个是需要作为形参手动传入的。
当然,也有人想,我何必用肉眼去观察呢,可以用其它排序手法写个程序找出其最大值最小值,再传入此处啊。认真思考一下,这样多没意思啊,其它排序手法直接就可以排好序啊,真这样做又何必多此一举再用计数排序呢。
所以,这里其实引申出了计数排序的使用场景。就是无论数列有多少元素,其最大值最小值应当容易辨别。例如高中生考试的总分数,显然用0-750就OK啦;又比如一群人的年龄,用个0-150应该就可以了,再不济就用0-200喽。
除了最值容易辨别外,还有个暗含条件是,最大值最小值不能相差太大,否则需要消耗很多的资源。例如数组{1,20000000,5,8},最大值最小值容易辨别,但!如果用计数排序,那么新建计数数组的长度是2千万,显然这种场景不应该采用计数排序。
核心代码
public static void countSort(int[] a, int max, int min) {
int[] b = new int[a.length];//存储数组
int[] count = new int[max - min + 1];//计数数组
int[] sum = new int[max - min + 1];//加总数组
for (int num = min; num <= max; num++) {
//初始化各元素值为0,数组下标从0开始因此减min
count[num - min] = 0;
}
for (int i = 0; i < a.length; i++) {
int num = a[i];
count[num - min]++;//每出现一个值,计数数组对应元素的值+1
}
sum[0] = count[0];
for (int num = min + 1; num <= max; num++) {
//加总数组元素的值为计数数组对应元素及左边所有元素的值的总和
sum[num - min] = sum[num - min - 1] + count[num - min];
}
for (int i = 0; i < a.length; i++) {
int num = a[i];//源数组第i位的值
int index = sum[num - min] - 1;//加总数组中对应元素的下标
b[index] = num;//将该值存入存储数组对应下标中
sum[num - min]--;//加总数组中,该值的总和减少1。
}
//将存储数组的值一一替换给源数组
for(int i=0;i<a.length;i++){
a[i] = b[i];
}
}
//---------代码调用--------
int[] a = new int[]{6, -2, -8, 9, 3};
countSort(a, 9, -8); //9和-8分别是最大值和最小值。
纯文笔记
记录知识,分享心得。
以上是关于图解排序算法:计数排序的主要内容,如果未能解决你的问题,请参考以下文章