桶排序 【Java】

一、问题描述

利用桶排序算法对整形数组排序。

二、问题分析

假设数组元素最大值和最小值分别为max和min,则桶的个数为max - min + 1,也即数组区间[min, max]每个元素和桶下标区间[0,max - min + 1]中每个元素一一对应,这也是桶排序的核心思想。


(1)数组元素与桶下标对应关系

元素arr[i]------>桶下标arr[i] - min

例如:

数组元素为:-1 ,-3 ,0 ,2 ,4 ,4 ,3 ,6 ,9

对应桶下标:2  , 0 ,3 ,5 ,7 ,7 ,6 ,9 ,12


(2)数组元素arr[i]在排序后的序列中的下标为bucket[arr[i] - min]

分析如下:

假设数组元素为:-1 ,-3 ,0 ,2 ,4 ,4 ,3 ,6 ,9,请注意下面三行中相同位置的元素对应关系

遍历一次数组后,可以得到(1)中各元素对应的桶下标,可以得到桶元素为: [1, 0, 1, 1, 0, 1, 1, 2, 0, 1, 0, 0, 1]

                                       其中,桶中非0元素对应数组元素情况为: -3    -1  0      2  3  4       6         9    

再处理一次桶中元素使bucket[i] = bucket[i] + bucket[i - 1],操作后桶元素为:     [1, 1, 2, 3, 3, 4, 5, 7, 7, 8, 8, 8, 9]

处理之后,桶中i位置元素值即为落入桶i中数组元素在排序后的序列中的下标值。

因为此时桶中i位置元素值为所有小于落入桶i位置数组元素的数组元素个数总和。

三、算法代码

public static void bucketSort(int [] arr){
		System.out.println("排序前数组:" + Arrays.toString(arr));
		System.out.println();
		
		//寻找数组中min,max,用于建桶
		int min = 0, max = 0;
		for(int i = 0; i <= arr.length - 1; i++){
			if(arr[i] < min){
				min = arr[i];
			}
			if(arr[i] > max){
				max = arr[i];
			}
		}
		System.out.println("预处理信息:" + "min:" + min + " " + "max:" + max);
		System.out.println();
		
		//开始建桶,注意桶的数量等于max - min + 1
		System.out.println("排序过程中桶状态:");
		int bucketCount = max - min + 1;
		System.out.println("桶个数:" + bucketCount + ",桶下标范围0~" + (bucketCount - 1));
		int[] bucket = new int[bucketCount];
		for(int i = 0; i <= arr.length - 1; i++){
			bucket[arr[i] - min]++;
		}
		System.out.println(Arrays.toString(bucket));
		for(int i = 1; i < bucketCount; i++){
			bucket[i] = bucket[i] + bucket[i - 1];
		}
		System.out.println(Arrays.toString(bucket));
		System.out.println();
		
		//开始排序
		int [] copy = new int[arr.length];
		System.arraycopy(arr, 0, copy, 0, arr.length);
		
		//从后往前排序,保持元素相对位置,保证算法稳定性。
		for(int i = arr.length - 1; i >= 0; i--){
			arr[--bucket[copy[i] - min]] = copy[i];
		}
		//若从前往后排序,虽然排序结果相同,但会破坏元素相对位置和算法稳定性
//		for(int i = 0; i <= arr.length - 1; i++){
//			arr[--bucket[copy[i] - min]] = copy[i];
//		}
		System.out.println("排序后数组:" + Arrays.toString(arr));
	}
四、完整测试代码

import java.util.Arrays;

public class BucketSort {

	public static void main(String[] args) {
		int [] arr = {-1,-3,0,2,4,4,3,6,9};
		bucketSort(arr);
	}
	
	public static void bucketSort(int [] arr){
		System.out.println("排序前数组:" + Arrays.toString(arr));
		System.out.println();
		
		//寻找数组中min,max,用于建桶
		int min = 0, max = 0;
		for(int i = 0; i <= arr.length - 1; i++){
			if(arr[i] < min){
				min = arr[i];
			}
			if(arr[i] > max){
				max = arr[i];
			}
		}
		System.out.println("预处理信息:" + "min:" + min + " " + "max:" + max);
		System.out.println();
		
		//开始建桶,注意桶的数量等于max - min + 1
		System.out.println("排序过程中桶状态:");
		int bucketCount = max - min + 1;
		System.out.println("桶个数:" + bucketCount + ",桶下标范围0~" + (bucketCount - 1));
		int[] bucket = new int[bucketCount];
		for(int i = 0; i <= arr.length - 1; i++){
			bucket[arr[i] - min]++;
		}
		System.out.println(Arrays.toString(bucket));
		for(int i = 1; i < bucketCount; i++){
			bucket[i] = bucket[i] + bucket[i - 1];
		}
		System.out.println(Arrays.toString(bucket));
		System.out.println();
		
		//开始排序
		int [] copy = new int[arr.length];
		System.arraycopy(arr, 0, copy, 0, arr.length);
		
		//从后往前排序,保持元素相对位置,保证算法稳定性。
		for(int i = arr.length - 1; i >= 0; i--){
			arr[--bucket[copy[i] - min]] = copy[i];
		}
		//若从前往后排序,虽然排序结果相同,但会破坏元素相对位置和算法稳定性
//		for(int i = 0; i <= arr.length - 1; i++){
//			arr[--bucket[copy[i] - min]] = copy[i];
//		}
		System.out.println("排序后数组:" + Arrays.toString(arr));
	}

}
五、运行结果

排序前数组:[-1, -3, 0, 2, 4, 4, 3, 6, 9]

预处理信息:min:-3 max:9

排序过程中桶状态:
桶个数:13,桶下标范围0~12
[1, 0, 1, 1, 0, 1, 1, 2, 0, 1, 0, 0, 1]
[1, 1, 2, 3, 3, 4, 5, 7, 7, 8, 8, 8, 9]

排序后数组:[-3, -1, 0, 2, 3, 4, 4, 6, 9]




  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值