[Algoritmo de clasificación clásico] 9. Clasificación de grupos

La clasificación de depósitos divide los datos que se van a clasificar en varios intervalos (los distintos intervalos se ordenan en sí mismos), denominados depósitos. Cada depósito clasifica sus elementos y luego fusiona los datos en los depósitos para completar la clasificación. La clasificación de depósitos debe distribuir los datos de manera uniforme en el depósito. Si los datos están todos en un depósito, la clasificación degenerará en el tipo de clasificación del depósito.

La clasificación por recuento se puede considerar como una clasificación extrema de cubos. Un número corresponde a un cubo, y un cubo solo almacena un número específico (no un número de intervalo).

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

public class Main {
    public static void main(String[] args) {
        int[] arr = {3, 5, 6, 2, 1, 7, 4};
        System.out.print("排序前:");
        arrPrint(arr);
        int[] result = BucketSort(arr, 4);
        System.out.print("排序后:");
        arrPrint(result);
    }

    // 桶排序
    // bucketsize用于定义桶排序时候桶的size/长度,分配的桶数量则为(max - min)/bucketsize + 1
    // 实例中bucketsize设为4,桶数量bucketnum则为2。
    //
    //
    // 最大最小值max和min初始化为arr的第一个元素,遍历arr元素,把总是比max大的数赋给max,
    // 把总是比min小的数赋给min。得到arr中的最大最小值max和min。
    //
    // 计算桶数量bucketnum = (max - min)/bucketsize + 1,桶排序是将待排序数组arr
    // 中的元素,平均切分到 bucketnum 这么多个区间的排序,因此max-min计算区间范围长度,
    // 在本实例中max-min=6,÷桶的长度bucketsize=4,再+1即可得到bucketnum=2(除法+1,相
    // 当于除法的余数向上取整)。
    // (参考计数排序中,利用-min操作,将arr[i]∈[min,max]映射到方便从0索引的
    // arr[i]-min∈[0,max-min]的操作,桶排序的桶区间元素同样如此)
    //
    // 利用ArrayList数据类型开辟桶空间buckets,容量声明为bucketnum。
    // 第一个for循环,遍历buckets,索引从0遍历到bucketnum,在buckets开辟的空间中
    // 填入ArrayList<Integer>,作为桶空间来存储元素(并排序)。bucketnum为2就填入2个
    // ArrayList<Integer>。
    //
    // 第二个for循环,遍历arr的元素,利用arr[i]-min的映射,将arr[i]∈[min,max]的分布,
    // 映射到 arr[i]-min∈[0,max-min]的分布,方便我们利用桶索引来对应元素。
    // 同时由于[0,max-min]已经被buckets切分为 bucketnum=2 份了,
    // 所以(arr[i]-min)/bucketsize 得到的除数正好可以作为桶索引bkindex,
    // 本实例中第一个bucketsize的范围是[0,bucketsize - 1],第二个桶的范围
    // 是[bucketsize, max - min]。如果(arr[i]-min)/bucketsize除数为0,
    // 说明arr[i]应该放入第一个桶,以此类推。得到桶索引bkindex后利用ArrayList
    // get方法取得桶,add方法将元素放入桶即可:buckets.get(bkindex).add(arr[i])
    //
    // 第三个for循环,对每个桶各自使用排序(这里使用Collections的自带排序)。
    //
    // 第四个for循环组,for双循环,第一个for,索引为i,顺序遍历buckets的每一个桶
    // buckets.get(i)。第二个for,索引为j,顺序遍历每个桶中的每一个元素(已被排序)
    // buckets.get(i).get(j),元素存入result中即可。
    // 最后返回result。
    // 注:查看桶情况可插入 System.out.println(buckets.toString()) 来打印桶
    private static int[] BucketSort(int[] arr, int bucketsize) {
        int max = arr[0];
        int min = arr[0];
        for (int num: arr) {
            if (max < num)
                max = num;
            if (min > num)
                min = num;
        }
        int bucketnum = (max - min) / bucketsize + 1;
        ArrayList<ArrayList<Integer>> buckets = new ArrayList<>(bucketnum);
        for (int i = 0; i < bucketnum; i++) {
            buckets.add(new ArrayList<Integer>());
        }

        for (int i = 0; i < arr.length; i++) {
            int bkindex = (arr[i] - min) / bucketsize;
            buckets.get(bkindex).add(arr[i]);
        }

        for (int i = 0; i < buckets.size(); i++) {
            Collections.sort(buckets.get(i));
        }

        int index = 0;
        int[] result = new int[arr.length];
        for (int i = 0; i < buckets.size(); i++) {
            for (int j = 0; j < buckets.get(i).size(); j++) {
                result[index++] = buckets.get(i).get(j);
            }
        }
        return result;
    }

    // 辅助函数:将int[] 打印出来
    private static void arrPrint(int[] arr) {
        StringBuilder str = new StringBuilder();
        str.append("[");
        for (int v : arr) {
            str.append(v + ", ");
        }
        str.delete(str.length() - 2, str.length());
        str.append("]");
        System.out.println(str.toString());
    }
}

La demostración animada de este ejemplo es la siguiente:

Inserte la descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/fisherish/article/details/114479002
Recomendado
Clasificación