什麼是計數排序?
導讀 | 計數排序的核心在於將輸入的資料值轉化為鍵儲存在額外開闢的陣列空間中。作為一種線性時間複雜度的排序,計數排序要求輸入的資料必須是有確定範圍的整數。 |
1. 計數排序的特徵
當輸入的元素是 n 個 0 到 k 之間的整數時,它的執行時間是 Θ(n + k)。計數排序不是比較排序,排序的速度快於任何比較排序演算法。
由於用來計數的陣列C的長度取決於待排序陣列中資料的範圍(等於待排序陣列的最大值與最小值的差加上1),這使得計數排序對於資料範圍很大的陣列,需要大量時間和記憶體。例如:計數排序是用來排序0到100之間的數字的最好的演算法,但是它不適合按字母順序排序人名。但是,計數排序可以用在基數排序中的演算法來排序資料範圍很大的陣列。
通俗地理解,例如有 10 個年齡不同的人,統計出有 8 個人的年齡比 A 小,那 A 的年齡就排在第 9 位,用這個方法可以得到其他每個人的位置,也就排好了序。當然,年齡有重複時需要特殊處理(保證穩定性),這就是為什麼最後要反向填充目標陣列,以及將每個數字的統計減去 1 的原因。
演算法的步驟如下:
- 找出待排序的陣列中最大和最小的元素
- 統計陣列中每個值為i的元素出現的次數,存入陣列C的第i項
- 對所有的計數累加(從C中的第一個元素開始,每一項和前一項相加)
- 反向填充目標陣列:將每個元素i放在新陣列的第C(i)項,每放一個元素就將C(i)減去1
2. 動圖演示
程式碼實現:
JavaScript
例項
function countingSort(arr, maxValue) { var bucket = new Array(maxValue+1), sortedIndex = 0; arrLen = arr.length, bucketLen = maxValue + 1; for (var i = 0; i < arrLen; i++) { if (!bucket[arr[i]]) { bucket[arr[i]] = 0; } bucket[arr[i]]++; } for (var j = 0; j < bucketLen; j++) { while(bucket[j] > 0) { arr[sortedIndex++] = j; bucket[j]--; } } return arr; }
Python
例項
def countingSort(arr, maxValue): bucketLen = maxValue+1 bucket = [0]*bucketLen sortedIndex =0 arrLen = len(arr) for i in range(arrLen): if not bucket[arr[i]]: bucket[arr[i]]=0 bucket[arr[i]]+=1 for j in range(bucketLen): while bucket[j]>0: arr[sortedIndex] = j sortedIndex+=1 bucket[j]-=1 return arr
Go
例項
func countingSort(arr []int, maxValue int) []int { bucketLen := maxValue + 1 bucket := make([]int, bucketLen) // 初始為0的陣列 sortedIndex := 0 length := len(arr) for i := 0; i < length; i++ { bucket[arr[i]] += 1 } for j := 0; j < bucketLen; j++ { for bucket[j] > 0 { arr[sortedIndex] = j sortedIndex += 1 bucket[j] -= 1 } } return arr }
Java
例項
public class CountingSort implements IArraySort { @Override public int[] sort(int[] sourceArray) throws Exception { // 對 arr 進行複製,不改變引數內容 int[] arr = Arrays.copyOf(sourceArray, sourceArray.length); int maxValue = getMaxValue(arr); return countingSort(arr, maxValue); } private int[] countingSort(int[] arr, int maxValue) { int bucketLen = maxValue + 1; int[] bucket = new int[bucketLen]; for (int value : arr) { bucket[value]++; } int sortedIndex = 0; for (int j = 0; j < bucketLen; j++) { while (bucket[j] > 0) { arr[sortedIndex++] = j; bucket[j]--; } } return arr; } private int getMaxValue(int[] arr) { int maxValue = arr[0]; for (int value : arr) { if (maxValue < value) { maxValue = value; } } return maxValue; } }
PHP
例項
function countingSort($arr, $maxValue = null) { if ($maxValue === null) { $maxValue = max($arr); } for ($m = 0; $m < $maxValue + 1; $m++) { $bucket[] = null; } $arrLen = count($arr); for ($i = 0; $i < $arrLen; $i++) { if (!array_key_exists($arr[$i], $bucket)) { $bucket[$arr[$i]] = 0; } $bucket[$arr[$i]]++; } $sortedIndex = 0; foreach ($bucket as $key => $len) { if ($len !== null) $arr[$sortedIndex++] = $key; if($len !== null){ for($j = 0; $j < $len; $j++){ $arr[$sortedIndex++] = $key; } } } return $arr; }
C
例項
#include#include#includevoid print_arr(int *arr, int n) { int i; printf("%d", arr[0]); for (i = 1; i < n; i++) printf(" %d", arr[i]); printf("\n"); } void counting_sort(int *ini_arr, int *sorted_arr, int n) { int *count_arr = (int *) malloc(sizeof(int) * 100); int i, j, k; for (k = 0; k < 100; k++) count_arr[k] = 0; for (i = 0; i < n; i++) count_arr[ini_arr[i]]++; for (k = 1; k < 100; k++) count_arr[k] += count_arr[k - 1]; for (j = n; j > 0; j--) sorted_arr[--count_arr[ini_arr[j - 1]]] = ini_arr[j - 1]; free(count_arr); } int main(int argc, char **argv) { int n = 10; int i; int *arr = (int *) malloc(sizeof(int) * n); int *sorted_arr = (int *) malloc(sizeof(int) * n); srand(time(0)); for (i = 0; i < n; i++) arr[i] = rand() % 100; printf("ini_array: "); print_arr(arr, n); counting_sort(arr, sorted_arr, n); printf("sorted_array: "); print_arr(sorted_arr, n); free(arr); free(sorted_arr); return 0; }
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69955379/viewspace-2758835/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 漫畫:什麼是計數排序?排序
- PHP的引用計數是什麼意思?PHP
- Arrays.sort(arr)是什麼排序排序
- 漫畫:什麼是氣泡排序?排序
- 什麼是函數語言程式設計函數程式設計
- 設計模式的數學定義是什麼?設計模式
- Scala 變數是什麼變數
- 什麼是數字簽名?什麼是數字信封?他們如何使用
- 什麼是雲端計算?什麼是公司網盤?
- 計數排序、桶排序和基數排序排序
- UI設計是什麼_UI設計學什麼?UI
- 計數排序vs基數排序vs桶排序排序
- 數字簽名是什麼?
- 輕鬆一刻:什麼是雞尾酒排序和地精排序?排序
- PHP面試:說下什麼是堆和堆排序?PHP面試排序
- 計數排序排序
- 什麼是敏捷估計?敏捷
- 什麼是設計模式設計模式
- 什麼是雲端計算
- 什麼是雲端計算?
- 什麼是數字化工廠?數字化工廠的整體架構是什麼?架構
- Java排序之計數排序Java排序
- 計數排序的原址排序排序
- [譯] Bob,函數語言程式設計是什麼鬼?函數程式設計
- 征服 JavaScript 面試:什麼是函數語言程式設計?JavaScript面試函數程式設計
- js基礎梳理-究竟什麼是變數物件,什麼是活動物件?JS變數物件
- python 複數是什麼意思Python
- 什麼是智慧數字經營
- Scala 函數語言程式設計(一) 什麼是函數語言程式設計?函數程式設計
- 【雲端計算小知識】什麼是雲端計算?雲端計算特點是什麼?
- 非交換排序-計數排序和桶排序排序
- 排序演算法__計數排序排序演算法
- 什麼是AOP程式設計?程式設計
- 什麼是設計模式?為什麼要使用設計模式?有什麼好處?設計模式
- 什麼是cookie,什麼是sessionCookieSession
- 什麼是DNS,什麼是HostsDNS
- 什麼是模式? 什麼是框架?模式框架
- 這是什麼這是什麼