私は、線形時間で正の整数値配列をソートすることに興味があります(均一なコスト尺度を持つRAMモデル、つまり、整数は対数サイズまで持つことができますが、それらの算術演算は単位時間)。もちろん、これは比較ベースのソートアルゴリズムでは不可能であるため、「近似」ソートの計算、つまり、順列計算に興味がありますは本当に一般的にソートされていないが、のソートバージョンの「良い近似」。続編の記述が少し楽になるので、整数を降順でソートしていると仮定しますが、もちろん問題を逆に表現することもできます。
近似ソートの1つの可能な基準は次のとおりです(*):をとし、ごとに、(つまり、 「準ソート済み」リストは、上から減少関数によって制限されます。実際のソートがこれを満たしていることは簡単にわかりますは以下でなければならないため、最大ではであり、一般には以下でなければなりませんである。
たとえば、要件(*)は、以下のアルゴリズムによって実現できます(@Louisが推奨)。私の質問は次のとおりです。実際のソートが満たす(*)などの要件を課すことにより、線形時間で整数を「ほぼソート」するこのタスクに関する既存の作業はありますか?以下のアルゴリズム、またはそのバリアントには、確立された名前がありますか?
編集:アルゴリズムを修正し、説明を追加しました
アルゴリズム:
INPUT: V an array of size n containing positive integers
OUTPUT: T
N = Σ_{i<n} V[i]
Create n buckets indexed by 1..n
For i in 1..n
| Add V[i] into the bucket min(floor(N/V[i]),n)
+
For bucket 1 to bucket n
| For each element in the bucket
| | Append element to T
| +
+
このアルゴリズムは、次の理由で意図したとおりに機能します。
- 要素の場合はバケットにあるJその後、V≤N / J。
はバケットに入れられるため、
- 要素がバケット場合、またはいずれかです。
はバケットに入れられるため、またはます。最初の場合、、したがってを意味します。
用、あり、せいぜい、バケット内の要素は1〜。
ましょうおよびletバケット1..jの一つの要素の総数です。2.により、バケット()のすべての要素は、ます。したがって、バケット内のからまでのすべての要素の合計は、よりも大きくなります。この合計また、以下でより従って、したがって 私たちに与える又は。V I I ≤ J N /(J + 1 )≤ N /(I + 1 )< V K 1 jはK × N /(J + 1 )K N K × N /(J + 1 )< K ≤ NのK /(J + 1 )<
J T T [ J ] ≤ N / Jは(*)を満たします。つまり、番目の要素は、
3.我々はそれを持っている、番目の要素、バケツから来てとため、。
このアルゴリズムには線形時間がかかります。
の計算には線形時間がかかります。バケットは、挿入と反復を持つリンクリストで実装できます。ネストされたループは、要素の数だけ実行されます(つまり、回)。