計數排序

計數排序

描述:
對每一個輸入元素x, 確定小於x的元素個數。利用這一信息,就可以直接把x放到它在輸入數組中的位置上。例如,有17個元素小於x, 則x就應該放在第18個輸出位置上。當有幾個元素相同時候,這一方案需要略作修改。

修改:
只要知道x 有幾個元素,假如這裏x有2個元素,那麼將第1個x放在第18個元素,第2個x放在第19個元素。如果這時候有一個y 元素=x+1,那麼y元素所放的位置 = 比x的元素個數+ x元素個數。這就是整個算法的原理。

算法:在計算機中需要用一個temp數組來存放對應元素的位置信息。

package com.zq.algorithm.sort;

/**
 * Created by zhengshouzi on 2015/11/7.
 */
public class CountSort {

    public static void main(String[] args) {
        int[] a = {2,6,9,10,87,45,21,44,29,37,100,200,187,243,567,88};
        int[] d ={2,5,3,0,2,3,0,3};

        countSort(a);
        //輸出排序後的值
        for (int c :a){
            System.out.print(" "+ c);
        }
    }

    public static void countSort(int[] a){
        //一個備份數組,用來存放數組 a 的拷貝,
        int[]  b = new int[a.length];
        //找出待排序數組中的最大值,和最小值
        int max=a[0];
        int min=a[0];
        for (int i = 0; i < a.length; i++) {
            if (max<a[i]){
                max = a[i];
            }
            if (min>a[i]){
                min=a[i];
            }
            //賦值給備份數組
            b[i]=a[i];
        }
        //定義零時數組的大小
        int[] temp = new int[max-min+1];

        //對零時數組賦值
        for (int i = 0; i < a.length; i++) {
            //零時數組每一個元素的值,應該是 a 數組相應元素的個數值。如果a 中有 2個元素7,那麼最終temp[7-min] = 2,,
            temp[a[i]-min]++;
        }
        //改變零時數組的值
        for (int i = 1; i < temp.length; i++) {
            //爲什麼需要改變呢?  因爲  temp數組中的每一個值,都表示 a數組中有多少個對應的元素,   那麼賤temp[2] + temp[1] 就表示,比 a[i]-min=2這個a[i] 小的元素有多少個了。
            temp[i] = temp[i]+temp[i-1];
        }
        //這裏就是關鍵的地方,通過上面計算過後的temp的值,去改變 a 數組中的排序。
        //這裏for循環由小到大,是不穩定排序,由大到小是穩定排序。
        for (int i = 0; i <a.length; i++) {
            int j = temp[(b[i]-min)];
            a[--j] = b[i];
            temp[a[i]-min]--;
        }
    }
}

時間複雜度:O(n+k), 空間複雜度O(n+k), k=最大元素-最小元素+1.

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