カーディナリティの並べ替えを理解する

カーディナリティソートは、非比較の整数ソートアルゴリズムであり、その原理は、整数を桁ごとに異なる数値にカットし、各桁ごとに比較することです。整数は文字列(名前や日付など)や浮動小数点数を特定の形式で表現することもできるため、基数ソートは整数に限定されません。

1.カーディナリティソートvs.カウントソートvs.バケットソート

基数ソートには2つの方法があります。

これらの3つの並べ替えアルゴリズムはすべてバケットの概念を使用していますが、バケットの使用には明らかな違いがあります。

  1. カーディナリティソート:キー値の各桁に従ってバケットを割り当てます。
  2. ソートのカウント:各バケットは単一のキー値のみを格納します。
  3. バケットソート:各バケットは特定の範囲の値を格納します。

2.LSDカーディナリティソートアニメーションデモ

コード:

JavaScript

インスタンス

// LSD基数ソート
varcounter = []; 
関数radixSort(arr、maxDigit){ 
    var mod = 10; 
    var dev = 1; 
    for(var i = 0; i <maxDigit; i ++、dev * = 10、mod * = 10){ 
        for(var j = 0; j <arr.length; j ++){varbucket 
            = parseInt((arr [j] %mod)/ dev); 
            if(counter [bucket] == null){ 
                counter [bucket] = []; 
            } 
            counter [bucket] .push(arr [j]); 
        } 
        var pos = 0; 
        for(var j = 0; j <counter.length; j ++){ 
            var value = null; 
            if(counter [j]!= null){ 
                while((value = counter [j] .shift())!= null){
                      arr [pos ++] =値; 
                }
          } 
        } 
    } 
    return arr; 
}

Java

インスタンス

/ ** 
 *基数ソート
 *負の数の場合も参照できます:https:
//code.i-harness.com/zh-CN/q/e98fa9 
 * / public class RadixSortimplements IArraySort { 

    @Override 
    public int [ ] sort(int [] sourceArray)throws Exception { 
        //パラメータの内容を変更せずにarrをコピーする
        int [] arr = Arrays.copyOf(sourceArray、sourceArray.length); 

        int maxDigit = getMaxDigit(arr); 
        return radixSort(arr、maxDigit ); 
    } 

    / 
    ***
     最上位桁を取得
     * / private int getMaxDigit(int [] arr){ 
        int maxValue = getMaxValue(arr); 
        return getNumLenght(maxValue); 
    }
 
    private int getMaxValue(int [] arr){
        int maxValue = arr [0]; 
        for(int value:arr){ 
            if(maxValue <value){ 
                maxValue = value; 
            } 
        } 
        return maxValue; 
    } 

    protected int getNumLenght(long num){ 
        if(num == 0){ 
            return 1; 
        } 
        int lenght = 0; 
        for(long temp = num; temp!= 0; temp / = 10){ 
            lenght ++; 
        } 
        return lenght; 
    } 

    private int [] radixSort(int [] arr、int maxDigit){ 
        int mod = 10; 
        int dev = 1;

        for(int i = 0; i <maxDigit; i ++、dev * = 10、mod * = 10){ 
            //負の数の場合を考えます。ここでは、キューの数を2倍にします。ここで、[0-9]は負の数に対応します。数値、[10-19]正の数(バケット+ 10)に対応
            int [] [] counter = new int [mod * 2] [0]; 

            for(int j = 0; j <arr.length; j ++) { 
                intバケット=((arr [j]%mod)/ dev)+ mod; 
                counter [bucket] = arrayAppend(counter [bucket]、arr [j]); 
            } 

            int pos = 0; 
            for(int []バケット: counter){ 
                for(int value:bucket){ 
                    arr [pos ++] = value; 
                } 
            } 
        } 

        return arr; 
    } 

    / **
     *データを自動的に展開して保存します
     ** 
     * @param編曲:
     * @param値
     * / 
    private int [] arrayAppend(int [] arr、int value){ 
        arr = Arrays.copyOf(arr、arr.length + 1); 
        arr [arr.length-1] =値; 
        到着を返す; 
    } 
}

PHP

インスタンス

function radixSort($ arr、$ maxDigit = null)
{ 
    if($ maxDigit === null){ 
        $ maxDigit = max($ arr); 
    } 
    $ counter = []; 
    for($ i = 0; $ i <$ maxDigit; $ i ++){ 
        for($ j = 0; $ j <count($ arr); $ j ++){ 
            preg_match_all( '/ \ d /'、(string)$ arr [$ j]、$ matches); 
            $ numArr = $ matches [0]; 
            $ lenTmp = count($ numArr); 
            $ bucket = array_key_exists($ lenTmp- $ i-1、$ numArr)intval($ numArr [$ lenTmp- $ i-1])
                :0; 
            if(!array_key_exists($ bucket、$ counter)){ 
                $ counter [$ backup] = []; 
            }
            $ counter [$ bucket] [] = $ arr [$ j]; 
        } 
        $ pos = 0; 
        for($ j = 0; $ j <count($ counter); $ j ++){ 
            $ value = null; 
            if($ counter [$ j]!== null){ 
                while(($ value = array_shift($ counter [$ j]))!== null){ 
                    $ arr [$ pos ++] = $ value; 
                } 
          } 
        } 
    } 

    return $ arr; 
}

C ++

インスタンス

