算法導論之js實現--計數排序

計數排序


排序問題

  • 輸入:n個數的一個序列<a1, a2, ..., an>
  • 輸出:輸入序列的一個排列<a1', a2', ..., an'>,知足a1' <= a2' <= ... <= an'

計數排序

計數排序(Counting sort)是一種穩定的線性時間排序算法。
計數排序使用一個額外的數組C,其中第i個元素是待排序數組A中值等於i的元素的個數。而後根據數組C來將A中的元素排到正確的位置。算法

當輸入的元素是n個0到k之間的整數時,它的運行時間是Θ(n + k)。計數排序不是比較排序,排序的速度快於任何比較排序算法。
因爲用來計數的數組C的長度取決於待排序數組中數據的範圍(等於待排序數組的最大值與最小值的差加上1),這使得計數排序對於數據範圍很大的數組,須要大量時間和內存。數組

思路

  1. 找出待排序的數組中最大和最小的元素。
  2. 統計數組中每一個值爲i的元素出現的次數,存入數組C的第i項。
  3. 對全部的計數累加(從C中的第一個元素開始,每一項和前一項相加)。
  4. 反向填充目標數組:將每一個元素i放在新數組的第C(i)項,每放一個元素就將C(i)減去1。

js基本思路實現

這裏咱們先使用兩個數組分別保存「基準」左邊、右邊的子集。spa

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function countingSort(iArr, max) {
var n = iArr.length;
var oArr = [];
// 建立長度max的數組,填充0
var C = [];
for(var i = 0; i <= max; i++){
C[i] = 0;
}
// 遍歷輸入數組,填充C
for(var j = 0; j < n; j++){
C[iArr[j]]++;
}
// 遍歷C,輸出數組
for(var k = 0; k <= max; k++){
// 按順序將值推入輸出數組,並在比較後將對應標誌位減1
while(C[k]-- > 0){
oArr.push(k);
}
}
return oArr;
}

驗證

 

1
2
3
4
5
6
7
8
countingSort([ 5, 2, 4, 6, 1, 3], 6);
// 輸出[1, 2, 3, 4, 5, 6]
 
countingSort([ 2, 1, 3, 1, 5], 5);
// 輸出[1, 1, 2, 3, 5]
 
countingSort([ 5, 2, 12, 2, 134, 1, 3, 34, 4, 6, 1, 3, 4], 134);
// 輸出[1, 1, 2, 2, 3, 3, 4, 4, 5, 6, 12, 34, 134]
相關文章
相關標籤/搜索