目次
1. はじめに
コンピューター サイエンスの並べ替えアルゴリズムは、データを昇順または降順に並べるために使用されます。使用可能な個別のプロパティを持つ複数の並べ替えアルゴリズムがあります。マージ ソートは、配列をソートできる C++ のメソッドの 1 つです。
2. C++ におけるマージ ソートとは何ですか
マージ ソートは、配列の要素を配置できる分割統治手法を使用します。 C++ の要素のリストを並べ替えることもできます。入力を 2 つの半分に分割し、それぞれを個別に並べ替えて、正しい順序でマージします。
3. 分割統治アプローチ
ソート アルゴリズムは、分割統治戦略を適用します。これには、入力配列を小さなサブ配列に分割し、それらを個別に解決し、結果をマージしてソートされた出力を生成します。マージ ソートの場合、配列は各半分に 1 つの要素だけが残るまで再帰的に 2 つの半分に分割されます。
4. マージソートアルゴリズム
マージ ソート アルゴリズムは、分割とマージという 2 つの主要なステップで構成されます。手順は次のとおりです。
4.1 除算
マージソートアルゴリズムは、配列内の要素をソートするための分割統治戦略に従います。
- アルゴリズムの最初のステップでは、配列要素をチェックします。要素が 1 つ含まれている場合は、すでにソートされているとみなされ、アルゴリズムは変更せずに同じ配列を返します。
- 配列に複数の要素が含まれている場合、アルゴリズムは配列を 2 つの半分 (左半分と右半分) に分割します。
- 次に、マージ ソート アルゴリズムが配列の左半分と右半分に再帰的に適用され、効率的に小さいサブ配列に分割され、個別にソートされます。
- この再帰的なプロセスは、サブ配列にそれぞれ要素が 1 つだけ含まれるまで (ステップ 1 のように) 継続され、その時点で要素をマージして、最終的なソートされた出力配列を生成できます。
4.2 マージ
次に、配列をマージする手順を見てみましょう。
- マージ ソート アルゴリズムの最初のステップでは、空の配列を作成します。
- 次に、アルゴリズムは入力配列の左半分と右半分の最初の要素を比較します。
- 2 つの要素のうち小さい方が新しい配列に追加され、入力配列のそれぞれの半分から削除されます。
- 次に、半分のうちの 1 つが空になるまで、ステップ 2 ~ 3 が繰り返されます。
- 次に、空ではない半分に残っている要素が新しい配列に追加されます。
- 結果の配列は完全にソートされ、マージソートアルゴリズムの最終出力を表します。
5. C++でのマージソートの実装
C++ でマージ ソートを実装するには、2 つの異なる方法に従います。両方のメソッドの時間計算量は同等ですが、一時サブ配列の使用法が異なります。
C++ のマージ ソートの最初の方法では 2 つの一時サブ配列が使用されますが、2 番目の方法では 1 つだけが使用されます。最初のメソッドの 2 つの一時サブ配列の合計サイズは、2 番目のメソッドの元の配列のサイズと等しいため、空間の複雑さは一定のままであることに注意してください。
方法 1 – 2 つの一時サブ配列を使用する
以下は、2 つの一時サブ配列を使用する方法 1 を使用した C++ でのマージ ソートのプログラム例です。
#include名前空間 std を使用する ;
空所 マージ ( 整数 到着しました [ 】 、 整数 私 、 整数 メートル 、 整数 r )
{
整数 n1 = メートル - 私 + 1 ;
整数 n2 = r - メートル ;
整数 L [ n1 】 、 R [ n2 】 ;
ために ( 整数 私 = 0 ; 私 < n1 ; 私 ++ )
L [ 私 】 = 到着しました [ 私 + 私 】 ;
ために ( 整数 j = 0 ; j < n2 ; j ++ )
R [ j 】 = 到着しました [ メートル + 1 + j 】 ;
整数 私 = 0 、 j = 0 、 k = 私 ;
その間 ( 私 < n1 && j < n2 ) {
もしも ( L [ 私 】 <= R [ j 】 ) {
到着しました [ k 】 = L [ 私 】 ;
私 ++;
}
それ以外 {
到着しました [ k 】 = R [ j 】 ;
j ++;
}
k ++;
}
その間 ( 私 < n1 ) {
到着しました [ k 】 = L [ 私 】 ;
私 ++;
k ++;
}
その間 ( j < n2 ) {
到着しました [ k 】 = R [ j 】 ;
j ++;
k ++;
}
}
空所 マージソート ( 整数 到着しました [ 】 、 整数 私 、 整数 r )
{
もしも ( 私 < r ) {
整数 メートル = 私 + ( r - 私 ) / 2 ;
マージソート ( 到着しました 、 私 、 メートル ) ;
マージソート ( 到着しました 、 メートル + 1 、 r ) ;
マージ ( 到着しました 、 私 、 メートル 、 r ) ;
}
}
整数 主要 ( )
{
整数 到着しました [ 】 = { 12 、 十一 、 13 、 5 、 6 、 7 } ;
整数 arr_size = のサイズ ( 到着しました ) / のサイズ ( 到着しました [ 0 】 ) ;
コート << 「与えられた配列は \n 」 ;
ために ( 整数 私 = 0 ; 私 < arr_size ; 私 ++ )
コート << 到着しました [ 私 】 << 「」 ;
マージソート ( 到着しました 、 0 、 arr_size - 1 ) ;
コート << 」 \n ソートされた配列は \n 」 ;
ために ( 整数 私 = 0 ; 私 < arr_size ; 私 ++ )
コート << 到着しました [ 私 】 << 「」 ;
戻る 0 ;
}
このプログラムでは、merge 関数は 3 つの引数 arr、l、r を受け取り、これらはソートされる配列を表し、マージする必要がある部分配列のインデックスを示します。この関数は、まずマージする 2 つの部分配列のサイズを検出し、次に 2 つの一時的な部分配列 L および R を作成して、これらの部分配列の要素を格納します。次に、L と R の要素を比較し、それらを という名前の元の配列にマージします。 到着しました 昇順で。
分割統治手法は、mergeSort 関数によって使用され、部分配列内に 1 つの要素だけが残されるまで、配列を再帰的に 2 つの半分に分割します。次に、2 つの部分配列をソートされた部分配列にマージします。この関数は、配列全体をソートしない限り、サブ配列のマージを続けます。
main 関数では、6 つの要素を持つ配列 arr を定義し、mergeSort 関数を呼び出して並べ替えます。コードの最後で、ソートされた配列が出力されます。
方法 2 – 1 つの一時サブアレイを使用する
以下は、単一の一時サブ配列を使用する方法 2 を使用した、C++ でのマージ ソートのプログラム例です。
#include名前空間 std を使用する ;
空所 マージ ( 整数 到着しました [ 】 、 整数 私 、 整数 メートル 、 整数 r )
{
整数 私 、 j 、 k ;
整数 n1 = メートル - 私 + 1 ;
整数 n2 = r - メートル ;
// 一時的なサブ配列を作成します
整数 L [ n1 】 、 R [ n2 】 ;
// データを部分配列にコピーします
ために ( 私 = 0 ; 私 < n1 ; 私 ++ )
L [ 私 】 = 到着しました [ 私 + 私 】 ;
ために ( j = 0 ; j < n2 ; j ++ )
R [ j 】 = 到着しました [ メートル + 1 + j 】 ;
// 一時的なサブ配列をマージして元の配列に戻します
私 = 0 ;
j = 0 ;
k = 私 ;
その間 ( 私 < n1 && j < n2 ) {
もしも ( L [ 私 】 <= R [ j 】 ) {
到着しました [ k 】 = L [ 私 】 ;
私 ++;
}
それ以外 {
到着しました [ k 】 = R [ j 】 ;
j ++;
}
k ++;
}
// L[] の残りの要素をコピーします
その間 ( 私 < n1 ) {
到着しました [ k 】 = L [ 私 】 ;
私 ++;
k ++;
}
// R[] の残りの要素をコピーします
その間 ( j < n2 ) {
到着しました [ k 】 = R [ j 】 ;
j ++;
k ++;
}
}
空所 マージソート ( 整数 到着しました [ 】 、 整数 私 、 整数 r )
{
もしも ( 私 < r ) {
整数 メートル = 私 + ( r - 私 ) / 2 ;
// 左半分と右半分を再帰的に並べ替えます
マージソート ( 到着しました 、 私 、 メートル ) ;
マージソート ( 到着しました 、 メートル + 1 、 r ) ;
// ソートされた 2 つの部分をマージします
マージ ( 到着しました 、 私 、 メートル 、 r ) ;
}
}
整数 主要 ( )
{
整数 到着しました [ 】 = { 12 、 十一 、 13 、 5 、 6 、 7 } ;
整数 arr_size = のサイズ ( 到着しました ) / のサイズ ( 到着しました [ 0 】 ) ;
コート << 「与えられた配列は \n 」 ;
ために ( 整数 私 = 0 ; 私 < arr_size ; 私 ++ )
コート << 到着しました [ 私 】 << 「」 ;
マージソート ( 到着しました 、 0 、 arr_size - 1 ) ;
コート << 」 \n ソートされた配列は \n 」 ;
ために ( 整数 私 = 0 ; 私 < arr_size ; 私 ++ )
コート << 到着しました [ 私 】 << 「」 ;
戻る 0 ;
}
このプログラムは前のプログラムと似ていますが、2 つの一時サブ配列 L および R を使用する代わりに、1 つの一時サブ配列 temp を使用します。マージ関数は以前と同じように機能しますが、データを L と R にコピーする代わりに、temp にコピーします。次に、一時配列要素をマージして元の 到着しました これが元の配列です。
mergeSort 関数は、一時部分配列を格納するために L と R の代わりに temp を使用することを除いて、前と同じです。
main 関数では、6 つの要素を持つ配列 arr を定義し、mergeSort 関数を呼び出して並べ替えます。コードの実行は、ソートされた配列を画面に表示することで終了します。
結論
マージ ソートは配列要素をソートするアルゴリズムであり、分割統治手法を使用して要素間の比較を行います。 C++ のマージ ソートの時間計算量は O(n log n) であり、大きな配列のソートに特に効果的です。マージされたサブ配列を保存するには追加のメモリが必要ですが、その安定性により、並べ替えによく使用されます。