[常用排序算法] 桶排序 (Bucket Sort)

一 基本思想

桶排序是计数排序的升级版。它利用了函数的映射关系,高效与否的关键就在于这个映射函数的确定。桶排序 (Bucket sort)的工作的原理:假设输入数据服从均匀分布,将数据分到有限数量的桶里,每个桶再分别排序(有可能再使用别的排序算法或是以递归方式继续使用桶排序进行排)。

二 算法描述

第1步,求数列最大最小值,运算量为n。

第2步,创建空桶,运算量为n。

第3步,把原始数列的元素分配到各个桶,运算量为n。

第4步,把每个桶内部做排序,在元素分布相对均匀的情况下(即一个桶只有一个元素),所有桶的运算量之和为n。

第5步,输出排序数列,运算量为n。

总上所述,桶排序的总体时间复杂度为O(n+n+n+n+n)=O(n)

空间复杂度同样是O(n)。

三 图片演示

在这里插入图片描述

四 代码实现

import java.util.*;
public class TongSort {
    public static void main(String[] args){
        //double[] arr = new double[] {4.12,6.421,0.0023,3.0,2.123,8.122,4.12, 10.09};
        int[] arr = {2, 4, 11, 0, 54,433, 90};
        //printArr(arr);
        // tSort(arr);
        //printArr(arr);
        arr = tSort(arr);
		System.out.println("排序后: " + Arrays.toString(arr));

    }
    public static int[] tSort(int[] arr){
        //确定最大最小值,获得总差值
        int min = arr[0];
        int max = arr[0];
        for(int i = 1;i<arr.length;i++){
            if(arr[i] < min){
                min = arr[i];
            }
            if(arr[i] >max){
                max = arr[i];
            }
        }
        int d = max -min;
        //初始化桶
        int bucketNum = max -min;
        ArrayList<LinkedList<Integer>> bucketList = new ArrayList<>(bucketNum);
        for(int i = 0;i<bucketNum;i++){
            bucketList.add(new LinkedList<Integer>());
        }
        //往桶里装元素
        for(int i =0;i<arr.length;i++){
            //获得桶下标
            int bucketIndex = (int)((arr[i]-min)/d * (bucketNum-1));// 偏移量:总差值 = 桶下标:(总桶数-1)
			bucketList.get(bucketIndex).add(arr[i]);

        }
        for(int i =0; i<bucketList.size();i++){
            Collections.sort(bucketList.get(i)); //桶内部排序
        }
        //创建输出数组
        int[] sortArray = new int[arr.length];
		int index = 0;
		for(LinkedList<Integer> list : bucketList) {
			for(int element : list) {
				sortArray[index++] = element;
			}
		}
		return sortArray;

    }
    // public static void printArr(int[] arr){
    //     for(int i = 0; i<arr.length;i++){
    //         if(i==0){
    //             System.out.print("["+arr[i]+",");
    //         }else if(i == arr.length - 1){
    //             System.out.print(arr[i]+"]");
    //         }else {
    //             System.out.print(arr[i]+",");
    //         }
    //     }
    //     System.out.println("");
    // }
}

五 算法分析

  • 复杂度分析:

  • 空间复杂度
    空间复杂度为O(n)

  • 时间复杂度

  • 最优时间复杂度:O(n)
    最坏时间复杂度:O(nlogn)
    平均时间复杂度:O(n)

  • 是否属于原地排序算法
    不是一种原地排序算法

  • 稳定性:
    稳定

  • 适应范围:
    适应外部排序,即数据量比较大,但是数据范围比较小的排序

参考链接 https://blog.csdn.net/Xidian2850/article/details/91128690
https://blog.csdn.net/mazhaMJ/article/details/92629394

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值