Eight sorting algorithms (2) ----- merge sort

1. Algorithmic thinking

First, the n records of the initial sequence are regarded as n ordered subsequences, and the length of each subsequence is 1, and then the two are merged to obtain n/2 and the whole length is 2 (when n is an odd number, the last one An ordered subsequence of a sequence of length 1). On this basis, the ordered subsequences of length 2 are merged in pairs to obtain several ordered subsequences of length 4. And so on, until an ordered sequence of length n is obtained.

2. Algorithm implementation

1. Recursive implementation

#include<stdio.h>
#include<stdlib.h>
void Merg(int arry[],int temp[],int left,int right,int mid)
{
    int i = left,j = right,k = mid + 1;
    while(i < mid + 1 && k < right + 1)
    {
        if(arry[i] < arry[j])
        {
            temp[k++] = arry[i++];
        }
        else
            temp[k++] = arry[j++];
    }
    while(i < mid + 1)
    {
        temp[k++] = arry[i++];
    }
    while(j < right + 1)
    {
        temp[k++] = arry[j+1];
    }
    for(i = left;i<right;i++)
    {
       arry[i] = temp[i];
    }   
}
void Mergsort(int arry[],int temp[],int left,int right)
{
    int mid;
    if(left < right)
    {
        Mergsort(arry,temp,left,mid);
        Mergsort(arry,temp,mid+1,right);
        Merg(arry,temp,left,right,mid);
    }
}

The execution order of the entire algorithm can be expressed as 1--20 as shown in the following figure with the help of the following figure


The array represented by each Merge is as follows


2. Non-recursive implementation

 
 
#incldue <iostream>
using namespace std;
/*Merge the array of length at the beginning of a and the array of length at the beginning of b into an array of length n*/
void Merge(int *data,int a,int b,int length,int n)
{
    int size;
    if(b+length-1 >= n-1)
    {
        size = n - b;
    }
    else
    {
        size = length;
    }
    int* temp = new int[length+size];
    int i=0,j=0;
    while(i<=length-1 && j<= size - 1)
    {
        if(data[a+i] <= data[b+i])
        {
            temp[i+j] = data[a+i];
            i++;
        }
        else
        {
            temp[i+j] = data[a+i];
            i++;
        }
    }
    if(j == size)
    {
        memcpy(temp+i+j,data+b+j,(size -j) * sizeof(int))
    }
    else if(i == length)
    {
        memcpy(temp + i + j,data + b + j,(right - j)*sizeof(int));
    }
    memcpy(data + a,temp,(right + length)*sizeof(int));
    delete[] temp;
}
void Mergesort(int* data,int n)
{
    int step = 1;
    while(step < n)
    {
        for(int i=0;i<n-step-1;i+=2*step)
        {
            Merge(data,i,i+step,step,n);
        }
        step*=2;
    }
}

3. Time complexity analysis

From the entire sorting process, it can be seen that the time of merge sorting is mainly spent on dividing the time series, sorting the two subsequences, and merging. The time to divide the sequence is constant and can be ignored.

The time of the merge process grows linearly with the length n of the record sequence. Therefore, to merge and sort a sequence of records with a length of n, the operation of calling a merge sort is to call the Merge algorithm of n/2h to round down, and the sequence of records adjacent to arry and the ordered segment of length h is processed. Two-by-two merging, adjacent ordered segments with a length of 2h are obtained, and stored in arry, the time complexity of which is O(N). The entire merge sort requires logn (base 2) two-way merges, so the total time complexity of merge sort is O(nlogn).

4. Stability

It can be seen from the algorithm that the merge starts from the left half every time, and when the keywords of the left half and the right half are equal, the left half takes precedence, so the entire sorting algorithm is stable.


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325163562&siteId=291194637