基数ソート


23

基数ソートでは、最初に最下位桁でソートし、次に2番目に下位桁でソートします。その後、ソート済みリストになります。

数字のリストがある場合、これらの数字を区別するためにビットが必要です。したがって、作成する基数ソートパスの数はなり。各パスは時間かかるため、基数ソートの実行時間はnlog⁡nlog⁡nO(n)O(nlog⁡n)

しかし、線形時間アルゴリズムであることはよく知られています。どうして?


このため、線形時間ソートでは通常、入力が一定範囲の整数である必要があります。基数ソートでは、数字に固定範囲が必要です。あなたの例では、範囲はであると仮定しましたが、数字には任意の整数範囲が可能です。たとえば、を選択した可能性があります[ 0 、√[0,1][0,n]
— ジョー

回答:


19

数字のリストがある場合、ビットが必要ですlog nnlog⁡n

いいえ:からまでの数字のリストがある場合、ビットが必要です。一般に、と間に関係はありません。2 k − 1 k k log n02k−1kklog⁡n

したがって、数値がすべて異なる場合、、および異なる数値の基数ソートは時間複雑度を持ち。一般に、基数の複雑さは、ソートされここで、ソートとする要素の数であり、各要素のビット数です。Ω (N ログN )Θ (nはlog⁡n≥kΩ(nlog⁡n)n kΘ(nk)nk

基数ソートの複雑さはであると言うことは、数値に固定ビットサイズを使用することを意味します。これは、が十分に大きい、重複する値が多数存在することを意味します。nO(n)n


一度に2つの要素を比較することで機能する配列またはリストの並べ替え方法は、最悪の場合より速く実行できないという一般的な定理があり。基数の並べ替えは要素を比較しても機能しませんが、同じ証明方法が機能します。基数ソートは、配列に適用する順列を決定する決定プロセスです。あります配列の順列、および基数ソートはバイナリ決定を行います。つまり、各段階で2つの要素を交換するかどうかを決定します。バイナリ決定の後、基数ソートは個の順列を決定できます。に到達するには可能な順列、です。n !m 2 m n !M ≥ ログ(N !)= Θ (nはログN )Θ(nlog⁡n)n!m2mn!m≥log⁡(n!)=Θ(nlog⁡n)

上記で説明しなかったという証明の前提は、要素が異なる場合にアルゴリズムが機能する必要があるということです。要素がすべて異なるわけではないことが事前にわかっている場合、潜在的な順列の数は完全な。ビット数をソートする場合、場合に別個の要素のみを持つことができます。その場合、基数ソートの複雑さは確かにです。値が大きい場合、衝突が発生する必要があります。これは、基数ソートがときにより小さい複雑さを持つ方法を説明します。K N N ≤ 2 K Ω (N ログN )N Θ (N ログN )N > 2 Kn!knn≤2kΩ(nlog⁡n)nΘ(nlog⁡n)n>2k


1
別の観点は、ワードRAMコストモデルです。このマシンは、一定時間でビットの整数を処理できます。(現在のマシンはです。)そのように、バケットによる分散ソートの1ステップは、対応する配列要素に直接アクセスすることにより時間で実行できます。このように、基数ソートは、それぞれビットの整数に対して線形です。w = 64 2 w O (1 )n w = O (log n )ww=642wO(1)nw=O(ログ⁡n)
— セバスチャン14年

9

あなたの分析には注意してください:あなたはランをソートするために何を想定します時間?あなたの数字のそれぞれは、範囲内にあるので、これはです0までのk - 1あなたの数字が上取ることができることを意味し、kの可能な値。安定したソートアルゴリズムが必要なため、たとえばカウントソートを選択できます。ソートのカウントはΘ (n + k )時間で実行されます。もしK = O (N )、線形時間でソートランをカウントします。O(n)0k−1kΘ(n+k)k=O(n)

文字列または数字のそれぞれに桁があります。あなたが言うように、あなたはそれらをdパスします。したがって、基数ソートは明らかにΘ (d (n + k ))時間で実行されます。しかし、dが定数でk = O (n )であると考えると、基数ソートは線形時間で実行されることがわかります。ddΘ(d(n+k))dk=O(n)


1
たとえば、定数dの一部のN = O (n d)に対しての範囲の整数をソートするとします。次に、それぞれ範囲O (n )のO (d )桁にすることができます。[0,N−1]N=O(nd)dO(d)O(n)
— ジョー

-2

仮定は間違っていると思います。16進数などの数値を使用して基数ソートを実行できます。したがって、各ステップで、数値の配列を16個のバケットに分割します。k=ログ2⁡(n)16


6
big-Oに関する限り、とlog 16 nの間に違いはありません。log2⁡nlog16⁡n
— リックデッカー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.