有趣的桶排序
程式設計師的核心技能之一就是演算法,談到演算法,似乎都是從排序開始。對一組已知範圍的資料進行排序,最快的演算法是什麼呢?快速排序?希爾排序?非也,非也~是本文的主角“桶排序”!
來看一個實際例子吧:已知一組範圍在0~10的資料(如:9,5,2,7,7),你有沒有什麼好方法編寫一段程式,將資料從大到小輸出呢?
看到這樣的題目,相信很多人第一反應跟我一樣,就是將這些資料進行比較,然後進行位置的交換,最終實現排序。可桶排序徹底顛覆了這種想法——第一次看到桶排序時,確實被驚豔到了——還有這種操作?!原來排序不一定非得老老實實對原有資料進行位置調整!
好了,回到我們的題目。我們只需要藉助一個一維陣列就可以解決問題。首先,我們申請一個長度為11的陣列int a[11]
,因為我們的資料範圍是0~10,而int a[11]
的元素正好是a[0]~a[10]
。開始的時候,我們將所有元素都初始化為0,表示這些數都未出現過。例如a[0]
等於0,就表示待排序資料還未出現過0;同理,若a[9]
等於1,則表示待排資料中9出現過1次。
有了上面的說明,那接下來就非常簡單了,我們只需要遍歷待排陣列,然後將每個數值對應下標的元素加1(比如第一個數是9,我們就將a[9]
加1)。你會發現,待排陣列遍歷完之後,a[0]~a[10]
中的數值,其實就是0~10出現的次數,我們只需要按次數將下標列印出來就實現排序了。程式碼如下:
#include <stdio.h>
int main()
{
int a[11],i,j,t;
for(i=10; i>=0; i--)
{
a[i]=0;
}
for(i=1; i<=5; i++) //迴圈讀入5個待排數
{
scanf("%d",&t); //把每一個數讀到變數t中
a[t]++; //進行計數
}
for(i=10; i>=0; i--)
{
for(j=1; j<=a[i];j++)
{
printf("%d ",i);
}
}
printf("\r\n");
getchar();
return 0;
}
執行該程式,我們可以隨意輸入5個0~10的數字,然後程式會將其按從大到小排序輸出,如下圖:
接下來我們來看看時間複雜度。首先我們用了一個m次(m為桶的個數)的迴圈把桶清空;然後再用一個n次(n為待排序資料的個數)的迴圈,設定的資料的顯示次數;最後又進行了m+n次迴圈,把資料顯示出來。所以,整個排序演算法一共執行了m+n+m+n次。我們用大寫字母O來表示時間複雜度,因此該演算法的時間複雜度是O(m+n+m+n)即O(2*(m+n))。我們在說時間複雜度的時候可以忽略較小的常數,最終桶排序的時間複雜度為O(m+n)。還有一點,在表示時間複雜度的時候,n和m通常用大寫字母即O(M+N),這是一個非常快的排序演算法。
桶排序雖快,但其實它是用空間在換時間。如果需要排序的數範圍非常寬,那我們就需要申請非常多的“桶”來儲存每一個數出現的次數。即使依然只是需要對5個數進行排序,這太浪費空間了!所以在選擇使用哪種排序演算法之前,還是需要根據實際情況,權衡好複雜度與空間的問題。
參考書籍:《啊哈!演算法》
說明:本文所提到的是簡化版的桶排序演算法,真正的同排序演算法要複雜些,有興趣的朋友可以自行搜尋學習。
相關文章
- 桶排序排序
- 桶排序2排序
- 排序演算法__桶排序排序演算法
- 桶排序和基數排序排序
- 基於桶的排序之計數排序排序
- 桶排序bucket sort排序
- (四)桶排序法排序
- 排序演算法之——桶排序排序演算法
- 桶排序 選擇,插入排序排序
- shellsort排序有趣的試驗排序
- 非交換排序-計數排序和桶排序排序
- 計數排序、桶排序和基數排序排序
- hive分桶表排序Hive排序
- 常用排序演算法之桶排序排序演算法
- 計數排序vs基數排序vs桶排序排序
- 基於桶的排序之基數排序以及排序方法總結排序
- Elasticsearch聚合的巢狀桶如何排序Elasticsearch巢狀排序
- 資料結構(python) —— 【18排序: 桶排序】資料結構Python排序
- 三分鐘搞懂桶排序排序
- rust-algorithms:3-桶排序RustGo排序
- 【JS面試向】選擇排序、桶排序、氣泡排序和快速排序簡介JS面試排序
- (戀上資料結構筆記):計數排序、基數排序 、桶排序資料結構筆記排序
- 複習資料結構:排序演算法(七)——桶排序資料結構排序演算法
- 【資料結構與演算法】非比較排序(計數排序、桶排序、基數排序)資料結構演算法排序
- 第三章:查詢與排序(下)----------- 3.20桶排序排序
- 資料結構 桶排序 基數排序MSD c++ swift 版本資料結構排序C++Swift
- 基數排序--陣列模擬桶結構排序陣列
- .net版 字串陣列桶排序演算法字串陣列排序演算法
- 資料結構與演算法——桶排序資料結構演算法排序
- 手寫演算法並記住它:桶排序演算法排序
- 排序演算法之歸併,快速,堆和桶排序演算法
- 《演算法筆記》5. 字首樹、桶排序、排序演算法總結演算法筆記排序
- 【資料結構與演算法】內部排序之五:計數排序、基數排序和桶排序(含完整原始碼)資料結構演算法排序原始碼
- 聊一聊那些腦洞大開、有趣又奇葩的排序演算法排序演算法
- 每天一道演算法題--排序之桶排序實現求排序後相鄰最大差值問題演算法排序
- 有趣的cssCSS
- 【我就瞎記記,你就瞎看看】小演算法-桶排序演算法排序
- 漏桶、令牌桶限流的Go語言實現Go