一、思想
一句話總結:划分多個范圍相同的區間,每個子區間自排序,最后合並。
桶排序是計數排序的擴展版本,計數排序可以看成每個桶只存儲相同元素,而桶排序每個桶存儲一定范圍的元素,通過映射函數,將待排序數組中的元素映射到各個對應的桶中,對每個桶中的元素進行排序,最后將非空桶中的元素逐個放入原序列中。
桶排序需要盡量保證元素分散均勻,否則當所有數據集中在同一個桶中時,桶排序失效。
二、圖解過程
三、核心代碼
public static void bucketSort(int[] arr){ // 計算最大值與最小值 int max = Integer.MIN_VALUE; int min = Integer.MAX_VALUE; for(int i = 0; i < arr.length; i++){ max = Math.max(max, arr[i]); min = Math.min(min, arr[i]); } // 計算桶的數量 int bucketNum = (max - min) / arr.length + 1; ArrayList<ArrayList<Integer>> bucketArr = new ArrayList<>(bucketNum); for(int i = 0; i < bucketNum; i++){ bucketArr.add(new ArrayList<Integer>()); } // 將每個元素放入桶 for(int i = 0; i < arr.length; i++){ int num = (arr[i] - min) / (arr.length); bucketArr.get(num).add(arr[i]); } // 對每個桶進行排序 for(int i = 0; i < bucketArr.size(); i++){ Collections.sort(bucketArr.get(i)); } // 將桶中的元素賦值到原序列 int index = 0; for(int i = 0; i < bucketArr.size(); i++){ for(int j = 0; j < bucketArr.get(i).size(); j++){ arr[index++] = bucketArr.get(i).get(j); } } }
四、復雜度分析
1. 時間復雜度:O(N + C)
對於待排序序列大小為 N,共分為 M 個桶,主要步驟有:
N 次循環,將每個元素裝入對應的桶中
M 次循環,對每個桶中的數據進行排序(平均每個桶有 N/M 個元素)
一般使用較為快速的排序算法,時間復雜度為 O ( N l o g N ) O(NlogN)O(NlogN),實際的桶排序過程是以鏈表形式插入的。
整個桶排序的時間復雜度為:
O ( N ) + O ( M ∗ ( N / M ∗ l o g ( N / M ) ) ) = O ( N ∗ ( l o g ( N / M ) + 1 ) ) O(N)+O(M*(N/M*log(N/M)))=O(N*(log(N/M)+1))O(N)+O(M∗(N/M∗log(N/M)))=O(N∗(log(N/M)+1))
當 N = M 時,復雜度為 O ( N ) O(N)O(N)
2. 額外空間復雜度:O(N + M)
五、穩定性分析
桶排序的穩定性取決於桶內排序使用的算法。
————————————————
版權聲明:本文為CSDN博主「str_818」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/qq_27124771/article/details/87651495