計數排序是一種理解起來非常容易的排序演算法,以前我們學習到的排序演算法都是比較排序,而它不是一種比較排序演算法,它的時間複雜度是O(n),它的原理其實很簡單,我們在基數排序裡面就已經用到了。
它首先用一個數組tempList,記錄待排序列sortList中每個數出現的次數。tempList[i]代表是的待排序列中i出現的次數,tempList[5]=2,代表待排序列中5出現了兩次。
然後用一個數組indexList記錄比當前數小的所有數小的個數。indexList[i]代表的是待排序列中比i小的數出現的個數,indexList[3]=2,代表待排序列中比3小的數總共有2個,indexList[3]=tempList[0]+tempList[1]+tempList[2].
indexList計算出來了,那麼其實就已經知道了這個數的位置了,indexList[3]=2,代表待排序列中比3小的數字有2個,那麼證明3在排序好的數組裡面的位置應該是位置3了,依次讀出所有的indexList的值,然後按照這些值把數字放入到相應的位置就行了。如下:
代碼如下(代碼的實現可能與上面的分析有一些不一樣,但原理是一樣):
public void CSort(List<int> sortList,int max)
{
int[] tempList = new int[max+1];//桶的個數比待排序列中最大數的值還要多一個
int[] tempResult = new int[sortList.Count];//最後存放結果的數組
//tempList[k]記錄的是待排數組中,值為k的數的個數
for (int j = 0; j < sortList.Count; j++)
{
tempList[sortList[j]] += 1;
}
for (int j = 0; j < sortList.Count; j++)
{
int m = sortList[j];
int sumCount = 0;
for (int k = 0; k < m; k++)
{
sumCount += tempList[k];
}
while (tempResult[sumCount] != 0)
{
sumCount++;
}
tempResult[sumCount] = sortList[j];
}
for (int m = 0; m < sortList.Count; m++)
{
sortList[m] = tempResult[m];
}
}
從代碼中我們可以看出,待排序列中的數越大,需要的桶(對應於額外的空間)就越多,所以計數排序,只適合在待排序列中數比較小的情況下使用。對比較小的數進行排序,計數排序是最快的。