計數排序並不基於元素的比較,而是一種利用數組下標來確定元素正確位置的算法。計數排序的核心在於將輸入的數據值轉化爲鍵值存儲在額外開闢的數組空間中。作爲一種線性時間複雜度的排序,計數排序算法的時間複雜度O(n + k)(k爲整數的範圍)。
簡單描述就是,在一個有確定範圍的整數空間中,建立一個長度更大的數組,如當輸入的元素是 n 個 0 到 k 之間的整數時,建立一個長度大於等於k的數組。該數組的每一個下標位置的值代表了數組中對應整數出現的次數。根據這個統計結果,直接遍歷數組,輸出數組元素的下標值,元素的值是幾, 就輸出幾次。
僞碼
COUNTSORT(A,B,k)
//let C[0...k] be a new array
for i=0 to k
C[i] = 0
for j=1 to A.length
C[a[j]] ++
for i=1 to k
C[i] += c[i-1]
for j=A.length downto 1
B[C[A[j]]] = A[j]
C[A[j]] --
算法演示過程
C++實現
#include<iostream>
#include<vector> //用vector比用數組好操作一些
using namespace std;
void countsort(vector<int>& arr, int k) {
int size = arr.size();
if (size < 1) {
return;
}
vector<int> count(k + 1, 0);
vector<int> temp(arr);
for (auto x : arr) {
count[x]++;
}
for (int i = 1; i < k; i++) {
count[i] += count[i - 1];
}
for (int j = size - 1; j > 0; j--) {
arr[count[temp[j]] - 1] = temp[j];
count[temp[j]]--;
}
}
int main() {
vector<int> arr = { 1,4,4,5,6,7,7,7,8,8,8,9,4,3 };
int k = 100;
countsort(arr, k);
for (auto x : arr)
cout << x << "\t";
cout << endl;
return 0;
}
java實現
import java.util.Arrays;
public class P_jishu {
public static int[] CountSort(int[] a,int k){
int[] C=new int[k+1];//構造C數組
int length=a.length,sum=0;//獲取A數組大小用於構造B數組
int[] B=new int[length];//構造B數組
for(int i=0;i<length;i++)
{
C[a[i]]+=1;// 統計A中各元素個數,存入C數組
}
for(int i=0;i<k+1;i++)//修改C數組
{
sum+=C[i]; //sum = sum+C[i]; //把前面的所以的數的和都保存起來
C[i] = sum;
}
for(int i=length-1;i>=0;i--)//遍歷A數組,構造B數組
{
B[C[a[i]]-1]=a[i];//將A中該元素放到排序後數組B中指定的位置
C[a[i]]--;//將C中該元素-1,方便存放下一個同樣大小的元素
}
return B;
}
public static void main(String[] args){
int[] a = {1,2,3,4,4,3,2,3,3,32,5};
//int[] a = {2,3,4,4,4,4,2};
int k = 100;
System.out.println(Arrays.toString(CountSort(a,k)));
}
}