JAVA十大排序算法之桶排序詳解
桶排序
桶排序是計數排序的升級,計數排序可以看成每個桶隻存儲相同元素,而桶排序每個桶存儲一定范圍的元素,通過函數的某種映射關系,將待排序數組中的元素映射到各個對應的桶中,對每個桶中的元素進行排序(有可能再使用別的排序算法或是以遞歸方式繼續使用桶排序),最後將非空桶中的元素逐個放入原序列中。
桶排序需要盡量保證元素分散均勻,否則當所有數據集中在同一個桶中時,桶排序失效。
代碼實現
1.找出數組中的最大值max和最小值min,可以確定出數組所在范圍min~max
2.根據數據范圍確定桶的數量
1.若桶的數量太少,則桶排序失效
2.若桶的數量太多,則有的桶可能,沒有數據造成空間浪費
所以桶的數量由我們自己來確定,但盡量讓元素平均分佈到每一個桶裡,這裡提供一個方式
(最大值 – 最小值)/每個桶所能放置多少個不同數值+1
3.確定桶的區間,一般是按照(最大值 – 最小值)/桶的數量來劃分的,且左閉右開
public class BucketSort { public static final int[] ARRAY = {35, 23, 48, 9, 16, 24, 5, 11, 32, 17}; /** * @param bucketSize 作為每個桶所能放置多少個不同數值,即數值的類型 * 例如當BucketSize==5時,該桶可以存放{1,2,3,4,5}這幾種數字, * 但是容量不限,即可以存放100個3 */ public static List<Integer> sort(List<Integer> array, int bucketSize) { if (array == null || array.size() < 2) return array; int max = array.get(0), min = array.get(0); // 找到最大值最小值 for (int i = 0; i < array.size(); i++) { if (array.get(i) > max) max = array.get(i); if (array.get(i) < min) min = array.get(i); } //獲取桶的數量 int bucketCount = (max - min) / bucketSize + 1; //構建桶,初始化 List<ArrayList<Integer>> bucketArr = new ArrayList<>(bucketCount); List<Integer> resultArr = new ArrayList<>(); for (int i = 0; i < bucketCount; i++) { bucketArr.add(new ArrayList<>()); } //將原數組的數據分配到桶中 for (int i = 0; i < array.size(); i++) { //區間范圍 bucketArr.get((array.get(i) - min) / bucketSize).add(array.get(i)); } for (int i = 0; i < bucketCount; i++) { if (bucketSize == 1) { for (int j = 0; j < bucketArr.get(i).size(); j++) resultArr.add(bucketArr.get(i).get(j)); } else { if (bucketCount == 1) bucketSize--; //對桶中的數據再次用桶進行排序 List<Integer> temp = sort(bucketArr.get(i), bucketSize); for (int j = 0; j < temp.size(); j++) resultArr.add(temp.get(j)); } } return resultArr; } public static void print(List<Integer> array) { for (int i : array) { System.out.print(i + " "); } System.out.println(""); } public static void main(String[] args) { print(Arrays.stream(ARRAY).boxed().collect(Collectors.toList())); System.out.println("============================================"); print(sort(Arrays.stream(ARRAY).boxed().collect(Collectors.toList()), 2)); } }
時間復雜度
桶排序算法遍歷瞭2次原始數組,運算量為2N,最後,遍歷桶輸出排序結果的運算量為N,初始化桶的運算量為M。
對桶進行排序,不同的排序算法算法復雜度不同,冒泡排序算法復雜度為O(N^2),堆排序、歸並排序算法復雜度為O(NlogN),我們以排序算法復雜度為O(NlogN)進行計算,運算量為N/M * log(N/M) * M
最終的運算量為3N+M+N/M * log(N/M) * M,即3N+M+N(logN-logM),去掉系數,時間復雜度為O(N+M+N(logN-logM))
算法穩定性
桶排序算法在對每個桶進行排序時,若選擇穩定的排序算法,則排序後,相同元素的位置不會發生改變,所以桶排序算法是一種穩定的排序算法。
總結
本篇文章就到這裡瞭,希望能給你帶來幫助,也希望您能夠多多關註WalkonNet的更多內容!
推薦閱讀:
- java版十大排序經典算法:完整代碼(4)
- Java List的sort()方法改寫compare()實現升序,降序,倒序的案例
- Java集合案例之鬥地主遊戲
- Java 數組轉List的四種方式小結
- 關於二分法查找Java的實現及解析