計數排序

原理

通過統計各個元素出現次數,以決定元素的位置。

應用場景

適合元素值不大,且重複較多的情況。計數排序的精髓在於通過統計次數進行排序,相比於比較排序算法,性能更佳。當適用場景有限,比如對公司員工按年齡排序等。

性能

時間複雜度僅O(n),空間複雜度O(n)。

代碼

    /* 非常巧妙的實現 */
    public static void countSort(int a[]){
        if(a == null)
            return;
        int max = a[0];
        for(int i = 1; i < a.length; i++){ //求當前數組最大值
            if(max < a[i])
                max = a[i];
        }

        int[] count = new int[max+1];
        for(int i = 0; i < count.length; i++){ //初始化
            count[i] = 0;
        }
        for(int i = 0; i < a.length; i++){ //統計a中各個元素出現的次數
            count[a[i]]++;
        }
        int k = 0;
        for(int i = 0; i <= max; i++){
            for(int j = 0; j < count[i]; j++){
                //值i在數組a中出現了count[i]次,就將a[]設置count[i]次,相當於給數組a[]排序
                a[k++] = i;
            }
        }
    }

    /* 按算法導論第三版實現 */
    public static int[] countSort1(int a[]){
        if(a == null)
            return null;
        int max = a[0];
        for(int i = 1; i < a.length; i++){ //求當前數組最大值
            if(max < a[i])
                max = a[i];
        }

        int[] count = new int[max+1];
        for(int i = 0; i < count.length; i++){ //初始化
            count[i] = 0;
        }
        for(int i = 0; i < a.length; i++){ //統計a中各個元素出現的次數
            count[a[i]]++;
        }
        for(int i = 1; i < count.length; i++){ //累計次數
            count[i] += count[i-1];
        }

        int[] b = new int[a.length];
        for(int i = a.length-1; i >= 0; i--){ //通過統計的次數決定元素位置 
            b[count[a[i]] - 1] = a[i]; //注意索引從0開始
            count[a[i]]--; //減一是爲了防止相同元素插入同一位置
        }
        return b;
    }

    public static void main(String[] args){
        int[] a = new int[]{6, 7, 8, 10, 6, 7, 6, 6, 16, 10};
        int[] b = countSort1(a);
        for(int v: b)
            System.out.println(v);
    }

參考文獻

【1】劍指offer
【2】算法導論 第三版

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章