2010-11-22 8 views
5

2n個のRAMを使用してn^2要素をソートする方法を教えてください。 考えられるアプローチの1つは、サイズnのn個のアレイにそれぞれ分割することです。そして、n要素内でマージソートを行い、最後にn個の配列にサイズnのヒープを保持します。しかし、これは、1つの要素が配置されるたびに、私はディスクの読み込みを行い、n要素が完成するたびにディスク書き込みを行うことを意味します。 より良い提案はありますか?おかげさまで 2n RAMでn^2要素をソートする方法

+1

「O(log(n))RAMでn個の要素をソートする方法」という別の言い方をしています。 – erikkallen

+5

それはO(sqrt(n))ではいけませんか? –

+2

Knuthは、この問題に関する全章をComputer Programming * Volume 3で手掛けています。 –

答えて

0

これはできません。要素のためだけにn^2のメモリが必要です。

この明らかなメモリ消費を考慮しない場合は、ヒープソートなどのインプレースソートアルゴリズムの1つをお勧めします。 O(1)余分なスペースが必要です。

外部ストレージがカウントされず、内部ストレージのみがカウントされる外部ソートアルゴリズムを探している場合は、ボトムアップのmergesortを使用することをおすすめします。あなたはこれを、あなたが望むほどの量の内部メモリを消費するようにすることができます。約2nのメモリを消費し、部分的にソートされた各セットから常にn/2個の要素を読み込み、それらをn個の要素の別の配列にマージします。結果をディスクに書き戻します(できるだけ別のファイルに書き込むことをお勧めします)。

+2

最初にすべてのデータをロードする必要はありません。 –

+0

しかしあなたはどこかにそれらを保存しなければなりません。ディスク上でさえ、彼らは依然としてO(n^2)バイトの記憶域を使います。 –

+0

OP、彼はO(n) 'RAM'を持っていて、O(n^2)のスペースがないと言ったのですか?問題を解決するための彼の提案はまさに彼が外部空間を持っていると言う。 –

2

キャッシュ忘却型優先度キューの実装がある場合は、ディスクとメモリ階層の各レベルでメモリ転送の観点から最適な実行時間を達成するために使用できます(http://courses.csail.mit.edu/6.897/spring05/lec/lec23.pdf参照)。

それ以外の場合は、単純なコードを最初から書きたい場合は、mergesortのディスクベースの実装がうまくいくはずです。基本的に、 "左"と "右"の半分を最初に再帰的にソートし、2nメモリを使ってそれらをマージして、再帰的にソートされたサブアレイをディスクからバッファすることによって、配列の範囲をソートできます。単純な実装では、これは適切ではないため、ディスク上にアレイの2つのコピーを保管して前後にシャトルする必要があります。

+0

n^2要素がある場合、2nメモリで最後のマージはどうしますか? –

+1

ディスクから番号をバッファリングしています。ディスク上にマージしたい2つのリストがあるので、それぞれからnをロードしてマージし、マージの結果をディスクに書き込みます。バッファの1つが使い果たされると、バッファがリロードされます。技術的には、ディスクに書き込むときにもバッファリングする必要があります。そのため、出力バッファにもO(n)メモリを確保する必要があります。 – jonderry

関連する問題