データ構造:一般的な並べ替えアルゴリズム(8):マージ並べ替え(C ++実装)

データ構造:一般的な並べ替えアルゴリズム(8):マージ並べ替え

(1)基本的な考え方:

マージ(マージ)ソート方法は、2つ(またはそれ以上)の順序付きリストを新しい順序付きリストにマージすることです。つまり、ソートするシーケンスをいくつかのサブシーケンスに分割し、各サブシーケンスを順序付けます。次に、順序付けられたサブシーケンスが全体的な順序付けられたシーケンスにマージされます。マージソートの2番目のステップでは、2つの順序付けられた配列をソートするルールは非常に単純です。同時に、2つの配列の最初の位置のサイズを比較し、小さい方を空の配列に入れてから、その位置を空の配列に入れます。ポインタが1つ後ろに移動してから、別の配列の前の位置との比較を続けます。いずれかのアレイが最初にスタックからポップアウトされるまで、他のアレイのすべての要素が新しいアレイに追加されます。

マージソートとクイックソートの効果は同じです。クイックソート:最初にアレイを2つのサブアレイに大まかにソートし、次に2つのサブアレイを再帰的かつ大まかに分割して、サブアレイに要素が1つだけになると、自然にソートされます。これは、最初に並べ替え、次に再帰的に並べ替えることとして要約できます。マージ並べ替え:何があっても、配列は2つのサブ配列に分割され、配列に要素が1つだけになるまで、配列は2つのサブ配列に再帰的に分割され、並べ替えが開始されます。 2つの配列を順番に並べ替え、再帰的な戻り値に従って2つの配列を順番に並べ替えます。最後に、配列全体を並べ替えることができます。

(2)例

例:a [15] = {3、44、38、5、47、15、36、26、27、2、46、4、19、50、48}マージソートによるソート

img

2.1反復法

①スペースを申請して、ソートされた2つのシーケンスの合計サイズにします。このスペースは、マージされたシーケンスを格納するために使用されます。

②2つのポインタを設定します。初期位置はそれぞれ2つのソートされたシーケンスの開始位置です。

③2つのポインタが指す要素を比較し、比較的小さい要素を選択してマージスペースに配置し、ポインタを次の位置に移動します

④ポインタがシーケンスの最後に到達するまで、手順③を繰り返します。

⑤別のシーケンスの残りの要素をすべて、マージされたシーケンスの最後に直接コピーします

2.2再帰

①シーケンス内の隣接する2つの番号ごとにマージして、floor(n / 2)シーケンスを形成します。ソート後、各シーケンスには2つの要素が含まれます。

②上記のシーケンスを再度マージしてfloor(n / 4)シーケンスを形成し、各シーケンスには4つの要素が含まれます

③すべての要素がソートされるまで手順②を繰り返します

コード例:

// 归并排序(递归法)
template<typename T>
void merge_sort_recursive(T arr[], T reg[], int start, int end) {
    if (start >= end)
        return;
    int len = end - start, mid = (len >> 1) + start;
    int start1 = start, end1 = mid;
    int start2 = mid + 1, end2 = end;
    merge_sort_recursive(arr, reg, start1, end1);
    merge_sort_recursive(arr, reg, start2, end2);
    int k = start;
    while (start1 <= end1 && start2 <= end2)
        reg[k++] = arr[start1] < arr[start2] ? arr[start1++] : arr[start2++];
    while (start1 <= end1)
        reg[k++] = arr[start1++];
    while (start2 <= end2)
        reg[k++] = arr[start2++];
    for (k = start; k <= end; k++)
        arr[k] = reg[k];
}

// merge_sort
template<typename T>
void merge_sort(T arr[], const int len) {
    T reg[15];
    merge_sort_recursive(arr, reg, 0, len - 1);
}

3.要約:

時間の複雑さ:マージソートは、主に分割と並べ替え順序付き配列に分けられます。分割操作の時間の複雑さはlognであり、ソートの複雑さはnであるため、マージソートの時間の複雑さはO(nlogn)マージソートです。のスペースの複雑さは、一時的な配列と再帰中にスタックにプッシュされるデータによって占有されるスペースです:n + lognなので、スペースの複雑さはO(n)です。

おすすめ

転載: blog.csdn.net/qq_43801020/article/details/108219886