原理
通過統計各個元素出現次數,以決定元素的位置。
應用場景
適合元素值不大,且重複較多的情況。計數排序的精髓在於通過統計次數進行排序,相比於比較排序算法,性能更佳。當適用場景有限,比如對公司員工按年齡排序等。
性能
時間複雜度僅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】算法導論 第三版