13 | 线性排序:如何根据年龄给100万用户数据排序?

本文介绍了线性排序的三种算法:桶排序、计数排序和基数排序。桶排序利用分桶策略进行排序,适合外部排序;计数排序是一种特殊形式的桶排序,适用于元素范围较小的情况;基数排序则通过处理数据的每一位来实现排序,要求数据可分高位和低位。三种排序的时间复杂度均为O(n),但适用场景各有不同。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今日内容

1、桶排序 2、计数排序 3、基数排序

这些排序算法的时间复杂度是线性的(原因是这三个算法是非基于比较的排序算法,都不涉及元素之间的比较操作。),所以我们把这类排序算法叫作线性排序(Linear sort)

这三种排序算法的时间复杂度是 O(n)

一、桶排序(Bucket sort)

1、分桶的时候,应该怎么分?分几个?每个范围是多少?
2、放入桶的时候,应该怎么查找放入哪一个桶?

1、核心思想

在一个数组中找到最大值和最小值,然后根据最大值和最小值、数组长度得出桶的个数和每个桶的范围。(有序的桶)然后遍历整个数组每个元素,去对比在哪个桶内?并且放入对应桶中,最后把每个桶单独排序,把每个桶连起来后就是有序的了。

在这里插入图片描述

2、代码实现

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedList;

/**
 * 桶排序
 */
public class BucketSort {
   
    public static void main(String[] args) {
   
       double[] arr = {
   1.2,2.5,9.5,1.3,1.1};


        double[] doubles = bucketSort(arr);
       System.out.println(Arrays.toString(doubles));
    }

    public static double[] bucketSort(double[] array){
   
        //得到数列的最大值和最小值,并计算出差值d
        double max=array[0];
        double min=array[0];
        for (int i=1;i<array.length;i++){
   
            if (array[i]>max){
   
                max=array[i];
            }
            if (array[i]<min){
   
                min=array[i];
            }
        }
        double d=max-min;

        //初始化桶     初始化一个集合(集合类型是集合)设置长度为原数组的大小
        int bucketNum=array.length;//求桶的个数(和每个桶的范围)公式不是唯一,只要尽量将数据均匀分布即可。
//        int bucketNum = (max - min) / arr.length + 1;
        ArrayList<LinkedList<Double>> bucketList=new ArrayList<LinkedList<Double>>(bucketNum);
        for (int i=0;i<bucketNum;i++){
   
            //添加满集合
            bucketList.add(new LinkedList<Double>());
        }

        //遍历原始数组将每个元素放入桶中
        for (int i=0;i<array.length;i++){
   
            //桶的编号(索引):当前值与最小值之间的差值。d:最大最小值的差值
            int num=(int)((array[i]-min)*(bucketNum-1)/d);
//            int num = (arr[i] - min) / (arr.length);
            //得到对应索引位置的桶(集合类型),然后将当前值添加到该桶。
            bucketList.get(num).add(array[i]);
        }

        //对每个桶内部进行排序
        for(int i=0;i<bucketList.size();i++){
   
            // 使用Collections.sort,其底层实现基于归并排序或归并排序的优化版本
            Collections.sort(bucketList.get(i));
        }

        //输出全部元素
        double[] sortedArray=new double[array.length];
        int index=0;
        for (LinkedList<Double> list:bucketList) {
   
            for (double element:list){
   
                sortedArray[index]=element;
                index++;
            }
        }
        return sortedArray;
    }

}

3、应用场景(桶排序比较适合用在外部排序中)

比如说我们有 10GB 的订单数据,我们希望按订单金额(假设金额都是正整数)进行排序,但是我们的内存有限,只有几百 MB,没办法一次性把 10GB 的数据都加载到内存中。这个时候该怎么

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值