Lila25mila
Lila25milaMarch 6, 2019, 3:49 a.m.

Merge Sort Algorithm

Merge sort is a kind of divide and conquer algorithm in computer programming. It is one of the most popular sorting algorithms and a great way to build confidence in building recursive algorithms.


Divide and Conquer Strategy

Using the Divide and Conquer technique, we divide the problem into subtasks. When the solution for each subproblem is ready, we "combine" the results from the subproblems to solve the main problem.

Suppose we needed to sort an array A. The subtask would be to sort a subsection of this array starting at index p and ending at index r, denoted as A[p..r].

Share

If q is an intermediate point between p and r, then we can split the subarray A[p..r] into two arrays A[p..q] and A[q + 1, r].

Own it

In the conquest step, we are trying to sort both subarrays A[p..q] and A[q + 1, r]. If we haven't reached the base case yet, we separate both of these subarrays again and try to sort them.

Combine

When the conqueror step reaches the base step and we get two sorted subarrays A[p..q] and A[q + 1, r] for array A[p..r], we combine the results, creating a sorted array A[p. .r] of two sorted subarrays A[p..q] and A[q + 1, r]

Merge sort algorithm

The MergeSort function repeatedly divides the array into two halves until we reach a stage where we try to MergeSort on a subarray of size 1, i.e. p == r.
After that, the merge function comes into play, which merges the sorted arrays into larger arrays until the entire array has been merged.

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)

To sort the entire array, we need to call MergeSort(A, 0, length(A)-1).
As shown in the figure below, the merge sort algorithm recursively divides the array into two halves until we reach the base case of an array with 1 element. The merge function then selects the sorted subarrays and merges them to gradually sort the entire array.

Merge sort merge step

Each recursive algorithm depends on a base case and the ability to combine results from base cases. merge sort is no exception. The most important part of the algorithm is the "merge" step.

The merge step is a solution to the simple problem of combining two sorted lists (arrays) to create one large sorted list (array).

The algorithm maintains three pointers, one for each of the two arrays and one for maintaining the current index of the final sorted array.

Достигли ли мы конца какого-либо из массивов?
    Нет:
        Сравните текущие элементы обоих массивов
        Скопируйте меньший элемент в отсортированный массив
        Переместить указатель на элемент, содержащий меньший элемент
    Да:
        Скопировать все оставшиеся элементы непустого массива

Since there are no more elements left in the second array and we know that both arrays were sorted at startup, we can copy the remaining elements from the first array directly

Writing code for the merge algorithm

A notable difference between the merge step we described above and the one we use for merge sort is that the merge function is only performed on consecutive subarrays.

That's why we only need the array, the first position, the last index of the first subarray (we can compute the first index of the second subarray), and the last index of the second subarray.

Our task is to combine two subarrays A[p..q] and A[q + 1..r] to create a sorted array A[p..r]. Thus, the input data for the function A, p, q and r

The merge function works like this:

  1. Create copies of the subarrays L ← A [p..q] and M ← A [q + 1..r].
  2. Create three pointers i, j and k
  3. i maintains the current index L starting from 1
  4. j maintains the current index of M, starting at 1
  5. k maintains the current index of A [p..q] starting from p
  6. Until we reach the end of L or M, choose the larger of the elements from L and M and place them in the correct position in A[p..q]
  7. When we run out of elements in L or M, take the remaining elements and put in A [p..q]

In code it will look like this:

void merge(int A[], int p, int q, int r)
{
    /* Создание L ← A[p..q] и M ← A[q+1..r] */
    int n1 = q - p + 1;
    int n2 =  r - q;

    int L[n1], M[n2];

    for (i = 0; i < n1; i++)
        L[i] = A[p + i];
    for (j = 0; j < n2; j++)
        M[j] = A[q + 1 + j];

    /* Поддержание текущего индекса вложенных массивов и основного массива */
    int i, j, k;
    i = 0; 
    j = 0; 
    k = p; 


    /* Пока мы не достигнем конца L или M, выбираем большее из элементов L и M и помещаем их в правильное положение в точке A [p..r]*/
    while (i < n1 && j < n2)
    {
        if (L[i] <= M[j])
        {
            arr[k] = L[i];
            i++;
        }
        else
        {
            arr[k] = M[j];
            j++;
        }
        k++;
    }

    /* Когда у нас кончаются элементы в L или M, возьмите оставшиеся элементы и поместите в A [p..r]*/
    while (i < n1)
    {
        A[k] = L[i];
        i++;
        k++;
    }

    while (j < n2)
    {
        A[k] = M[j];
        j++;
        k++;
    }
}
Merge function step by step

There is a lot of action in this function, so let's take a look at an example to see how it would work.

The array A[0..8] contains two sorted subarrays A[1..5] and A[6..7]. Let's see how the merge function will merge two arrays.

void merge(int A[], int p = 1, int q = 4, int 6)
{
Step 1. Create duplicate copies of subarrays for sorting
 /* Создание L ← A[p..q] и M ← A[q+1..r] */
    n1 = 4 - 1 + 1 = 4;
    n2 =  6 - 4 = 2;

    int L[4], M[2];

    for (i = 0; i < 4; i++)
        L[i] = A[p + i];
    /* L[0,1,2,3] = A[1,2,3,4] = [1,5,10,12] */

    for (j = 0; j < 2; j++)
        M[j] = A[q + 1 + j];
    /* M[0,1,2,3] = A[5,6] = [6,9]

Step 2: Maintaining the current index of the sub-arrays and the main array
 int i, j, k;
    i = 0; 
    j = 0; 
    k = p; 

Step 3: Until we reach the end of L or M, the larger one among the L and M elements is selected and placed in the correct position at point A [p..r]
 while (i < n1 && j < n2) { 
        if (L[i] <= M[j]) { 
            A[k] = L[i]; i++; 
        } 
        else { 
            A[k] = M[j]; 
            j++; 
        } 
        k++; 
    }

Step 4: When the elements in L or M run out, the remaining elements must be placed in A [p..r]
/* Мы вышли из предыдущего цикла, потому что j <n2 не выполняется */  
    while (i < n1)
    {
        A[k] = L[i];
        i++;
        k++;
    }

/* Мы вышли из предыдущего цикла, потому что i <n1 не выполняется */  

    while (j < n2)
    {
        A[k] = M[j];
        j++;
        k++;
    }
}

This step would be necessary if the size M was larger than L.
At the end of the merge function, the subarray A[p..r] is sorted.

We recommend hosting TIMEWEB
We recommend hosting TIMEWEB
Stable hosting, on which the social network EVILEG is located. For projects on Django we recommend VDS hosting.

Do you like it? Share on social networks!

Comments

Only authorized users can post comments.
Please, Log in or Sign up
e
  • ehot
  • April 1, 2024, 12:29 a.m.

C++ - Тест 003. Условия и циклы

  • Result:78points,
  • Rating points2
B

C++ - Test 002. Constants

  • Result:16points,
  • Rating points-10
B

C++ - Test 001. The first program and data types

  • Result:46points,
  • Rating points-6
Last comments
k
kmssrFeb. 9, 2024, 5:43 a.m.
Qt Linux - Lesson 001. Autorun Qt application under Linux как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
Qt WinAPI - Lesson 007. Working with ICMP Ping in Qt Без строки #include <QRegularExpressionValidator> в заголовочном файле не работает валидатор.
EVA
EVADec. 25, 2023, 9:30 p.m.
Boost - static linking in CMake project under Windows Ошибка LNK1104 часто возникает, когда компоновщик не может найти или открыть файл библиотеки. В вашем случае, это файл libboost_locale-vc142-mt-gd-x64-1_74.lib из библиотеки Boost для C+…
J
JonnyJoDec. 25, 2023, 7:38 p.m.
Boost - static linking in CMake project under Windows Сделал всё по-как у вас, но выдаёт ошибку [build] LINK : fatal error LNK1104: не удается открыть файл "libboost_locale-vc142-mt-gd-x64-1_74.lib" Хоть убей, не могу понять в чём дел…
G
GvozdikDec. 19, 2023, 8:01 a.m.
Qt/C++ - Lesson 056. Connecting the Boost library in Qt for MinGW and MSVC compilers Для решения твой проблемы добавь в файл .pro строчку "LIBS += -lws2_32" она решит проблему , лично мне помогло.
Now discuss on the forum
a
a_vlasovApril 14, 2024, 4:41 p.m.
Мобильное приложение на C++Qt и бэкенд к нему на Django Rest Framework Евгений, добрый день! Такой вопрос. Верно ли следующее утверждение: Любое Android-приложение, написанное на Java/Kotlin чисто теоретически (пусть и с большими трудностями) можно написать и на C+…
Павел Дорофеев
Павел ДорофеевApril 14, 2024, 12:35 p.m.
QTableWidget с 2 заголовками Вот тут есть кастомный QTableView с многорядностью проект поддерживается, обращайтесь
f
fastrexApril 4, 2024, 2:47 p.m.
Вернуть старое поведение QComboBox, не менять индекс при resetModel Добрый день! У нас много проектов в которых используется QComboBox, в версии 5.5.1, когда модель испускает сигнал resetModel, currentIndex не менялся. В версии 5.15 при resetModel происходит try…
AC
Alexandru CodreanuJan. 19, 2024, 10:57 p.m.
QML Обнулить значения SpinBox Доброго времени суток, не могу разобраться с обнулением значение SpinBox находящего в делегате. import QtQuickimport QtQuick.ControlsWindow { width: 640 height: 480 visible: tr…

Follow us in social networks