非比较排序之计数排序/桶排序

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

计数排序(Counting-sort)

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

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

动态演示图点此查看

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

代码实现如下:

import java.util.Arrays;

public class CountingSort {

    public static void main(String[] args) {
        int[] arr = new int[]{2, 5, 3, 0, 2, 3, 0, 3};
        System.out.println("before counting sort, the array is: ");
        System.out.println(Arrays.toString(arr));

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

        System.out.println("\nend counting sort, the array is: ");
        System.out.println(Arrays.toString(result));
    }

    private static int[] countingSort(int[] original, int k) {
        int[] tempK = new int[k + 1];
        int[] result = new int[original.length];

        for (int i = 0; i < original.length; i++) {
            tempK[original[i]] += 1;
        }

        for (int i = 1; i < tempK.length; i++) {
            tempK[i] = tempK[i] + tempK[i - 1];
        }

        for (int j = original.length - 1; j >= 0; j--) {
            result[tempK[original[j]] - 1] = original[j];
            tempK[original[j]] -= 1;
        }
        return result;
    }
}

小结

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

参考资料:
《算法导论》

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

发布了159 篇原创文章 · 获赞 225 · 访问量 21万+

猜你喜欢

转载自blog.csdn.net/lyg673770712/article/details/87998413