import java.util.Arrays;
/**
* 計數排序,屬於穩定排序
* 時間複雜度:代碼1、2、4步都涉及遍歷原始數列,運算量都是n,第3步遍歷統計數列,運算量是m,所以總體運算量是m,所以總體的運算量是3n+m,去掉係數,時間複雜度是O(n+m)
* 空間複雜度:如果不考慮結果數組,只考慮統計數組大小的劃,空間複雜度是O(m)
* 侷限性:
* 1、當數列最大和最小值差距過大時,並不適合使用計數排序(例如給出20個隨機數,範圍在0-1億之間,這時如果使用計數排序需要使用長度爲1億的數組。不但浪費空間、時間複雜度也會提升)
* 2、當數列不是整數時,也不適用於計數排序(消暑無法創建對應的統計數組)
*/
public class CountSort {
public static int[] countSort(int[] arr) {
//1、得到數列的最大值和最小值,並算出差值d
int min = arr[0];
int max = arr[0];
for (int i : arr) {
if (i > max) {
max = i;
}
if (i < min) {
min = i;
}
}
int d = max - min;
//2、創建統計數組並統計對應元素的個數
int[] countArray = new int[d + 1];
for (int i : arr) {
countArray[i - min]++;
}
//3、統計數組做變形,後面的元素等於前面元素之和.累加的原因:讓統計數組存儲的元素值,等於相應整數的最終排序位置序號
for (int i = 1; i < countArray.length; i++) {
countArray[i] += countArray[i - 1];
}
//4、倒序遍歷原始數列,從統計數組找到正確位置,輸出結果數組
int[] sortArray = new int[arr.length];
for (int i = arr.length-1; i >= 0; i--) {
sortArray[countArray[arr[i] - min] - 1] = arr[i];
countArray[arr[i] - min] -- ;
}
return sortArray;
}
public static void main(String[] args) {
int[] array = new int[]{95,94,91,98,99,90,99,93,91,92};
int[] sortArray = countSort(array);
System.out.println(Arrays.toString(sortArray));
}
}