桶排序


一、思想
一句話總結:划分多個范圍相同的區間,每個子區間自排序,最后合並。

桶排序是計數排序的擴展版本,計數排序可以看成每個桶只存儲相同元素,而桶排序每個桶存儲一定范圍的元素,通過映射函數,將待排序數組中的元素映射到各個對應的桶中,對每個桶中的元素進行排序,最后將非空桶中的元素逐個放入原序列中。

桶排序需要盡量保證元素分散均勻,否則當所有數據集中在同一個桶中時,桶排序失效。

二、圖解過程

 

 

 


三、核心代碼

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM