mergesor、日本人

マージソート

タイトル:

マージソート

言語:

C

著者:

フィリップ・J・アーデルスキー

日付:

1998年7月31日

使用方法:

公共エリア; の使用上の制限はありません

ポータビリティ:

どのようなCコンパイラ

キーワード:

ソート

要約:

AC関数は、任意のリードを使用して、ファイルをソート書き込み機能の比較とOであるテープマージアルゴリズムは、全ての場合において(N Nログ)します。 その機能は非再帰とリエントラントです。

Merge_sort機能は、()呼び出し元のプログラムが提供する読み取り、書き込み、および比較機能を使用して、ファイルの種類のほぼすべてのタイプになります。

  1. 可変サイズレコードのようなもの。
  2. それは関係なく、最初の注文の、nはレコードの数で比較、(N Nログ)Oをとります。 予測可能で一貫性のあるファイルをソートするための時間。 これは、一般的なタイプのために最適なパフォーマンスを知られています。
  3. レコードは読み出しまたは書き込みが行わなければならない回数は、ディスク・ファイルもO(nはn個のログを記録)。
  4. このアルゴリズムではない再帰的に繰り返されているので、何のスタックオーバーフローの問題がありません。 利用規約には、予測可能で一貫性のある、小さな積み重ね。
  5. これは、ファイルの2つのコピーを保持するために周囲に十分なディスク領域が必要です。 ファイルは、この部屋に残ってソートされています。
  6. これは、3つのレコードを保持するために少なくとも十分なメモリを必要としますが、より多くのメモリを備えている場合、それはより速く実行されます。
  7. これは、一度に4つの一時ファイルを作成するために)(TMPFILEを呼び出します。
  8. ソートされていないファイルが順次読み出され、ソートされたファイルは順次書き込まれます。 そこで彼らは、テープ、I / Oストリームまたはタイトな任意の他の配列であってもよいです。

次のように関数呼び出しは次のとおりです。

結果= merge_sort(unsorted_file、sorted_file、読み取り、書き込み、比較、
ポインタ、max_record_size、BLOCK_SIZE、PCOUNT)。

呼び出し側のプログラムは、以下のパラメータを提供する必要があります。

FILEの*のunsorted_file。

ファイルへのファイルポインタをソートします。 ファイルが読み込みのために開かれている必要があります。また、ファイルポインタはファイルの先頭に配置する必要があります。

FILEの*のsorted_file。

ソートされたファイルへのファイルポインタ。 ファイルが書き込み用に開かれている必要があります。また、ファイルポインタはファイルの先頭に配置する必要があります。

int型(*読み込み)();

一つのレコードを読み込む機能。

int型(*書き込み)();

メモの書き込み機能。

int型(*比較)();

二つのレコードを比較する関数。

void *型のポインタ。

それらが呼び出される(*読み取り)()、(*書き込み)()と(*比較)()関数に転送されるユーザ定義のポインタ。

符号なしmax_record_size;

それはメモリに読み込まれたレコード、中の最大バイト数。 それがファイル内にあるとき、これはレコードのサイズと同じである必要はありません。

unsigned long型BLOCK_SIZE。

ソートメモリが使用されない場合は、レコードの数は、メモリ、または1Lでソートされます。

符号なしlong * PCOUNT。

この情報が返されなかった場合、レコードの数(仕事のこの種の場合)、またはNULLを受け取る変数へのポインタ。

この関数は次の値を返します。

int型の結果。

コードの結果:

  • 成功のいくつかの並べ替えのための0
  • メモリへの1は十分ではありません
  • ファイル作成エラーのために2
  • エラー書き込みファイルのための3

ファイルがソートされ、バックまたは閉じ再生できないソートされます。 各ファイルは、ファイルポインタがファイルの末尾に配置され、開いたままであろう。 しかし、2つの同一のポインタファイルならば、ファイルが巻き戻されると、ソートされたレコードは、その上に書き込まれます。

(*読んで)()関数はmerge_sort(によって呼び出される)は、次のように、と(ソートされていないファイルの終わりが検出された場合を除く)と呼ばれるたびつのレコードを読まれるべきです。

N =(読み取り)(FP、バッファ、ポインタ)。

FILEの* fpは、

ファイルへのファイルポインタは、ソートやTMPFILE()を呼び出すことによって作成される一時ファイル。

void *型バッファ;

レコードを受信するためのバッファへのポインタ。 このバッファは、ほとんどmax_record_sizeバイトを保持することができます。

void *型のポインタ。

(merge_sortへの引数として渡されたコピーポインタ)。

int型のn;

レコード内のバイト数、またはゼロの試みが分離されていないファイルの終わりを超えて読み取るように構成されている場合。

この関数はゼロを返した場合、それは同じファイルのために再び呼び出されることはありません。 試みは、一時ファイルの終わりを超えて読み取るために行われることはありません。

指定された最大サイズよりも大きいレコードは、切断又は他の適切な方法で処理されるべきです。 バッファがオーバーフローすることが許可されている場合、または値によって返された場合(*読み取り)()最大レコード・サイズよりも大きい機能は破滅的に失敗します。

録音フォーマットは、それがメモリに読み込まれたとき、それを提供変更することができます。

  1. 変更は、(*書き込み)()と(*比較)()関数と互換性があり、そして
  2. それはメモリバッファ内にある間に()関数(*読み取り)によって返される値は、レコードのバイト数であることが。

メモリに読み込まれたときに、例えば、DOS / Windowsでラインターミネータの\ r \ nは、n \に変換することができます。

(*書き込み)()関数は次のように呼ばれ、それが呼び出されるたびにノートを書かなければならなかったされています。

N =(書き込み)(FP、バッファ、ポインタ)。

FILEの* fpは、

ファイルへのファイルポインタは、ソートやTMPFILE()を呼び出すことによって作成される一時ファイル。

void *型バッファ;

(*読み取り)(によってメモリに読み込まれるように、1つの音符を保持するバッファへのポインタ)。

void *型のポインタ。

(merge_sortへの引数として渡されたコピーポインタ)。

int型のn;

ゼロは成功を書き込みます。 ディスク容量不足のためにゼロ。

レコードの長さがパラメータとして渡されていないことに注意してください。 これは、レコードに、明示的または暗示的に、自分自身を含めるべきか、いくつかの()関数内で他の場所では(*書き込み)によってアクセスすることができます。

以下のように(*比較)()関数は、二つのレコードを比較するために呼び出されます。

N =(*比較)(P、Q、ポインタ)。

void *型のP;

でメモリに読み込まれるように、最初のレコードを含むバッファへのポインタ(*読み取り)()。

void *型Q;

でメモリに読み込むように、第2の音符を含むバッファへのポインタ(*読み取り)()。

void *型のポインタ。

(merge_sortへの引数として渡されたコピーポインタ)。

int型のn;

比較の結果、次のように:

  • > 0 * pをソートする* qを後になってきていた場合
  • <0 * pは* qをソートする前になっている場合
  • 0ならシーケンス* pと* qを無関係

次のような結果をソートします:

  1. ファイルから読み込んだレコードがソートされ、ブロック内の2つの一時ファイルに書き込まれます。 各ブロックは、それが一時ファイルに書き込まれる前にlinked_list_sort()を呼び出すことで(少ないレコードを含むことができ、最後のブロックを除く)引数BLOCK_SIZEで指定されたレコードの数、およびメモリ内のソートが含まれています。
  2. 一時ファイルは、その後のパスの数でブロックを組み合わせることにより、ソートされています。 各パスでは、2のブロックは、2倍の数のレコードを含むブロックにソースファイルをマージし、2つの出力ファイルに書き込まれました。 ブロックに等しいサイズまたはファイルのサイズとソートファイルで一つのファイル内のすべてのレコードを超えた場合に処理を終了します。

タイプは、以下の場合に失敗する可能性があります

  1. malloc関数の呼び出し()十分なメモリがないのでNULLを返し、または
  2. TMPFILEの呼び出し()あまりにも多くの開いているファイルがあるので、NULLを返し、または
  3. 十分なディスクスペースがあるので(*書き込み)()の呼び出しはゼロを返します。

この種の仕事であるかに関係なく、すべての割り当てられたメモリブロックの割り当てが解除され、すべての一時ファイルが閉じられ、削除されます。 このような障害場合は、ファイルへのファイルポインタがソートされていないままに、彼らがあることが起こるどこにソートされます。

彼らは関数が呼び出すリエントラントである場合にmerge_sort()関数はリエントラントです。

  • (*コンペア)()
  • fcloseを()
  • 無料()
  • malloc()
  • memcpy()
  • (*読みください)()
  • 後方()
  • TMPFILE()
  • (*ライト)()

DOS / Windowsでは、TMPFILE()は、バイナリファイルを作成します。 しかし、これは通常、DOS / Windowsは一貫変換を処理するためにソートし、ソートされたファイルは、テキストファイルであっても、問題を作成しません。

ディスク容量が非常にタイトである場合には、そのような何かが分離されていないファイルが占有するスペースを使用するように変更することができます。 ソートされていないファイル、一時ファイル、およびファイルをソートして、約2倍のソートファイルのスペースに入ることができています。 これらの変更を行うには、単にそれが読み込まれた後にソートされたファイルを削除するためのコードを入力してください。 この技術が使用されている場合、ファイルがソートされ、異なるようにソートされ、ファイルを削除する関数呼び出しとして少しエレガント可能な構造を渡す引数が正常にだけではなく、ファイルポインタの仕様ファイルを必要としていることに注意してください。

merge_sort()関数は安定していません。 すなわち、それは(*比較)()関数はゼロを返しための2つのレコードの相対位置を維持しません。 Stable_merge_sort機能は、()は、このプロパティを持っています。 しかし、追加機能は、価格を運ぶ:4バイトのレコード番号は、メモリや一時ファイルにあるものとして、各レコードに追加されます。 これは、小さなノートであれば多数で、ディスクとメモリの要件を向上させます。

SORTユーティリティ)は、(使用stable_merge_sortを示します。 これは、テキストファイルの行をソートするDOSやUNIXのフィルタです。 最大の行の長さは、各ラインの終わりにキャリッジ・リターンおよび改行を含むMAX_LINE文字ではありません。 ユーティリティは、ソートをキャンセルし、読出し線を超えるMAX_LINE文字を含む場合、エラーメッセージが表示されます。 MAX_LINE値は255に設定されていますが、ユーティリティを再コンパイルすることで変更することができます。

次のようにユーティリティが呼び出されます。

SORT <unsorted_file> MN sorted_file

一番左の列は数ゼロであるNまでの列Mの数、包括的含むこの種。 Nを省略すると、ソートM列とその右にあるすべての列を含みます。 MとNの両方が省略された場合、すべての列がソートに使用されます。

それが右端にヌルで埋めたかのようにN + 1列未満含む行がソートされます。

符号なしバイトとして考える彼らのASCIIコード、文字によってランク付け。

このパッケージは、他のパッケージのために呼び出します。

テキスト形式のソースコード:

No Comments

    Leave a reply