計數排序
描述:
對每一個輸入元素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.