C / C ++ implement sorting algorithms series - merge sort (MergeSort)

Merge sort

Merge sort (MergeSort) is based on the operation of an efficient merge sorting algorithm is (divide and conquer -Divide and Conque) of a typical application using divide and conquer, it is one of the more popular classical algorithm. Merging merge sort can be divided into three-way merge, merge multi-channel, etc. Based on the most popular Road to tell merge.
FIG. Source: https: //www.programiz.com/dsa/merge-sort

Merge sort step

First of all, we should know, divide and conquer idea can be applied to the problems encountered in daily life, a big problem is the first cut into several small problems, small problems to solve, and then merge them, a big problem It can be easily solved. This respect, it is not a sorted sequence cut into two sub-sequences, the two separate sub-sequences are sorted and then merged together can get a sorted sequence.
In general, summarized in two steps:
the Step. 1: splitting
the sequence into two subsequences, assumed midis arrayan intermediate value, then arrrayat midthe boundary can be divided into two sub-sequences array[0...mid],array[mid+1...end];
Step2: ordered merge
in this step inside, we need to merge the two ordered sequences, when the merger is guaranteed to be ordered. There may put a bit fuzzy, but here when you become two separate elements of a sequence in a split time, two sub-sequence is ordered, so the merger if the two elements required at the time of the first time consolidation of so go back and get back sequence is ordered, the merger must be before the first sequence is split can not be divided.

Pseudocode appreciated

//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)

Here understanding of the establishment and merge on the understanding of the recursion, the pseudo code above description that I have just a formal reflect two steps, first obtaining an intermediate part of the sequence, and then each of two sub-sequences of two decomposition sort after decomposition sorted, then ordered combined, where the termination condition is that the recursive index starting with the index equal to the last element of the time when it is equal to the time it shows that both the sequence of only one element .
Focus:
What is split sort? Is only one element to continue to split time, two sequences can be seen as a natural and orderly, then ordered according to the merger, will be able to return a sorted sequence.

Code

merge

Here Insert Picture Description
The merger is two ordered sequences to merge, how to merge it? I believe reading the above illustration also should know how to be merged.
Suppose i,jthe starting index of the two sequences
step 1:
when i,jthe time reaches the end of a two array are not, it is determined who is to put a small whoever (who should who put large), and then increments the index.

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

step 2:
after the above steps are finished, if there is a two element sequence, the remaining elements will be assigned to all of the auxiliary array

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

step 3:
The elements of the array are moved to an auxiliary member of the array.

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

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

Function integral part

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];
    }
}

Merge sort function
splitting sort sequence then combined

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);
}

Perform analysis

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

From the above results can be seen consistent execution and I started to say, after the first split merger.

Complexity Analysis

Space complexity O (N)
time complexity O (nlogn)

Alternative achieve

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;
}

reference

Wiki-OI
Merge the Sort Mathimatics-Numerical algorithms
merge sort

Published 19 original articles · won praise 3 · Views 3811

Guess you like

Origin blog.csdn.net/weixin_42792088/article/details/103196627