C / C ++ソートアルゴリズムシリーズを実装する - マージソート(マージ)

マージソート

(マージ)マージソートアルゴリズムは、(分割統治-DivideとConque)でソーティング効率的マージの操作に基づいて分割統治を使用する典型的なアプリケーションでは、より人気の古典的なアルゴリズムの一つです。マージソートをマージするマージを伝えるために最も人気のある道路等に基づいて、マルチチャンネルをマージし、3ウェイマージに分けることができます。
図出典ます。https://www.programiz.com/dsa/merge-sort

マージソートステップ

まず第一に、私たちが知っておくべき、分割統治のアイデアが日常生活で直面する問題に適用することができ、大きな問題には、いくつかの小さな問題への最初のカットで、小さな問題は、大きな問題を解決し、それらをマージしますこれは、簡単に解決することができます。この点に関しては、それは、2つの別個のサブ配列をソートし、次にソート配列を得ることができ一緒にマージされ、二つのサブシーケンスにソート順序切断されません。
一般的に、二つのステップに要約:
ステップ1:分割。
2つのサブシーケンスにシーケンスを想定がmidあるarray中間値、その後arrraymid境界2つのサブシーケンスに分割することができるarray[0...mid],array[mid+1...end]
ステップ2:順序付けられたマージ
にこのステップの内部は、我々は合併を注文することが保証されている場合、2つの命じたシーケンスをマージする必要があります。二つの要素が最初の時間統合の際に必要な場合があり少しあいまいに出してもよいが、ここであなたがスプリットタイムに配列の2つの別々の要素になったときに、二つのサブシーケンスを注文されているため、合併最初にする前に合併がなければなりません、注文され戻って、シーケンスを取り戻すシーケンスを分割することはできません分割があります。

擬似コード感謝

//p 是起始下标  r是末尾下标(最后一个元素)
MergeSort(A, p, r)
    If p == r
        return;
    q = (p+r)/2;
    mergeSort(A, p, q)
    mergeSort(A, q+1, r)
    merge(A, p, q, r)

ここで私は正式には第一の配列の中間部を得る、2つのステップを反映していることを再帰の理解、説明上記の擬似コードに確立およびマージの理解、および2つの分解ソートの二つのサブシーケンスの各々分解がソート後、次いで、終了条件が再帰的なことであり、合成順序付けインデックスから始まるインデックスが時間の最後の要素に等しく、それが唯一の要素の配列の両方ことを示す時間に等しいです。 。
フォーカス:
スプリットソートとは何ですか?スプリットタイムを継続する唯一の要素である、2つの配列は、その後、合併に従って順序付け、自然と秩序として見ることができ、ソートされたシーケンスを返すことができるようになります。

コードの実装

合併

ここに画像を挿入説明
合併は、それをマージする方法を、マージにシーケンスを2命じたのですか?私はまた、上の図の読み取りがマージする方法を知っているべきだと考えています。
仮定i,j2つの配列の開始インデックスが
1ステップ:
ときi,j時間は、2つの配列の端部に到達しないが、(大置くべきである)誰でも小さなを置くことである、そして、インデックスをインクリメント者決定されます。

    while(i <= _mid && j <= _end){
        if(_array[i]<_array[j]){
            auxiliaryArray[k++] = _array[i++];
        }else{
            auxiliaryArray[k++] = _array[j++];
        }
    }
 

ステップ2:
2つの素子配列が存在する場合、上記の手順が、終了した後、残りの要素は、補助アレイの全てに割り当てられます

    while(i <=_mid){
        auxiliaryArray[k++] = _array[i++];
    }
    while(j <= _end){
        auxiliaryArray[k++] = _array[j++];
    }

ステップ3:
アレイの要素がアレイの補助部材を移動させます。

    for(int i = _start;i <= _end;i++){

        _array[i] = auxiliaryArray[i-_start];
    }

ファンクション不可欠

void _merge(int * _array,int _start,int _mid,int _end){
    //这里这个声明定义(new) 可以看作
    // int * auxiliaryArray = (int *)malloc(sizeof(int)*_end+);
    int * auxiliaryArray =new int[_end+1];
    int i = _start;
    int j = _mid+1;
    int k = 0;
    while(i <= _mid && j <= _end){
        if(_array[i]<_array[j]){
            auxiliaryArray[k++] = _array[i++];
        }else{
            auxiliaryArray[k++] = _array[j++];
        }
    }
    while(i <=_mid){
        auxiliaryArray[k++] = _array[i++];
    }
    while(j <= _end){
        auxiliaryArray[k++] = _array[j++];
    }

    for(int i = _start;i <= _end;i++){

        _array[i] = auxiliaryArray[i-_start];
    }
}

マージソート機能
分割ソート順序は、組み合わせ

void _mergeSort(int * _array,int _start,int _end){
    if(_start == _end){
        return ;
    }
    int _mid = (_start+_end)/2;

    _mergeSort(_array,_start,_mid);
    _mergeSort(_array,_mid+1,_end);
    _merge(_array,_start,_mid,_end);
}

分析を行います

1 6 9 4 2 7 8 64 4 5 7
1 6 9 4 2 7
1 6 9
1 6
1
6
1 6
9
1 6 9
4 2 7
4 2
4
2
2 4
7
2 4 7
1 2 4 6 7 9
8 64 4 5 7
8 64 4
8 64
8
64
8 64
4
4 8 64
5 7
5
7
5 7
4 5 7 8 64
1 2 4 4 5 6 7 7 8 9 64

以上の結果より一貫性のある実行を見ることができると私は、第1の分割合併後、言い始めました。

複雑性分析

宇宙複雑 O(N)
時間複雑 O(nlogn)

代替実現

int* merge_array(int *arr1, int n1, int* arr2, int n2)
{
    int * arr = new int[n1+n2];

    int i = 0,j = 0,k = 0;
    while(i < n1 || j < n2)
    {
        if((i < n1) && (j <n2) && (arr1[i]<arr2[j]))
        {
            arr[k++] = arr1[i];
            i++;
        }
        else if((i < n1) && (j <n2) && (arr1[i]>= arr2[j]))
        {
            arr[k++] = arr2[j];
            j++;
        }
        else if((i < n1) && (j >= n2))
        {
            for(; i < n1; i++ )
            {
                arr[k++] = arr1[i];
            }
        }
        else if((i >= n1) && (j < n2))
        {
            for(; j < n2; j++ )
            {
                arr[k++] = arr2[j];
            }
        }
    }
    for(int i = 0; i < k; i++)
    {
        arr1[i] = arr[i];
    }
    delete arr;
    return arr1;
}

int* merge_sort(int *arr, int n)
{
    if(n >= 2)
    {
        int *arr1 = &arr[n/2];
        arr = merge_sort(arr,n/2);

        if(n%2 == 0){
            arr1 = merge_sort(arr1,n/2);
            arr = merge_array(arr,n/2,arr1,n/2);
        }else{
            arr1 = merge_sort(arr1,n/2+1);
            arr = merge_array(arr,n/2,arr1,n/2+1);
        }
    }
    return arr;
}

参照

ウィキ-OIは
Mathimatics-数値アルゴリズムはマージソート
マージソートを

公開された19元の記事 ウォンの賞賛3 ビュー3811

おすすめ

転載: blog.csdn.net/weixin_42792088/article/details/103196627