常用排序演算法總結9一一計數排序
阿新 • • 發佈:2019-01-23
定義
計數排序(英語:Counting Sort)是一種穩定的線性時間排序演算法。計數排序使用一個額外的陣列C,其中第i個元素是待排序陣列A中值等於i的元素的個數。然後根據陣列C來將A中的元素排到正確的位置。
演算法步驟
- 找出待排序的陣列中最大和最小的元素
- 統計陣列中每個值為i的元素出現的次數,存入陣列 C 的第 i 項
- 對所有的計數累加(從C中的第一個元素開始,每一項和前一項相加)
- 反向填充目標陣列:將每個元素i放在新陣列的第C(i)項,每放一個元素就將C(i)減去1
當輸入的元素是n個0到k之間的整數時,它的執行時間是O(n + k)。計數排序不是比較排序,排序的速度快於任何比較排序演算法。
由於用來計數的陣列C的長度取決於待排序陣列中資料的範圍(等於待排序陣列的最大值與最小值的差加上1),這使得計數排序對於資料範圍很大的陣列,需要大量時間和記憶體。例如:計數排序是用來排序0到100之間的數字的最好的演算法,但是它不適合按字母順序排序人名。但是,計數排序可以用在基數排序演算法中,能夠更有效的排序資料範圍很大的陣列。
通俗地理解,例如有10個年齡不同的人,統計出有8個人的年齡比A小,那A的年齡就排在第9位,用這個方法可以得到其他每個人的位置,也就排好了 序。當然,年齡有重複時需要特殊處理(保證穩定性),這就是為什麼最後要反向填充目標陣列,以及將每個數字的統計減去1的原因。
程式碼實現(java)
public static int[] countSort(int []a)
{
int b[] = new int[a.length];
int max = a[0], min = a[0];
for(int i : a) {
if(i > max) {
max = i;
}
if(i < min) {
min = i;
}
}
//這裡k的大小是要排序的陣列中,元素大小的極值差+1
int k = max - min + 1;
int c[] = new int[k];
for(int i = 0; i < a.length; ++i) {
c[a[i]-min] += 1;//優化過的地方,減小了陣列c的大小
}
for(int i = 1; i < c.length; ++i) {
c[i] = c[i] + c[i-1];
}
for(int i = a.length-1; i >= 0; --i) {
b[--c[a[i]-min]] = a[i];//按存取的方式取出c的元素
}
return b;
}
總結
計數排序和基數排序很類似,都是非比較型排序演算法。但是,它們的核心思想是不同的,基數排序主要是按照進位制位對整數進行依次排序,而計數排序主要側重於對有限範圍內物件的統計。基數排序可以採用計數排序來實現。