二十二、自己動手實現排序算法(10)------“ Bucket Sort 桶排序 ”

參考文章:

https://www.cnblogs.com/guoyaohua/p/8600214.html                  十大經典排序算法最強總結(含JAVA代碼實現)

https://mp.weixin.qq.com/s/qrboxA5SwN7AbAcpZ_dpNQ             漫畫:什麼是桶排序?

https://www.runoob.com/w3cnote/bucket-sort.html                        1.9 桶排序

https://github.com/hustcc/JS-Sorting-Algorithm/blob/master/9.bucketSort.md     桶排序


桶排序分析:

平均時間複雜度 最好情況 最壞情況 空間複雜度 排序方式 穩定性
O(n+k) O(n+k) O(n^2) O(k) Out-place 穩定

溫馨提示:

        如果代碼看不懂,那就拿出紙和筆,照着代碼流程走一遍,走一遍,再走一遍,另外看基數排序,最好先把其他的排序都給看了,再看這個會好理解一些。

 

桶排序原理:

       桶排序是計數排序的升級版。它利用了函數的映射關係,高效與否的關鍵就在於這個映射函數的確定。

       桶排序 (Bucket sort)的工作的原理: 假設輸入數據服從均勻分佈,將數據分到有限數量的桶裏,每個桶再分別排序(有可能再使用別的排序算法或是以遞歸方式繼續使用桶排序進行排序。

 

算法描述:

  • 人爲設置一個BucketSize,作爲每個桶所能放置多少個不同數值(例如當BucketSize==5時,該桶可以存放{1,2,3,4,5}這幾種數字,但是容量不限,即可以存放100個3);
  • 遍歷輸入數據,並且把數據一個一個放到對應的桶裏去;
  • 對每個不是空的桶進行排序,可以使用其它排序方法,也可以遞歸使用桶排序;
  • 從不是空的桶裏把排好序的數據拼接起來。 

注意,如果遞歸使用桶排序爲各個桶排序,則當桶數量爲1時要手動減小BucketSize增加下一循環桶的數量,否則會陷入死循環,導致內存溢出。

 

桶排序圖解:

 

Java 代碼實現:

代碼一:


package com.sorting.algorithm;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class BucketSort {
	
	public static int[] bucketSort(int[] array ){
		
		// 1,計算最大最小值,劃分桶區間
		int max = array[0], min = array[0];
		for (int i = 0; i < array.length; i++) {
			if(max < array[i])
				max = array[i];
			if(min > array[i])
				min = array[i];
		}
		
		// 創建len個桶,桶內裝入的元素用 arraylist 存儲,每個桶的大小最多爲len個元素
		int bucketNum = 10;
		int len = (max - min)/bucketNum + 1;
		ArrayList<ArrayList<Integer>> buckets = new ArrayList<>(len);
		// 對桶進行初始化
		for (int i = 0; i < len; i++) {
			buckets.add(new ArrayList<Integer>());
		}
		
		// 2, 將數組中的數據放入桶中,並進行排序
		for (int i = array.length-1; i >= 0; i--) {
			int index =(int) Math.floor((array[i] -min)/bucketNum);
			buckets.get(index).add(array[i]);
		}
		
		// 將桶中數據進行排序
		for (int i = 0; i < buckets.size(); i++) {
			Collections.sort(buckets.get(i));
			System.out.println(buckets.get(i));
		}
		
		// 3, 將桶中排序好的數據拿出,放到數組中
		int index=0;
		int[] sortedArr = new int[array.length];
		for (int i = 0; i < buckets.size(); i++) {
			for (int j = 0; j < buckets.get(i).size(); j++) {
				sortedArr[index++] = buckets.get(i).get(j);
			}
		}
		
		return sortedArr;
	}
	
	public static void printArr(int[] array){
		for (int i = 0; i < array.length; i++) {
			if(i != array.length-1)
				System.out.print(array[i]+ ", ");
			else
				System.out.println(array[i]);
		}
		System.out.println();
	}
	
	public static void printArr(List<Integer> array){
		for (int i = 0; i < array.size(); i++) {
			if(i != array.size()-1)
				System.out.print(array.get(i)+ ", ");
			else
				System.out.println(array.get(i));
		}
		System.out.println();
	}
	
	public static void main(String[] args) {
		
		int[] array = {3,14,28,56,27,66,33,21,21,22,23,43,37,33,31};
		
		System.out.println("排序之前:");
		
		printArr(array);
		int[] sortedArr = bucketSort(array);

		System.out.println("排序之後:");
		printArr(sortedArr);
	}
}

 

 

 

 

桶排序代碼測試:

代碼一:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章