計數排序

計數排序（Counting sort）是一種穩定的線性時間排序演算法。該演算法於 1954 年由哈羅德・H・西華德提出。計數排序使用一個額外的陣列，其中第 i 個元素是待排序陣列中值等於的元素的個數。然後根據陣列來將中的元素排到正確的位置。

計數排序的特徵

當輸入的元素是個到之間的整數時，它的執行時間是。計數排序不是比較排序，因此不被 的下界限制。

由於用來計數的陣列的長度取決於待排序陣列中資料的範圍（等於待排序陣列的最大值與最小值的差加上 1），這使得計數排序對於資料範圍很大的陣列，需要大量時間和記憶體。例如：計數排序是用來排序 0 到 100 之間的數字的最好的演算法，但是它不適合按字母順序排序人名。但是，計數排序可以用在基數排序演算法中，能夠更有效的排序資料範圍很大的陣列。

通俗地理解，例如有 10 個年齡不同的人，統計出有 8 個人的年齡比 A 小，那 A 的年齡就排在第 9 位，用這個方法可以得到其他每個人的位置，也就排好了序。當然，年齡有重複時需要特殊處理（保證穩定性），這就是為什麼最後要反向填充目標陣列，以及將每個數字的統計減去 1。演算法的步驟如下：

找出待排序的陣列中最大和最小的元素
統計陣列中每個值為的元素出現的次數，存入陣列的第項
對所有的計數累加（從中的第一個元素開始，每一項和前一項相加）
反向填充目標陣列：將每個元素放在新陣列的第項，每放一個元素就將減去 1

Java 語言的實現

public class CountingSort {public static void main (String args) {int A = CountingSort.countingSort (new int {16, 4, 10, 14, 7, 9, 3, 2, 8, 1});

Utils.print (A);

}

public static int countingSort (int A) {

int B = new intA.length;

// 假設 A 中的資料 a' 有，0= 0; j--) {

int a = Aj;

BCa - 1 = a;

Ca -= 1;

}

}

}

// 針對 c 陣列的大小，最佳化過的計數排序

public class CountSort {public static void main (String args){

		// 排序的陣列

		int a = {100, 93, 97, 92, 96, 99, 92, 89, 93, 97, 90, 94, 92, 95};

		int b = countSort (a);

		for (int i : b){System.out.print (i + " ");

		}

		System.out.println ;}

	public static int countSort (int a){

		int b = new inta.length;

		int max = a0, min = a0;

		for (int i : a){if (i> max){max = i;}

			if (i = 0; --i){b--cai-min = ai;// 按存取的方式取出 c 的元素}

		return b;

	}

}

// 另一種參考，

// 缺點：不適合資料落差大、浮點數，資料落差大會生成大 a 陣列，數少用其他演算更好。

// 優點：線性快，固定重複巨量資料適用，沒有更快，理論，只統計，不做多餘運算或搬移。

import java.util.Arrays;

import java.util.Random;

public class Csoft {public static void main (String args) {//int arr = { -535000000, 0, -372, -299,830000};

		//int arr = {100, 93, 97, 92, 96, 99, 92, 89, 93, 97, 90, 94, 0, -1,-1,-95};

//int arr = Random_Numbers (500000000);

int arr = Random_Numbers (20);

System.out.println (Arrays.toString (arr));

new Csoft (arr);

System.out.println (Arrays.toString (arr));

}

private int min;

Csoft

Csoft (int arr) {b (arr);

}

public static int b (int arr) {

int max = 0, min = 0;

for (int i = 0; i arrmax ? i : max;

min = arri 0) {

for (int i = 0; i

C 語言的實現

include

void print_arr (const int *arr, const int n) {printf ("% d", arr0);

	for (int i = 1; i 0; i--)

		sortedarr--countarriniarri - 1 = iniarri - 1;

	free (count_arr);

}

int main (int argc, char argv) {

	int n = 10;

	int max_val = 100;

	int arr = (int ) calloc (n, sizeof (int));

	int sorted_arr = (int ) calloc (n, sizeof (int));

	srand (time (0));

	for (int i = 0; i

javascript 實現

Array.prototype.countSort = function {

const C =

for (let i = 0; i = 1 ? Cj ++ : (Cj = 1)

}

const D =

for (let j = 0; j 0) {D.push (j)

Cj--

}

}

}

return D

}

const arr = 11, 9, 6, 8, 1, 3, 5, 1, 1, 0, 100

console.log (arr.countSort )

Golang 的實現

func countingSort (arr int, minvalue, maxValue int) int {

bucketLen := maxValue - minvalue + 1

bucket := make (int, bucketLen)

for _, v := range arr {bucketv-minvalue++}

result := make (int, len (arr))

index := 0

for k, v := range bucket {

kk := k + minvalue

for j := v; j > 0; j-- {

resultindex = kk

index++

}

}

return result

}

Python3 的實現

-- coding: utf-8 --

def count_sort (a: list) -> list:

a_min: int = min (a)

k: int = max (a) - a_min + 1

c: list = 0 for _ in range (k)

for i in a:

ci - a_min += 1

for i, v in enumerate (c):

if i == 0:

continue

ci = v + ci-1

result: list = None for _ in range (len (a))

for i in a:

resultci - a_min - 1 = i

ci - a_min -= 1

return result

if name == 'main':

print (count_sort (652, 721, 177, 977, 24, 17, 126, 515, 442, 917))