1. 程式人生 > >線性排序算法

線性排序算法

復雜 多個 下標 場景 適用場景 桶排序 進行 復雜度 定性

桶排序:
1. 原理: 根據數據範圍,分成若幹個數據段的桶,通過遍歷講數據放到對應的桶中。每個桶裏都進行快排或歸並。
2. 時間復雜度: 最好o(n), 最壞o(nlogn), 平均o(n),一般桶分的越細越多復雜度就會最好。
3. 內存消耗: o(n)
4. 穩定性: 取決於每個桶的排序方式,快排就不穩定,歸並就穩定。
5. 適用場景: 數據範圍不大的。內存吃緊的,如磁盤的讀寫可以分成多個小文件並對每個小文件排序,然後直接寫到大文件裏,這個時候內存消耗不再是o(n)了。

計數排序:
1. 原理: 特殊的桶排序,即每個下標代表一個數據範圍,其值就是這個數據的個數。
2. 時間復雜度: 都是o(n)
3. 內存消耗: o(n)
4. 穩定性: 穩定,只要整理最後結果時從後開始遍歷即可。
5. 適用場景: 數據範圍不大的,如年齡排序。

// 計數排序,a 是數組,n 是數組大小。假設數組中存儲的都是非負整數。
public void countingSort(int[] a, int n) {
if (n <= 1) return; // 查找數組中數據的範圍
int max = a[0];
for (int i = 1; i < n; ++i) {
if (max < a[i]) {
max = a[i];
}
} int[] c = new int[max + 1]; // 申請一個計數數組 c,下標大小 [0,max]
for (int i = 0; i <= max; ++i) {
c[i] = 0;
} // 計算每個元素的個數,放入 c 中
for (int i = 0; i < n; ++i) {
c[a[i]]++;
} // 依次累加
for (int i = 1; i <= max; ++i) {
c[i] = c[i-1] + c[i];
} // 臨時數組 r,存儲排序之後的結果
int[] r = new int[n];
// 計算排序的關鍵步驟,有點難理解
for (int i = n - 1; i >= 0; --i) {
int index = c[a[i]]-1;
r[index] = a[i];
c[a[i]]--;
} // 將結果拷貝給 a 數組
for (int i = 0; i < n; ++i) {
a[i] = r[i];
}
}



基數排序:
1. 原理: 對數據的每一位進行桶排序或計數排序,對每位排序後結果就是有序的。
2. 時間復雜度: 最好o(n), 最壞o(nlogn), 平均o(n)
3. 內存消耗: o(n)
4. 穩定性: 穩定。否則就排不成的。
5. 適用場景: 是在桶排序和計數排序基礎上進行的,保證每位數據範圍不大,並且位數也不是很多。

線性排序算法