割り当てソートのカーディナリティー・ソート(Java言語の説明)

カーディナリティの並べ替え

カーディナリティソートは、カウントソートのアプリケーション拡張であり、割り当てソートの特殊なケースです。カウントソート(バケットソート)は、小数の範囲でのソートに適していますが、大きな数値には効率的ではありません。・基数の性質を利用し、16進数の範囲内で多数を10進数に分解し、複数回カウント等の安定したソートを行い、多数の範囲内でのソート機能を実現します。

たとえば、2桁間の並べ替えの問題の場合、通常は10桁から始め、同じ桁を10桁と比較してから、桁を比較し、最終的に目的の結果を取得します。基本的な並べ替えのプロセスはほぼ同じです。違いは、数十または同じ数の場合、カウントソートプロセスを使用します。中央の要素を比較する必要はありません。

カーディナリティの並べ替えは、最上位桁優先方式(MSD)と最下位桁優先方式(LSD)に分けられます。コンピューターが高優先順位方式を実装する場合、再帰的な分割統治であるバケットスペースの割り当てをネストする必要があります。アルゴリズムの実行はより複雑であるため、LSDの実装がより一般的です。

LSD配列ベースの実装コードは次のとおりです。

import java.util.Arrays;

public class RadixSort {

    public static void main(String[] args) {
        int[] arr = new int[] { 97, 53, 88, 59, 26, 41, 88, 31, 22 };
        arr = radixSort(arr, 9, 2, 10);
        System.out.println(Arrays.toString(arr));
    }

    /**
     * 
     * @param array 排序序列
     * @param n     排序序列元素数
     * @param d     排序位数(两位数传入2)
     * @param r     基
     */
    public static int[] radixSort(int[] array, int n, int d, int r) {
        // 内部桶排序时用以保存各桶中的元素数
        int[] count = new int[r];
        // 按照不同基位进行桶排序时存放元素
        int[] tmpArray = new int[n];
        // 模除数,计算桶位
        int radix = 1;

        // 临时变量,用于计算每个元素的桶位,避免重复声明
        int k = 0;

        // 进行d轮计数排序(/桶排序)
        for (int i = 0; i < d; i++) {
            // 每轮循环,须重新初始化count数组
            for (int j = 0; j < r; j++) {
                count[j] = 0;
            }

            // 遍历原始数组,计算每个桶位的元素数,存储于count数组
            for (int j = 0; j < n; j++) {
                k = (array[j] / radix) % r;
                count[k]++;
            }
            // 计数器对应位数值修改为下一位的开始位置
            for (int j = 1; j < r; j++) {
                count[j] = count[j] + count[j - 1];
            }
            
            // 进行桶排序过程
            for (int j = n - 1; j >= 0; j--) {
                // 计算元素桶位
                k = (array[j] / radix) % r;
                count[k]--;
                tmpArray[count[k]] = array[j];
            }
            
            // 回写到原数组
            for (int j = 0; j < n; j++) {
                array[j] = tmpArray[j];
            }

            // 基位递增
            radix *= r;
        }
        return array;
    }
}

まとめ

基数ソートの主な考え方は、基数に従ってソートされた要素を分割することです。分割後の各値は16進数の値に属します。これに基づいて、バケットのソートは各桁に従って実行されます。これは、直感的な理解とは異なります。再帰的な分割統治アルゴリズムを処理する場合、コンピューターはより複雑になるため、一般的な実装はLSDの低い優先度のアルゴリズムです。少し考慮すると、高優先度のMSDと低優先度のLSDの直観的な違いは、並べ替えの処理方向が異なることだけです。

推奨情報:
Radix sort-Wikiwand

詳細については、私の公開アカウントに注目してください。
私の公開アカウント

元の記事を159件公開 賞賛された225件 210,000回の閲覧

おすすめ

転載: blog.csdn.net/lyg673770712/article/details/88047572