什麼是計數排序?
導讀 | 計數排序的核心在於將輸入的資料值轉化為鍵儲存在額外開闢的陣列空間中。作為一種線性時間複雜度的排序,計數排序要求輸入的資料必須是有確定範圍的整數。 |
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/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 漫畫:什麼是計數排序?排序
- 漫畫:什麼是氣泡排序?排序
- Arrays.sort(arr)是什麼排序排序
- PHP的引用計數是什麼意思?PHP
- 計數排序vs基數排序vs桶排序排序
- 設計模式的數學定義是什麼?設計模式
- 計數排序排序
- Java排序之計數排序Java排序
- Scala 變數是什麼變數
- 輕鬆一刻:什麼是雞尾酒排序和地精排序?排序
- UI設計是什麼_UI設計學什麼?UI
- 排序演算法__計數排序排序演算法
- 什麼是設計模式設計模式
- 什麼是敏捷估計?敏捷
- 什麼是NFT數字藏品?
- python 複數是什麼意思Python
- 非交換排序-計數排序和桶排序排序
- [譯] Bob,函數語言程式設計是什麼鬼?函數程式設計
- PHP面試:說下什麼是堆和堆排序?PHP面試排序
- 什麼是數字化工廠?數字化工廠的整體架構是什麼?架構
- Scala 函數語言程式設計(一) 什麼是函數語言程式設計?函數程式設計
- 計數排序 - Counting Sort排序
- 什麼是AOP程式設計?程式設計
- 什麼是雲端計算?
- 什麼是NFT數字藏品收藏
- 什麼是智慧數字經營
- 基於桶的排序之計數排序排序
- 什麼是設計模式?為什麼要使用設計模式?有什麼好處?設計模式
- js基礎梳理-究竟什麼是變數物件,什麼是活動物件?JS變數物件
- (戀上資料結構筆記):計數排序、基數排序 、桶排序資料結構筆記排序
- 【資料結構與演算法】非比較排序(計數排序、桶排序、基數排序)資料結構演算法排序
- 快速排序為什麼這麼快?排序
- 計數排序 -- GoLang實現排序Golang
- 什麼是程式碼審計?程式碼審計有什麼好處?
- 資料庫審計是什麼意思?作用是什麼?資料庫
- python列表排序演算法有幾種?分為是什麼?Python排序演算法
- 什麼是cookie,什麼是sessionCookieSession
- 這是什麼這是什麼