マージソートは、マージ操作に基づく効率的なソートアルゴリズムです。このアルゴリズムは、分割統治法(Divide and Conquer)を採用した非常に典型的な例です。
まず、2つの整列済みの数列をどのようにマージするかを考えます。これは非常に簡単で、2つの数列の最初の数を比較し、小さい方を先に取り出し、取り出したら対応する数列からその数を削除します。その後、再び比較を行います。もしどちらかの数列が空になったら、もう一方の数列のデータを順に取り出すだけです。
整列済みの数列をマージする効率は比較的高く、O(n) に達することがわかります。
上記の整列済み数列のマージ問題を解決したら、次にマージソートを見てみましょう。その基本的な考え方は、配列をA、Bの2つのグループに分け、この2つのグループ内のデータがそれぞれ整列済みであれば、その2つのグループのデータを簡単にソートできるというものです。では、どうやってこの2つのグループ内のデータを整列させるのでしょうか?
A、Bグループをそれぞれさらに2つのグループに分けることができます。同様に繰り返し、分割された小グループが1つのデータだけになったとき、その小グループ内はすでに整列済みと見なせます。その後、隣接する2つの小グループをマージすればよいのです。このように、まず数列を再帰的に分割し、次に数列をマージすることでマージソートが完成します。
マージソートの効率は比較的高く、数列の長さを N とすると、数列を小さな数列に分割するには合計 logN ステップかかります。各ステップは整列済みの数列をマージするプロセスであり、時間計算量は O(N) と表せるため、全体で O(N*logN) になります。マージソートは毎回隣接するデータに対して操作を行うため、O(N*logN) のいくつかのソート方法(クイックソート、マージソート、シェルソート、ヒープソート)の中でも効率が比較的高いものとなっています。
私のコンピューター上で、バブルソート、直接挿入ソート、マージソート、およびシステムの qsort() を直接使用した場合を比較しました(いずれも Release バージョンです)。20000 個のランダムデータに対してテスト:

50000 個のランダムデータに対してテスト:

さらに 200000 個のランダムデータに対してテスト:

注:一部の書籍では、mergearray() で整列済みの数列をマージする際に一時配列を割り当てますが、new 操作が多すぎると非常に時間がかかります。そのため、少し変更を加えました。MergeSort() 内で一時配列を1つだけ new し、以降の操作はすべてこの1つの一時配列を共用します。
作者:MoreWindows
原文:https://blog.csdn.net/morewindows/article/details/6678165