簡單桶排序(Bucket Sort)

 

1.基本思想

桶排序是將待排序集合中處於同一個值域的元素存放在同一個桶中1java

2.算法設計2

假設有一個班級有5我的,此次期末他們分別考了5分,2分,4分,5分,8分(滿分爲10分)。須要將這些分數從小到大排序算法

首先咱們申請一個大小爲11的數組int bucket[11]。在最開始的時候咱們都把該數組的元素bucket[0]~bucket[10]都初始化爲0,表示這些分數都尚未人獲得過。例如bucket[0]表示的是目前尚未人獲得0分,bucket[8]表示的是目前尚未人獲得8分。
初始化數組

  1. 開始處理每個分數。第一我的的分數爲5分,那麼就將bucket[5]的值在原來的基礎上加1,即bucket[5]的值從0變爲1,表示5分出現過一次
    1
  2. 第二我的的分數爲2分,那麼就將bucket[2]的值在原來的基礎上加1,即bucket[2]的值從0變爲1,表示2分出現過一次
    2
  3. 第三我的的分數爲4分,以此類推,可得
    3
  4. 第四我的的分數爲5分,注意了,咱們在bucket[5]的值在原來的基礎上加1,那麼bucket[5]的值從1變爲2,表示5分出現兩次
    4
  5. 最後一我的的分數爲8分,得
    5
    最終,只須要將出現過的分數打印出來

3.代碼

public class SimpleBucketSort {
    public static void main(String[] args) {
        // 下面是學生取得的分數,假設分數最大爲10
        int[] a = {5,3,5,2,8};
        // 建立11個分數層,a[0]=0:表示分數爲0分的出現0我的
        int[] bucket = new int[11];
        for(int i = 0; i < a.length; i++) {
            // 出現分數爲a[i]的有barrel[a[i]]我的
            bucket[a[i]]++;
        }
        // 打印
        for (int i = 0; i < bucket.length; i++) {
            // 出現幾回就打印幾回
            for(int j = 1; j <= bucket[i]; j++) {
                System.out.print(i + " ");
            }
        }
    }
}

 

4.複雜度

  • 時間複雜度

在初始化桶時,須要循環n次(n爲桶的個數,在java語言中默認都已經初始化爲0),在把分數放入桶中時,循環了m次(m爲待排序的個數),而在打印時一共循環了(m+n)次,因此整個排序算法一共執行了(n+m+m+n)次。用大寫的O來表示時間複雜度,所以該算法的時間複雜度爲O(n+m+m+n),即O(2(n+m))。可是通常在說時間複雜度時都是忽略常數,也就是桶排序的最終時間複雜度爲O(m+n),而且通常字母都得大寫表示,即O(M+N)。spa

  • 空間複雜度

桶排序所佔用的空間比較糟糕,很是浪費空間,若是要排序的數的範圍在0~10000000000000,那得建立出10000000000001個變量。建立N個桶,而且待排序的數爲M,那麼空間複雜度爲O(N+M)。設計

5.優缺點

  • 優勢

速度是比較快的,從上面的時間複雜度能夠看出。3d

  • 缺點

比較浪費空間,假設待排序的數中有一個元素值爲2100000000000,那麼必須建立一個大於2100000000000的桶數。code

6.思考

  • 該算法其實能夠來作去重複元素,只須要在打印時作一點改動。
// 打印(去重)
for(int i = 0; i < barrel.length; i++) {
    if(barrel[i] != 0) {
        // 打印的是分數
        System.out.print(i + " ");
    }
}

 

  • 目前使用桶排序來對分數進行排序,那麼目前要是姓名和分數,要求將名字按分數從小到大排序後打印輸出,目前的簡單桶排序作不到,輸出的只能是分數。

  1. 參考博客:https://www.jianshu.com/p/204ed43aec0c ↩︎blog

  2. 參考書籍:《啊哈!算法》 ↩︎排序

相關文章
相關標籤/搜索