Javaは一般的なソートアルゴリズムを達成するために、(4)基数ソート

みなさん、こんにちは、私はアヒル午前:    

   発注の今日、株式ベースの基数ソートアルゴリズム。

 

1.基数ソート:


原理:基数ソート(基数ソート)も「バケット法」(バケットソート)やビン一種として知られている(流通ソート)、「順序を割り当て」されています。

均一なビット長の同じ数、先行ゼロを持つ桁短い数を比較するすべての値(正の整数)。その後、最低のスタートから、一度にソート。これが完了すると、シリーズは、順序付けられたシーケンスとなったビットの最上位に低いものからソートされています。

アイデア:

基数ソート、つまり一種のデジタル1ビット、アイデアアルゴリズム我々は、多くの場合、普通の生活を使用する:あなたはソート日付、年によって日付、月、日からなる、そのことについては、私たちは多くの場合、使用したい場合同じことが、月に比べればまだ比較的即日場合には、比較の最初の年です。

以下の4つの数字の並べ替え:123312245531

   ビット=> 10 =>百

   53 1       3 1 2       1 23

   31 2       1 2 3       2 45

   12 3       5 3 1       3 12

   24 5       2 4 5       5 31

コードの実装:

 /**
     * 基数排序
     * @param d
     * @param array
     *  时间复杂度 O的log2 N
     *  基数排序 运用二维数组来分别比较每一位,个位、十位、百位…
     * 输入10个整数的数组
     */
    private void radixSort(int d,int[] array){
        long nowTime = System.nanoTime();
        int n=1;//代表位数对应的数:1,10,100000...
        int k=0;//保存每一位排序后的结果用于下一位的排序输入
        int[][] bucket=new int[10][array.length];//排序桶用于保存每次排序后的结果,这一位上排序结果相同的数字放在同一个桶里
        int[] num=new int[array.length];//用于保存每个桶里有多少个数字 ,最多为输入数组长度
        while(n<=d)
        {
            for(int e:array) //将数组array里的每个数字放在相应的桶里
            {
                int digit=(e/n)%10;
                bucket[digit][num[digit]]=e;
                num[digit]++;
            }
            for(int i=0;i<array.length;i++)//将前一个循环生成的桶里的数据覆盖到原数组中用于保存这一位的排序结果
            {
                if(num[i]!=0)//这个桶里有数据,从上到下遍历这个桶并将数据保存到原数组中
                {
                    for(int j=0;j<num[i];j++)
                    {
                        array[k]=bucket[i][j];
                        k++;
                    }
                }
                num[i]=0;//将桶里计数器置0,用于下一次位排序
            }
            n*=10;
            k=0;//将k置0,用于下一轮保存位排序结果
        }
        System.out.println("基数排序,花费时间(ms):" + ((System.nanoTime() - nowTime) / 1000000.0) + "ms");
    }

基数ソートアルゴリズムは、rが取ら基数であり、そしてmはヒープの数であり、O(nlog(登録商標)M)であり、これは複雑さ、安定した、非常に効率的です。しかし、それは、整数のみの並べ替え、および補足スペースを使用する必要になることができます。

上記の制限は、コードの一部が、選択されたグループの値に適用することです。

int [] x = {25 ,11 ,22 ,34 ,15 ,44 ,76, 66, 100, 8 ,14, 20 ,2, 5 ,1 };

例えば、この配列は、ベース3を選択すべきです。ベース値を選択する方法を取り付けます。

 /**
     * 获取基数排序中的基数
     * @param array
     * @return
     */
    public int getRadixBasicNumber(int[] array){
        if(array == null && array.length ==0) {
            return 0;
        }
        int max =0;
        //1获取最大的绝对值的数
        for(int i =0;i<array.length;i++) {
            if(Math.abs(max)<Math.abs(array[i])) {
                max = array[i];
            }
        }
        int times = 0;
        if(max<0) max = -max;
        //2求出最大的绝对值的数,是10的times次幂。
        while(max >0) {
            max = max/10;
            times ++;
        }
        return times;
    }

 

時間のかかる比較:

ランダムデータランの図10Wピース:

それぞれ、比較基数ソート、インラインソート、シェルソート、およびクイックソート。ギャップは明らかです。

ランダムデータランの図50Wピース:

それぞれ、比較基数ソート、インラインソート、シェルソート、およびクイックソート。ギャップは明らかです。

ランダムデータランの図100Wピース:

それぞれ、比較基数ソート、インラインソート、シェルソート、およびクイックソート。ギャップは明らかです。

要約:

基数ソート

長所:高効率。

短所:大容量メモリフットプリント、唯一のソート正の整数の(2次元配列は、バレルを行います)

最悪時間計算量:O(P(N + B))。

平均時間計算量は次のとおりO(P(N + B))。

Pソート、N要素の数をソートすることの回数であり、Bは、バレルの数です。

様々なソート方法の比較:

 

その他のソートアルゴリズム:

バブルソート:   https://blog.csdn.net/Angry_Mills/article/details/81057900

挿入ソート:   https://blog.csdn.net/Angry_Mills/article/details/81208700

クイックソート:   https://blog.csdn.net/Angry_Mills/article/details/83339390

公開された115元の記事 ウォン称賛58 ビュー23万+

おすすめ

転載: blog.csdn.net/Angry_Mills/article/details/83383572