РУҚА
Задания № 25, 27 · ЕГЭ

Слияние массивов

Как объединить две последовательности, не нарушив порядок их элементов
6 мин чтенияСложность: Обновлено 29 сентября 2026

Слияние массивов — это построение одной последовательности из двух исходных с сохранением относительного порядка элементов. Приём особенно полезен, когда массивы уже упорядочены: тогда их можно объединить за один проход методом двух указателей, не выполняя полную сортировку заново.

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

Пусть даны последовательности \(A\) и \(B\). Нужно получить последовательность \(C\), содержащую все элементы \(A\) и \(B\). Если длины массивов равны \(n\) и \(m\), то длина результата равна \(n+m\). Слияние не удаляет повторяющиеся элементы и не меняет порядок элементов внутри каждого исходного массива.

D
Определение

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

T
Основное правило

Если массивы \(A\) и \(B\) отсортированы по возрастанию, то для получения отсортированного результата достаточно каждый раз сравнивать первые ещё не использованные элементы обоих массивов и переносить меньший.

\[|C|=|A|+|B|\]

Например, при слиянии \(A=(1,4,8)\) и \(B=(2,3,9)\) получаем \(C=(1,2,3,4,8,9)\). Но слияние возможно и для неотсортированных последовательностей: тогда сохраняется порядок элементов, однако результат не обязан быть отсортированным. Например, \(A=(5,1)\) и \(B=(4,2)\) можно объединить как \((5,1,4,2)\) или \((5,4,1,2)\) — выбор зависит от дополнительного условия задачи.

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

Для отсортированных массивов применяется метод двух указателей. Указатель \(i\) показывает первый неиспользованный элемент массива \(A\), а \(j\) — первый неиспользованный элемент массива \(B\). В начале \(i=0\) и \(j=0\) при нумерации с нуля.

  1. Пока в обоих массивах есть неиспользованные элементы, сравниваются \(A[i]\) и \(B[j]\).
  2. В результат записывается меньший элемент; указатель соответствующего массива увеличивается на один.
  3. Когда один массив заканчивается, все оставшиеся элементы второго добавляются в конец результата.
\[C[k]=\min(A[i],B[j]),\quad i\leftarrow i+1\ \text{или}\ j\leftarrow j+1\]

Если элементы равны, можно взять элемент из любого массива. В задачах, где нужно сохранить устойчивость — например, порядок одинаковых ключей, — обычно сначала выбирают элемент из \(A\). Для обычного объединения числовых массивов это различие не влияет на значения результата.

Python
def merge(a, b):
    i = 0
    j = 0
    result = []

    while i < len(a) and j < len(b):
        if a[i] <= b[j]:
            result.append(a[i])
            i += 1
        else:
            result.append(b[j])
            j += 1

    result.extend(a[i:])
    result.extend(b[j:])
    return result
Приём для экзамена

После основного цикла не сравнивайте элементы снова. Один из массивов уже пуст, поэтому остаток другого можно целиком дописать в результат. В цикле удобно проверять условие \(i<n\) и \(j<m\).

Почему алгоритм работает быстро

Каждый элемент каждого массива переносится в результат ровно один раз. Указатели только увеличиваются и никогда не возвращаются назад. Поэтому число действий пропорционально общей длине массивов.

\[T(n,m)=O(n+m)\]

Дополнительная память для нового массива равна \(O(n+m)\). Если требуется изменить один из массивов на месте, алгоритм может быть другим; в школьных задачах обычно создают отдельный массив результата.

T
Инвариант слияния

Перед каждой итерацией все уже записанные элементы результата являются наименьшими среди ещё не выбранных элементов и расположены в правильном порядке. Поэтому после добавления меньшего из \(A[i]\) и \(B[j]\) этот порядок сохраняется.

Проверь себя

Массивы \(A=(2,6,10)\) и \(B=(1,6,8)\) отсортированы по возрастанию. Какой элемент попадёт первым в результат?

Разобранный пример

Даны два отсортированных массива: \(A=(2,5,7,12)\) и \(B=(1,5,6,10,13)\). Требуется получить их объединение по возрастанию. Обозначим текущие позиции указателей через \(i\) и \(j\).

