排序演算法---最穩定的計數排序
阿新 • • 發佈:2019-01-11
演算法思想
有沒有一種排序演算法的時間複雜度為O(N)呢?
如果面試官這麼問你,千萬不要直接否定!
事實上是有線性時間複雜度的排序演算法,只不過其使用條件有限,只能是滿足條件的整數(0~n)序列,而且需要一定的輔助空間。這就是我們即將要提到的——計數排序。
對於排序演算法來說計數排序是穩定的,跟桶排序相比其所佔用的空間是可控的,跟其他比較排序相比它的速度又是快捷的。
其基本思想:用待排序的數作為計數陣列的下標,統計每個數字的個數。然後依次輸出即可得到有序序列。對每一個元素x,確定出小於x的元素個數。例如,如果有17個元素小於x,則x就是屬於第18個輸出位置。
這個演算法的步驟大致如下:
1. 初始化一個計數陣列,大小是輸入陣列中的最大的數。
2. 遍歷輸入陣列,遇到一個數就在計數陣列對應的位置上加一。例如:遇到5,就將計數陣列第五個位置的數加一。
3. 把計數陣列直接覆蓋到輸出陣列(節約空間)。
Java程式碼實現
public class CountSort {
public static void main(String[] args) {
System.out.println("輸入排序的個數n:");
Scanner input = new Scanner(System.in);
int n = input.nextInt();
int array[] = new int[n];
System.out.println("請輸入要排序的數字:");
for (int i = 0; i < n; i++) {
array[i] = input.nextInt();
}
System.out.println("計數排序結果為:");
count(array);
for (int i = 0; i < n; i++) {
System.out.print(array[i] + " ");
}
}
private static void count(int[] array) {
if (array.length <= 1 ) {
return;
}
int max = 0;
//尋找最大值
for (Integer i : array) {
if (i > max) {
max = i;
}
}
int count[] = new int[max + 1];//建立輔助計數陣列
Arrays.fill(count, 0);//初始化陣列
//用待排序的數作為計數陣列的下標,統計每個數字的個數
for (int i = 0; i < array.length; i++) {
count[array[i]]++;
}
//根據計數陣列,修改原陣列的順序
int k = 0;
for (int i = 0; i <= max; i++) {
for (int j = 0; j < count[i]; j++) {
array[k++] = i;
}
}
}
}
複雜度
跟桶排序一樣,計數排序的複雜度是線性的:
時間:O(n + k),n是輸入陣列長度,k是最大的數的大小。
空間:O(n + k),n是輸入陣列長度,k是最大的數的大小。