二十二、自己动手实现排序算法(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);
	}
}

 

 

 

 

桶排序代码测试:

代码一:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

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