Вам бонус- начислено 1 монета за дневную активность. Сейчас у вас 1 монета

Сортировка слиянием

Лекция



Привет, сегодня поговорим про сортировка слиянием, обещаю рассказать все что знаю. Для того чтобы лучше понимать что такое сортировка слиянием , настоятельно рекомендую прочитать все из категории Алгоритмы и теория алгоритмов.

Алгоритм сортировки слиянием был предложен праотцом современных компьютеров – Джоном фон Нейманом. Сам метод является устойчивым, т. е. он не меняет одинаковые по значению элементы в списке.

В основе сортировки слиянием лежит принцип «разделяй и властвуй». Список разделяется на равные или практически равные части, каждая из которых сортируется отдельно. После чего уже упорядоченные части сливаются воедино. Несколько детально этот процесс можно расписать так:

  1. массив рекурсивно разбивается пополам, и каждая из половин делиться до тех пор, пока размер очередного подмассива не станет равным единице;
  2. далее выполняется операция алгоритма, называемая слиянием. Два единичных массива сливаются в общий результирующий массив, при этом из каждого выбирается меньший элемент (сортировка по возрастанию) и записывается в свободную левую ячейку результирующего массива. После чего из двух результирующих массивов собирается третий общий отсортированный массив, и так далее. В случае если один из массивов закончиться, элементы другого дописываются в собираемый массив;
  3. в конце операции слияния, элементы перезаписываются из результирующего массива в исходный.

Основная подпрограмма MergeSort рекурсивно разбивает и сортирует массив, а Merge отвечает за его слияние. Так можно записать псевдокод основной подпрограммы:

 

1
2
3
4
5
6
7
8
9
10
11
Подпрограмма MergeSort(A, first, last)
{
//A – массив
//first, last – номера первого и последнего элементов соответственно
Если first<last то
{
Вызов MergeSort(A, first, (first+last)/2) //сортировка левой части
Вызов MergeSort(A, (first+last)/2+1, last) //сортировка правой части
Вызов Merge(A, first, last) //слияние двух частей
}
}

 

Эта подпрограмма выполняется только в том случае, если номер первого элемента меньше номера последнего. Как уже говорилось, из подпрограммы MergeSort вызывается подпрограмма Merge, которая выполняет операцию слияния. Перейдем к рассмотрению последней.

Работа Merge заключается в образовании упорядоченного результирующего массива путем слияния двух также отсортированных массивов меньших размеров. Вот псевдокод этой подпрограммы:

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Подпрограмма Merge(A, first, last)
{
//start, final – номера первых элементов левой и правой частей
//mas – массив, middle - хранит номер среднего элемента
middle=(first+last)/2 //вычисление среднего элемента
start=first //начало левой части
final=middle+1 //начало правой части
Цикл j=first до last выполнять //выполнять от начала до конца
Если ((start<=middle) и ((final>last) или (A[start]<A[final]))) то
{
mas[j]=A[start]
увеличить start на 1
}
Иначе
{
mas[j]=A[final]
увеличить final на 1
}
Цикл j=first до last выполнять //возвращение результата в список
A[j]=mas[j]
}

 

Разберем алгоритм сортировки слиянием на следующем примере. Об этом говорит сайт https://intellect.icu . Имеется неупорядоченная последовательность чисел: 2, 6, 7, 1, 3, 5, 0, 4. После разбивки данной последовательности на единичные массивы, процесс сортирующего слияния (по возрастанию) будет выглядеть так:

 

сортировка слиянием - схема" src="/th/25/blogs/id4383/0_690165ac0c5aef7fc2e87577f33ce0e6.png" alt="Сортировка слиянием - схема" width="362" height="291" />

 

Массив был разделен на единичные массивы, которые алгоритм сливает попарно до тех пор, пока не получится один массив, все элементы которого стоят на своих позициях.

Код программы на C++:

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include "stdafx.h"
#include <iostream>
using namespace std;
//функция, сливающая массивы
void Merge(int *A, int first, int last)
{
int middle, start, final, j;
int *mas=new int[100];
middle=(first+last)/2; //вычисление среднего элемента
start=first; //начало левой части
final=middle+1; //начало правой части
for(j=first; j<=last; j++) //выполнять от начала до конца
if ((start<=middle) && ((final>last) || (A[start]<A[final])))
{
mas[j]=A[start];
start++;
}
else
{
mas[j]=A[final];
final++;
}
//возвращение результата в список
for (j=first; j<=last; j++) A[j]=mas[j];
delete[]mas;
};
//рекурсивная процедура сортировки
void MergeSort(int *A, int first, int last)
{
{
if (first<last)
{
MergeSort(A, first, (first+last)/2); //сортировка левой части
MergeSort(A, (first+last)/2+1, last); //сортировка правой части
Merge(A, first, last); //слияние двух частей
}
}
};
//главная функция
void main()
{
setlocale(LC_ALL, "Rus");
int i, n;
int *A=new int[100];
cout<<"Размер массива > "; cin>>n;
for (i=1; i<=n; i++)
{ cout<<i<<" элемент > "; cin>>A[i];}
MergeSort(A, 1, n); //вызов сортирующей процедуры
cout<<"Упорядоченный массив: "; //вывод упорядоченного массива
for (i=1; i<=n; i++) cout<<A[i]<<" ";
delete []A;
system("pause>>void");
}

 

