數據結構與算法系列——排序(14)_桶排序 數據結構與算法——計數排序、桶排序、基數排序 桶排序

1. 工做原理(定義)

  桶排序的思想近乎完全的分治思想。桶排序是鴿巢排序的一種概括結果html

  桶排序 (Bucket sort)或所謂的箱排序,是一個非比較排序算法,是基於映射函數實現的。工做的原理是將數組分到有限數量的桶子裏。每一個桶子再個別排序(有可能再使用別的排序算法或是以遞歸方式繼續使用桶排序進行排序)。桶排序是鴿巢排序的一種概括結果。當要被排序的數組內的數值是均勻分配的時候,桶排序使用線性時間(Θ(n))。java

  桶排序是計數排序的升級版【能夠實數】。它利用了函數的映射關係,高效與否的關鍵就在於這個映射函數的肯定。爲了使桶排序更加高效,咱們須要作到這兩點:算法

  1. 在額外空間充足的狀況下,儘可能增大桶的數量
  2. 使用的映射函數可以將輸入的 N 個數據均勻的分配到 K 個桶中【在桶排序中保證元素均勻分佈到各個桶尤其關鍵。】

  同時,對於桶中元素的排序,選擇何種比較排序算法對於性能的影響相當重要。數組

2. 算法步驟

  1. 根據輸入創建適當個數的桶,每一個桶能夠存放某個範圍內的元素;【根據待排序集合中最大元素和最小元素的差值範圍和映射規則(映射函數通常是 f = array[i] / k,k^2 = n; n是全部元素個數),肯定申請的桶個數;】
  2. 將落在特定範圍內的全部元素放入對應的桶中;
  3. 對每一個非空的桶中元素進行排序,能夠選擇通用的排序方法,好比插入、快排;
  4. 按照劃分的範圍順序,將桶中的元素依次取出。排序完成。

元素分佈在桶中:數據結構

而後,元素在每一個桶中排序:函數

 

3. 動畫演示

Linked List Array index = Value * NUMBER_OF_ELEMENTS / (MAXIMUM_ARRAY_VALUE +1) = (value * 30)/1000post

MAXIMUM_ARRAY_VALUE 加1是爲了保證最大元素能夠存到數組最後一個位置,即arr.length - 1處。性能

這裏寫圖片描述

4. 性能分析

1. 時間複雜度

  對於N個待排數據,M個桶,平均每一個桶[N/M]個數據的桶排序平均時間複雜度爲:O(N)+O(M*(N/M)*log(N/M))=O(N+N*(logN-logM))=O(N+N*logN-N*logM),桶排序的平均時間複雜度爲線性的O(N+C),其中C=N*(logN-logM)。優化

  當M=N時,即極限狀況下每一個桶只有一個數據時。桶排序的最好效率可以達到O(N)。動畫

  當M=1時,即極限狀況下只有一個桶時。桶排序的最壞效率達到O(N*logN)。

  • 最壞時間複雜度:O(N*logN)。
  • 最好時間複雜度:O(N)。
  • 平均時間複雜度:O(N+N*logN-N*logM)

2. 空間複雜度

  桶排序的空間複雜度 爲O(N+M),若是輸入數據很是龐大,而桶的數量也很是多,則空間代價較大。 

3. 算法穩定性 

  桶排序是穩定的算法。【桶排序能夠是穩定的。這取決於咱們對每一個桶中的元素採起何種排序方法,好比桶內元素的排序使用快速排序,那麼桶排序就是不穩定的;若是使用的是插入排序,桶排序就是穩定的。

6. 優缺點

  桶排序也不能很好地應對元素值跨度很大的數組。好比[3, 2, 1, 0 ,4, 8, 6, 999],按照上面的映射規則,999會放入一個桶中,剩下全部元素都放入同一個桶中,在各個桶中元素分佈極不均勻,這就失去了桶排序的意義。

  桶排序和計數排序有個共同的缺點:耗費大量空間

  再細看桶排序,其實計數排序能夠看做是桶排序的一種特例,計數排序至關於將全部相同的元素放入同一個桶中,而桶排序能夠將必定範圍內的元素都放入同一個桶中;另外,桶排序的數據結構很像基於拉鍊法的散列表,只是定義的映射函數不一樣。桶排序的映射函數將較大值映射成較大的索引,這二者是呈正相關的。而散列表的映射函數獲得的哈希值是隨意的。

7. 應用

  

7. 具體代碼

import java.util.ArrayList;
import java.util.Arrays;

import java.util.*;

public class BucketSort{
   // 通常建立的桶數量等於原始數列的元素數量,除了最後一個桶只包含數列最大值,前面各個桶的區間按照比例肯定。【
OR 桶數量等於原始數列的元素數量+1,除了第一個桶只包含數列最小值,最後一個桶只包含數列最大值,中間各個桶的區間按照比例肯定。
   // 區間跨度 = (最大值-最小值)/ (桶的數量 - 1)
   // 定位元素屬於第幾個桶,是按照比例來定位:(array[i] - min) * (bucketNum-1) / (max - min) 
public static double[] bucketSort(double[] array, int bucketNum){
         //1.獲得數列的最大值和最小值,並算出差值d
         double max = array[0];
         double min = array[0];
         for(int i=1; i<array.length; i++) {
              if(array[i] > max) {
                   max = array[i];
              }
              if(array[i] < min) {
                   min = array[i];
              }
         }
         // 下面的運行慢
         // double max = Arrays.stream(array).max().getAsDouble();
         // double min = Arrays.stream(array).min().getAsDouble();
         
         double d = max - min;
         
         //2.初始化桶
         //int bucketNum = array.length;
         ArrayList<LinkedList<Double>> bucketList = new ArrayList<LinkedList<Double>>(bucketNum);
         for(int i = 0; i < bucketNum; i++){
              bucketList.add(new LinkedList<Double>());
         }
         //3.遍歷原始數組,將每一個元素放入桶中
         for(int i = 0; i < array.length; i++){
              int num = (int)((array[i] - min) * (bucketNum-1) / d);
              bucketList.get(num).add(array[i]);
         }
         //4.對每一個通內部進行排序
         for(int i = 0; i < bucketList.size(); i++){
              //JDK底層採用了歸併排序或歸併的優化版本
              Collections.sort(bucketList.get(i));
         }
         //5.輸出所有元素
         double[] sortedArray = new double[array.length];
         int index = 0;
         for(LinkedList<Double> list : bucketList){
              for(double element : list){
                   sortedArray[index] = element;
                   index++;
              }
         }
         return sortedArray;
    }
  
    public static void main(String[] args) {
         double[] array = new double[] {4.12,6.421,0.0023,3.0,2.123,8.122,4.12, 10.09};
         double[] sortedArray = bucketSort(array,3);
         System.out.println(Arrays.toString(sortedArray));
    }
    
}
 
 
 

8. 參考網址

  1. https://www.runoob.com/w3cnote/bucket-sort.html
  2. 排序算法系列之桶排序
  3. 數據結構與算法——計數排序、桶排序、基數排序
  4. https://visualgo.net/en/sorting
  5. 桶排序
  6. 漫畫:什麼是桶排序?
  7. 八大排序算法之桶排序
  8. 算法:排序算法之桶排序
相關文章
相關標籤/搜索