非比较排序之计数排序

Posted EffectiveMind

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了非比较排序之计数排序相关的知识,希望对你有一定的参考价值。

学习过比较排序后,接下来继续整理非比较排序的内容。比较排序算法复杂度最低为O(nlogn),而非比较排序,时间复杂度都要更好一些,为O(n),但都有其特定的适用场景,今天先从计数排序说起。

计数排序(Counting-sort)

计数排序,顾名思义,是通过统计序列中元素出现的次数来排序,适用范围是排序序列中的所有元素,都小于某个固定的不大的值,官方严谨的定义如下:

计数排序假设n个输入元素中的每一个都是0到k区间内的一个整数,其中k为某个整数。当k=O(n)时,排序的运行时间为O(n)

动态演示图点此查看

计数排序的基本思想是:初始化一个k+1个元素的数组,分别存放对应位置数值在元素中出现的个数,再修改为小于对应位置数值元素的总个数,再遍历原数组,将遍历值填充到输出结果数组,注意遍历过程中是从原始数组的末位开始的,这样可以实现稳定的(即原始数组中存在相等元素时排序后的序列其相对位置不变)输出结果

代码实现如下:

 
   
   
 
  1. import java.util.Arrays;

  2. public class CountingSort {

  3. public static void main(String[] args) {

  4. int[] arr = new int[]{2, 5, 3, 0, 2, 3, 0, 3};

  5. System.out.println("before counting sort, the array is: ");

  6. System.out.println(Arrays.toString(arr));

  7. int[] result = countingSort(arr, 5);

  8. System.out.println("\nend counting sort, the array is: ");

  9. System.out.println(Arrays.toString(result));

  10. }

  11. private static int[] countingSort(int[] original, int k) {

  12. int[] tempK = new int[k + 1];

  13. int[] result = new int[original.length];

  14. for (int i = 0; i < original.length; i++) {

  15. tempK[original[i]] += 1;

  16. }

  17. for (int i = 1; i < tempK.length; i++) {

  18. tempK[i] = tempK[i] + tempK[i - 1];

  19. }

  20. for (int j = original.length - 1; j >= 0; j--) {

  21. result[tempK[original[j]] - 1] = original[j];

  22. tempK[original[j]] -= 1;

  23. }

  24. return result;

  25. }

  26. }

小结

计数排序算法虽然看起来比较简单,但实现过程中还是有很多细节需要注意的,比如中间临时数组下标位置与原始数组值的对应,以及为了实现稳定的排序,最后的遍历要从原始数组的末尾开始等。

参考资料:《算法导论》

系列示例代码下载:欢迎关注我的github


以上是关于非比较排序之计数排序的主要内容,如果未能解决你的问题,请参考以下文章

十大经典排序之:基数排序 |计数排序

非比较排序 (计数排序 && 基数排序)

非比较排序 (计数排序 && 基数排序)

#yyds干货盘点#十大经典排序之:基数排序 |计数排序

排序算法非比较排序:计数排序基数排序桶排序

计数排序基数排序桶排序