Код программы на Pascal:

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
program Sort_Marge;
uses crt;
type massiv=array[1..100] of integer;
var n, i: integer;
A: massiv;
{процедура, сливающая массивы}
procedure Merge(var A: massiv; first, last: integer);
var middle, start, final , j: integer;
mas: massiv;
begin
middle:=(first+last) div 2; {вычисление среднего элемента}
start:=first; {начало левой части}
final:=middle+1; {начало правой части}
for j:=first to last do {выполнять от начала до конца}
if (start<=middle) and ((final>last) or (A[start]<A[final])) then
begin
mas[j]:=A[start];
inc(start);
end
else
begin
mas[j]:=A[final];
inc(final);
end;
{возвращение результата в массив}
for j:=first to last do A[j]:=mas[j];
end;
{рекурсивная процедура сортировки}
procedure MergeSort(var A: massiv; first, last: integer);
begin
if first<last then
begin
MergeSort(A, first, (first+last) div 2); {сортировка левой части}
MergeSort(A, (first+last) div 2+1, last); {сортировка правой части}
Merge(A, first, last); {слияние двух частей}
end;
end;
{основной блок программы}
begin
clrscr;
write('Размер массива > ');
readln(n);
for i:=1 to n do
begin
write(i, ' элемент > '); read(A[i]);
end;
MergeSort(A, 1, n); {вызов сортирующей процедуры}
write('Упорядоченный массив: '); {вывод отсортированного массива}
for i:=1 to n do write(A[i], ' ');
readkey;
end.

 

Недостатком сортировки слиянием является использование дополнительной памяти. Но когда работать приходиться с файлами или списками, доступ к которым осуществляется только последовательно, то очень удобно применять именно этот метод. Также, к достоинствам алгоритма стоит отнести его устойчивость и неплохую скорость работы O(n*logn).

На этом все! Теперь вы знаете все про сортировка слиянием, Помните, что это теперь будет проще использовать на практике. Надеюсь, что теперь ты понял что такое сортировка слиянием и для чего все это нужно, а если не понял, или есть замечания, то не стесняйся, пиши или спрашивай в комментариях, с удовольствием отвечу. Для того чтобы глубже понять настоятельно рекомендую изучить всю информацию из категории Алгоритмы и теория алгоритмов

Из статьи мы узнали кратко, но содержательно про сортировка слиянием
создано: 2014-11-30
обновлено: 2021-03-13
132548



Рейтиг 9 of 10. count vote: 2
Вы довольны ?:


Поделиться:

Найди готовое или заработай

С нашими удобными сервисами без комиссии*

Как это работает? | Узнать цену?

Найти исполнителя
$0 / весь год.
  • У вас есть задание, но нет времени его делать
  • Вы хотите найти профессионала для выплнения задания
  • Возможно примерение функции гаранта на сделку
  • Приорететная поддержка
  • идеально подходит для студентов, у которых нет времени для решения заданий
Готовое решение
$0 / весь год.
  • Вы можите продать(исполнителем) или купить(заказчиком) готовое решение
  • Вам предоставят готовое решение
  • Будет предоставлено в минимальные сроки т.к. задание уже готовое
  • Вы получите базовую гарантию 8 дней
  • Вы можете заработать на материалах
  • подходит как для студентов так и для преподавателей
Я исполнитель
$0 / весь год.
  • Вы профессионал своего дела
  • У вас есть опыт и желание зарабатывать
  • Вы хотите помочь в решении задач или написании работ
  • Возможно примерение функции гаранта на сделку
  • подходит для опытных студентов так и для преподавателей



Комментарии


Оставить комментарий
Если у вас есть какое-либо предложение, идея, благодарность или комментарий, не стесняйтесь писать. Мы очень ценим отзывы и рады услышать ваше мнение.
To reply

Алгоритмы и теория алгоритмов

Термины: Алгоритмы и теория алгоритмов