Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методы_new1 (2).doc
Скачиваний:
0
Добавлен:
11.02.2026
Размер:
197.59 Кб
Скачать
  1. Сортировка слиянием

Алгоритм сортировки слиянием был изобретен Джоном фон Нейманом в 1945 году. Он является одним из самых быстрых способов сортировки.

Слияние – это объединение двух или более упорядоченных массивов в один упорядоченный.

Сортировка слиянием является одним из самых простых алгоритмов сортировки (среди быстрых алгоритмов).

Особенностью этого алгоритма является то, что он работает с элементами массива преимущественно последовательно, благодаря чему именно этот алгоритм используется при сортировке в системах с различными аппаратными ограничениями (например, при сортировке данных на жестком диске).

Кроме того, сортировка слиянием является алгоритмом, который может быть эффективно использован для сортировки таких структур данных, как связанные списки.

Данный алгоритм применяется тогда, когда есть возможность использовать для хранения промежуточных результатов память, сравнимую с размером исходного массива.

Сначала задача разбивается на несколько подзадач меньшего размера. Затем эти задачи решаются с помощью рекурсивного вызова или непосредственно, если их размер достаточно мал.

Далее их решения комбинируются, и получается решение исходной задачи.

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

Алгоритм сортировки слиянием

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

Шаг 2. Разбить имеющиеся отсортированные цепочки на пары, и осуществить слияние цепочек каждой пары.

Шаг 3. Если число отсортированных цепочек больше единицы, перейти к шагу 2.

Рис. Демонстрация сортировки слиянием по неубыванию

//Описание функции сортировки слиянием

template <class T>

Void Merging_Sort (t *a, int n){

int i, j, //текущие индексы первого и второго сортированных

// подмассивов

k, //количество элементов в сортированных подмассивах

t, // индекс первого символа в первом подмассиве

s, //индекс массива вспомагательного

Fin1, //индекс первого элемента во втором подмассиве

Fin2; // индекс первого символа в первом подмассиве следующей

// группы подмассивов

T* tmp = new T[n]; //динамический массив того же размера

k = 1; // кол. элементов в сортированных слияемых подмассивах

while (k < n){ //1

t = 0; s = 0;

while (t+k < n){ //2 пока есть второй подмассив

Fin1 = t+k; // номер индекса первого элемента второго подмассива

Fin2 = (t+2*k < n ? t+2*k : n); //номер индекса первого эл. первого //подмассива следующей группы слияемых подмассивов

i = t; j = Fin1; // индексы на начало первого и второго подмассивов

for ( ; i < Fin1 && j < Fin2 ; s++){ // 3 пока мы в пределах обоих

//массивов

if (a[i] < a[j]) {

tmp[s] = a[i]; //заполняем динамический массив

i++;

}

else {

tmp[s] = a[j];

j++;

}

}//3

for ( ; i < Fin1; i++, s++) //если остались эл. в первом массиве

tmp[s] = a[i];

for ( ; j < Fin2; j++, s++) //если остались эл. во втором массиве

tmp[s] = a[j];

t = Fin2; // t присваивается индекс первого элемента первого

// подмассива следующей группы

}//2

//прошли все группы и теперь в сортированных массивах в 2 раза больше элементов

k *= 2;

for (s = 0; s < t; s++)

a[s] = tmp[s];

}//1

delete(tmp);

}

Недостаток алгоритма заключается в том, что он требует дополнительную память размером порядка n (для хранения вспомогательного массива).

Кроме того, он не гарантирует сохранение порядка элементов с одинаковыми значениями. Но его сложность всегда пропорциональна  O(n log n).

//-------------------------------------------------------------------------------------------------