int maxbit(int data []、int n)//補助関数、データの最大桁数を見つける
{ 
    int maxData = data [0]; /// <最大数
    ///最初に最大数を見つけてから、このようにして、各番号の元の番号が順番に判断され、わずかに最適化されます。
    for(int i = 1; i <n; ++ i)
    { 
        if(maxData <data [i])
            maxData = data [i]; 
    } 
    int d = 1; 
    int p = 10; 
    while(maxData> = p)
    { 
        // p * = 10; //多分オーバーフロー
        maxData / = 10; 
        ++ d; 
    } 
    return d; 
/ * int d = 1; //最大桁数を保存intp 
    = 10; 
    for(int i = 0; i <n; ++ i)
    { 
        while(data [i]> = p) 
        {
            p * = 10; 
            ++ d; 
        } 
    } 
    return d; * / 
} 
void radixsort(int data []、int n)//基数ソート
{ 
    int d = maxbit(data、n); 
    int * tmp = new int [ n]; 
    int * count = new int [10]; //カウンター
    inti、j、k; 
    int radix = 1; 
    for(i = 1; i <= d; i ++)//シーケンスd回
    { 
        for(j = 0; j <10; j ++)
            count [j] = 0; //各割り当ての前にカウンターをクリア
        for(j = 0; j <n; j ++)
        { 
            k =(data [j] / radix)%10; //各バケットのレコード数を
            カウントしますcount [k] ++; 
        } 
        for(j = 1; j <10; j ++)
            count [j] = count [j-1] + count [j]; // tmp内の位置を各バケットに順番割り当てます
        for(j = n-1; j> = 0; j-)//バケット内のすべてのレコードを順番にtmpに収集します
        { 
            k =(data [j] / radix)%10; 
            tmp [count [k] --1] = data [j]; 
            count [k]-; 
        } 
        for(j = 0; j <n; j ++)//一時配列の内容をデータにコピーします
            data [j] = tmp [j]; 
        radix = radix * 10; 
    } 
    delete [] tmp; 
    delete [] count; 
}

C

インスタンス

#include 
#define MAX 20 
//#define SHOWPASS 
#define BASE 10 

void print(int * a、int n){ 
  int i; 
  for(i = 0; i <n; i ++){ 
    printf( "%d \ t"、a [i]); 
  } 
} 

void radixsort(int * a、int n){ 
  int i、b [MAX]、m = a [0]、exp = 1; 

  for(i = 1; i <n; i ++){ 
    if(a [i]> m){ 
      m = a [i]; 
    } 
  } 

  while(m / exp> 0){ 
    intbucket [BASE] = {0}; 

    for(i = 0; i <n; i ++){
      バケット[(a [i] / exp)%BASE] ++; 
    } 

    for(i = 1; i <BASE; i ++){
      バケット[i] + =バケット[i-1]; 
    }

    for(i = n-1; i> = 0; i-){ 
      b [ -bucket [(a [i] / exp)%BASE]] = a [i]; 
    } 

    for(i = 0; i <n; i ++){ 
      a [i] = b [i]; 
    } 

    exp * = BASE; 

#ifdef SHOWPASS 
    printf( "\ nPASS:"); 
    print(a、n); 
#endif 
  } 
} 

int main(){ 
  int arr [MAX]; 
  int i、n; 

  printf( "要素の総数を入力してください(n <=%d):"、MAX); 
  scanf( "%d"、&n); 
  n = n <MAX?n:MAX; 

  printf( "Enter%d Elements:"、n); 
  for(i = 0; i <n; i ++){ 
    scanf( "%d"、&arr [i]); 
  } 

  printf( "\ nARRAY:");

  基数ソート(&arr [0]、n); 

  printf( "\ nSORTED:"); 
  print(&arr [0]、n); 
  printf( "\ n"); 

  0を返します。
}

取る

インスタンス

-获取表中位数
localmaxBit = function(tt)
    local weight = 10; -10進制
    ローカルビット= 1; 
   
    kの場合、ペア(tt)の
        v、v> =重みdo
            重み=重み* 10; 
            ビット=ビット+1;  
        エンド
    エンド
    リターンビット; 
エンド
-基数排序
ローカル基数ソート=関数(TT)
    ローカルmaxbit = maxBit(TT)。

    ローカルバケット= {}; 
    ローカル温度= {}; 
    ローカル基数= 1; 
    i = 1の場合、maxbitは
        j = 1の場合、10は
            bucket [j] = 0を実行します。---清空桶
        kについて、対にV(TT)を行います
            ローカル余り= math.floor((V /基数))10%+ 1。    
            バケット[剰余] =バケット[剰余] +1;バケットの場合、各バケットの数は自動的に1
        エンドずつ増加
       
            ます。 [j] =バケット[j-1] +バケット[j];-各バケットの数=前のバケットの数と+
        自分の端の数
        -バケットの位置に応じて、並べ替え-これはバケット並べ替えです、逆順を使用する必要があります。並べ替え方法が小さいものから大きいものへあるため、順序が下がっており、小さいものから大きいものがクリアされます。
        for k =#tt、1、-1do
            ローカル剰余= math.floor((tt [k] /基数))%10 + 1; 
            temp [bucket [remainder]] = tt [k]; 
            bucket [remainder] =バケット[剰余] -1;
        ペアでk、vの
        終了(temp)do 
            tt [k] = v;
        終了
        基数=基数* 10;
    エンド
エンド;

おすすめ

転載: blog.csdn.net/yaxuan88521/article/details/114114672