1. 程式人生 > >五分鐘學會一個有意思的排序:計數排序

五分鐘學會一個有意思的排序:計數排序

由於LeetCode上的演算法題很多涉及到一些基礎的資料結構,為了更好的理解後續更新的一些複雜題目的動畫,推出一個新系列 -----《圖解資料結構》,主要使用動畫來描述常見的資料結構和演算法。本系列包括十大排序、堆、佇列、樹、並查集、圖等等大概幾十篇。

你可以在公眾號 五分鐘學演算法 獲取更多排序內容

計數排序

計數排序是一種非基於比較的排序演算法,其空間複雜度和時間複雜度均為O(n+k),其中k是整數的範圍。基於比較的排序演算法時間複雜度最小是O(nlogn)的。該演算法於1954年由 Harold H. Seward 提出。

計數排序的核心在於將輸入的資料值轉化為鍵儲存在額外開闢的陣列空間中。作為一種線性時間複雜度的排序,計數排序要求輸入的資料必須是有確定範圍的整數

演算法步驟

  1. 花O(n)的時間掃描一下整個序列 A,獲取最小值 min 和最大值 max

  2. 開闢一塊新的空間建立新的陣列 B,長度為 ( max - min + 1)

  3. 陣列 B 中 index 的元素記錄的值是 A 中某元素出現的次數

  4. 最後輸出目標整數序列,具體的邏輯是遍歷陣列 B,輸出相應元素以及對應的個數

演算法演示

排序動畫過程解釋

  1. 首先,掃描一下整個序列

  2. 獲得最小值為 2 ,最大值為 7

  3. 新建陣列包含 2~7 的元素

  4. 再次掃描序列,將序列的值放置在新建陣列中

  5. 掃描數字 5,陣列中 index 為 3 的值為 5,次數為 1

  6. 掃描數字 3,陣列中 index 為 1 的值為 3,次數為 1

  7. 掃描數字 4,陣列中 index 為 2 的值為 4,次數為 1

  8. 掃描數字 7,陣列中 index 為 5 的值為 7,次數為 1

  9. 掃描數字 2,陣列中 index 為 0 的值為 2,次數為 1

  10. 掃描數字 4,陣列中 index 為 2 的值為 4,次數為 2

  11. 掃描數字 3,陣列中 index 為 1 的值為 3,次數為 2

  12. 按照這種節奏,掃描結束後,新建陣列中存放了整個序列以及每個數字出現的次數

  13. 最後輸出目標整數序列

  14. 輸出數字 2,同時陣列中 index 為 0 的值為 2 的元素次數變為 0

  15. 輸出數字 3,同時陣列中 index 為 1 的值為 3 的元素次數變為 1

  16. 同樣的操作,整個序列就完全輸出了

程式碼實現

為了更好的讓讀者用自己熟悉的程式語言來理解動畫,筆者將貼出多種程式語言的參考程式碼,程式碼全部來源於網上。

Go程式碼實現

Java程式碼實現

Python程式碼實現

JavaScript程式碼實現

如果你是iOS開發者,可以在GitHub上 github.com/MisterBooo/… 獲取更直觀可除錯執行的原始碼。

你可以在公眾號 五分鐘學演算法 獲取更多排序內容