计数排序

来源:互联网 发布:淘宝保证金别骗怎么办 编辑:程序博客网 时间:2024/04/27 22:42

基本思想: 对每一个输入元素x,确定出小于x的元素个数。有了这一信息,就可以把x直接放到它在最终输出数组中的位置上。例如,如果有17个元素小于x,则x就属于第18个输出位置。

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

算法过程: 假设输入的线性表L的长度为n,L=L1,L2,..,Ln;线性表的元素属于有限偏序集S,|S|=k且k=O(n),S={S1,S2,..Sk};则计数排序可以描述如下:
1、扫描整个集合S,对每一个Si∈S,找到在线性表L中小于等于Si的元素的个数T(Si);
2、扫描整个线性表L,对L中的每一个元素Li,将Li放在输出线性表的第T(Li)个位置上,并将T(Li)减1。

给定数组a[8]={2,5,3,0,2,3,0,3};
这里写图片描述

Java代码:

public class LinearTimeSorter {    /**     * 计数排序,所有的元素都在0和max之间。     */    public static void countingSort(int[] array, int fromIndex, int toIndex, int max) {        int[] counting = new int[max + 1];        for (int i = fromIndex; i < toIndex; i++) {            counting[array[i]]++;        } // counting[i]现在包含值为i的个数        for (int i = 1; i < counting.length; i++) {            counting[i] += counting[i-1];         } // counting[i]现在包含值小于等于i的个数        int[] tempArray = new int[toIndex - fromIndex];        for (int i = toIndex - 1; i >= 0; i--) { // 注意:这里是反向遍历,只有这样才是稳定的            tempArray[--counting[array[i]]] = array[i];        }        // copy back        System.arraycopy(tempArray, 0, array, fromIndex, tempArray.length);    }    public static void countingSort(int[] array, int max) {        countingSort(array, 0, array.length, max);    }    /**     * 计数排序,所有的元素都在min和max之间。     */    public static void countingSortMinMax(int[] array, int fromIndex, int toIndex, int min, int max) {        int[] counting = new int[max - min + 1];        for (int i = fromIndex; i < toIndex; i++) {            counting[array[i]-min]++;        } // counting[i]现在包含值为(i+min)的个数        for (int i = 1; i < counting.length; i++) {            counting[i] += counting[i-1];         } // counting[i]现在包含值小于等于(i+min)的个数        int[] tempArray = new int[toIndex - fromIndex];        for (int i = toIndex - 1; i >= 0; i--) {            tempArray[--counting[array[i] - min]] = array[i];        }        // copy back        System.arraycopy(tempArray, 0, array, fromIndex, tempArray.length);    }    public static void countingSortMinMax(int[] array, int min, int max) {        countingSortMinMax(array, 0, array.length, min, max);    }    /**     * 计数排序,自动决定min和max。     */    public static void countingSort(int[] array) {        if (array.length <= 1) return;        int min = array[0];        int max = array[0];        for (int i = 1; i < array.length; i++) {            if (min > array[i]) min = array[i];            if (max < array[i]) max = array[i];        }        countingSortMinMax(array, min, max);    }    public static void main(String[] args) {        int[] a = new int[] {2, 5, 3, 0, 2, 3, 0, 3};        countingSort(a, 5);        System.out.println(Arrays.toString(a));        a = new int[] {0, 3, 1, -2, 0, 1, -2, 1};        countingSortMinMax(a, -2, 3);        System.out.println(Arrays.toString(a));    }}
0 0
原创粉丝点击