1
В начале сравниваем \(A[0]=2\) и \(B[0]=1\). Меньше единица, поэтому берём её.
\(\displaystyle C=(1),\quad i=0,\ j=1\)
2
Сравниваем \(A[0]=2\) и \(B[1]=5\). Берём \(2\).
\(\displaystyle C=(1,2),\quad i=1,\ j=1\)
3
Сравниваем \(A[1]=5\) и \(B[1]=5\). При равенстве сначала берём элемент из \(A\).
\(\displaystyle C=(1,2,5),\quad i=2,\ j=1\)
4
Сравниваем \(A[2]=7\) и \(B[1]=5\). Берём \(5\) из массива \(B\).
\(\displaystyle C=(1,2,5,5),\quad i=2,\ j=2\)
5
Сравниваем \(7\) и \(6\). Берём \(6\). Затем сравниваем \(7\) и \(10\) и берём \(7\).
\(\displaystyle C=(1,2,5,5,6,7),\quad i=3,\ j=3\)
6
Сравниваем \(12\) и \(10\). Берём \(10\). Затем сравниваем \(12\) и \(13\) и берём \(12\).
\(\displaystyle C=(1,2,5,5,6,7,10,12),\quad i=4,\ j=4\)
7
Массив \(A\) закончился. Оставшиеся элементы \(B[4]=13\) дописываем без сравнений.
C=(1,2,5,5,6,7,10,12,13)
№
Ответ к примеру

Итоговый массив: \(C=(1,2,5,5,6,7,10,12,13)\). В нём \(4+5=9\) элементов — столько же, сколько было в исходных массивах вместе.

Слияние в задачах с условиями

В экзаменационных задачах требуется не только слить массивы полностью. Иногда нужно посчитать количество общих элементов, сформировать пересечение, удалить повторы или слить строки. Основная идея остаётся прежней: указатели движутся только вперёд.

  • Для объединения с сохранением повторов записывайте меньший элемент и увеличивайте один указатель.
  • Для пересечения записывайте элемент только при равенстве \(A[i]=B[j]\), затем увеличивайте оба указателя.
  • Для подсчёта элементов, встречающихся в обоих массивах, при равенстве увеличивайте счётчик.
  • Для удаления повторов проверяйте, отличается ли новый элемент от последнего уже записанного.

Если исходные массивы не отсортированы, сначала может потребоваться сортировка массива. В зависимости от условия используют сортировку по возрастанию или сортировку по убыванию. После сортировки можно применить слияние, но важно учитывать: сортировка меняет исходный порядок.

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

Частые ошибки

!
Что часто приводит к неверному ответу

1. Забывают дописать остаток массива после завершения основного цикла. 2. Используют условие i < n and j < m, но затем обращаются к элементу закончившегося массива. 3. Увеличивают оба указателя после выбора только одного элемента — часть данных теряется. 4. Считают, что слияние всегда сортирует данные, хотя для этого исходные массивы должны быть отсортированы. 5. Удаляют равные элементы без указания в условии: при обычном слиянии повторы сохраняются. 6. Путают индекс последнего элемента с длиной массива: при нумерации с нуля последний индекс равен \(n-1\).

Запомнить

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

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

  • Проверить, что длина результата равна сумме длин исходных массивов.
  • Проверить, что каждый исходный элемент встречается в результате нужное число раз.
  • Проверить порядок: последовательность элементов каждого массива не изменился.
  • Если массивы отсортированы, проверить сортировку результата.
  • Отдельно протестировать пустой массив и случай равных элементов.
Q
Быстрый тест по теме

Быстрая проверка

~ 2 мин4 вопроса
Вопрос 1 / 4
Вопрос 1 из 4 · длина результата
Какова длина результата при слиянии массивов длины \(7\) и \(4\)?
Главное за минуту

Главное

  • Слияние объединяет две последовательности и сохраняет все элементы в нужном порядке.
  • Для отсортированных массивов используется метод двух указателей.
  • После окончания одного массива остаток второго дописывается целиком.
  • Время работы слияния равно \(O(n+m)\), а длина результата — \(n+m\).
  • Перед решением проверьте, нужно ли сохранять повторы, сортировать данные или искать только общие элементы.