Files
hello-algo/ru/docs/chapter_divide_and_conquer/divide_and_conquer.md
Yudong Jin 22b3b568ef fix Ru translation (#1894)
* docs(ru): replace prose quotes with guillemets

* docs(ru): replace prose semicolons with periods

* docs(ru): align animation title forms

* docs(ru): align figure and table references
2026-04-14 18:10:12 +08:00

15 KiB
Raw Blame History

Стратегия разделяй и властвуй

Разделяй и властвуй (divide and conquer) - это очень важная и широко используемая стратегия построения алгоритмов. Обычно она реализуется через рекурсию и включает два этапа: «разделение» и «объединение».

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

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

  1. Разделение: рекурсивно разделить исходный массив (исходную задачу) на два подмассива (подзадачи), пока в подмассиве не останется только один элемент (наименьшая подзадача).
  2. Объединение: снизу вверх объединять упорядоченные подмассивы (решения подзадач), чтобы получить упорядоченный исходный массив (решение исходной задачи).

Стратегия разделяй и властвуй в сортировке слиянием

Как определить задачу «разделяй и властвуй»

Чтобы понять, подходит ли задача для решения методом «разделяй и властвуй», обычно можно ориентироваться на следующие критерии.

  1. Задача раскладывается на части: исходную задачу можно разбить на более мелкие и похожие подзадачи, причем такое разбиение можно применять рекурсивно.
  2. Подзадачи независимы: подзадачи не пересекаются, не зависят друг от друга и могут решаться независимо.
  3. Решения подзадач можно объединить: решение исходной задачи получается объединением решений подзадач.

Очевидно, что сортировка слиянием удовлетворяет всем трем критериям.

  1. Задача раскладывается на части: массив (исходная задача) рекурсивно делится на два подмассива (подзадачи).
  2. Подзадачи независимы: каждый подмассив можно сортировать отдельно (то есть каждую подзадачу можно решать независимо).
  3. Решения подзадач можно объединить: два упорядоченных подмассива (решения подзадач) можно объединить в один упорядоченный массив (решение исходной задачи).

Повышение эффективности с помощью «разделяй и властвуй»

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

Тогда возникает естественный вопрос: почему стратегия «разделяй и властвуй» повышает эффективность алгоритма и какова внутренняя логика этого подхода? Иными словами, почему разбиение большой задачи на несколько подзадач, решение этих подзадач и последующее объединение их решений оказывается эффективнее, чем прямое решение исходной задачи? Этот вопрос можно рассмотреть с двух сторон: через число операций и через параллельные вычисления.

Оптимизация числа операций

Рассмотрим «сортировку пузырьком»: для массива длины n ей требуется O(n^2) времени. Предположим, что мы разделим массив на два подмассива в середине, как показано на рисунке ниже. Тогда само разбиение потребует O(n) времени, сортировка каждого подмассива займет O((n / 2)^2) времени, а объединение двух подмассивов потребует еще O(n) времени. Общая временная сложность будет равна:


O(n + (\frac{n}{2})^2 \times 2 + n) = O(\frac{n^2}{2} + 2n)

Сортировка пузырьком до и после разбиения массива

Теперь рассмотрим следующее неравенство, в котором левая и правая части обозначают общее число операций до разбиения и после него:


\begin{aligned}
n^2 & > \frac{n^2}{2} + 2n \newline
n^2 - \frac{n^2}{2} - 2n & > 0 \newline
n(n - 4) & > 0
\end{aligned}

Это означает, что при n > 4 число операций после разбиения становится меньше, а значит, сортировка должна работать быстрее. При этом важно заметить, что временная сложность после разбиения все еще остается квадратичной, то есть O(n^2). Уменьшается лишь константный множитель.

Если пойти дальше и продолжать делить каждый подмассив пополам, пока в нем не останется только один элемент, то мы фактически получим «сортировку слиянием», чья временная сложность равна O(n \log n) .

Можно пойти еще дальше и спросить: что если задать несколько точек разделения и равномерно разбить исходный массив на k подмассивов? Такая ситуация очень похожа на блочную сортировку, которая особенно хорошо подходит для сортировки очень больших объемов данных и теоретически может достигать временной сложности O(n + k) .

Оптимизация параллельных вычислений

Мы знаем, что подзадачи, порождаемые стратегией «разделяй и властвуй», являются независимыми, а значит, их обычно можно решать параллельно. Иначе говоря, «разделяй и властвуй» не только может уменьшить временную сложность алгоритма, но и хорошо сочетается с параллельной оптимизацией на уровне системы.

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

Например, в «блочной сортировке», показанной на рисунке ниже, большой объем данных равномерно распределяется по блокам. Тогда сортировку каждого блока можно поручить отдельным вычислительным единицам, а после завершения просто объединить результаты.

Параллельные вычисления в блочной сортировке

Типичные применения стратегии «разделяй и властвуй»

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

  • Поиск ближайшей пары точек: сначала множество точек делится на две части, затем ищется ближайшая пара в каждой части, а затем ближайшая пара, пересекающая границу между двумя частями.
  • Умножение больших чисел: например, алгоритм Карацубы, который раскладывает умножение больших чисел на несколько умножений и сложений меньших чисел.
  • Умножение матриц: например, алгоритм Штрассена, который раскладывает умножение больших матриц на несколько умножений и сложений матриц меньшего размера.
  • Задача о Ханойской башне: задача о Ханойской башне решается рекурсивно и является типичным примером применения стратегии «разделяй и властвуй».
  • Подсчет инверсий: если в последовательности предыдущее число больше следующего, то такая пара образует инверсию. Эту задачу можно решить с помощью идей «разделяй и властвуй», опираясь на сортировку слиянием.

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

  • Двоичный поиск: двоичный поиск делит отсортированный массив на две части по индексу середины, а затем, в зависимости от результата сравнения целевого значения со средним элементом, исключает одну из половин и повторяет ту же операцию на оставшемся интервале.
  • Сортировка слиянием: она уже была рассмотрена в начале этого раздела, поэтому не будем повторяться.
  • Быстрая сортировка: в ней выбирается опорное значение, после чего массив делится на два подмассива: один содержит элементы меньше опорного, а другой - больше. Затем такая же операция повторяется для обеих частей, пока в подмассиве не останется один элемент.
  • Блочная сортировка: ее основная идея заключается в распределении данных по нескольким блокам, сортировке элементов внутри каждого блока и последующем последовательном извлечении элементов из блоков для построения отсортированного массива.
  • Деревья: например, двоичные деревья поиска, AVL-деревья, красно-черные деревья, B-деревья, B+ деревья и т.д. Их операции поиска, вставки и удаления можно рассматривать как применение стратегии «разделяй и властвуй».
  • Кучи: куча является особым видом полного двоичного дерева, а такие операции, как вставка, удаление и упорядочивание, по сути содержат идеи «разделяй и властвуй».
  • Хеш-таблицы: хотя хеш-таблицы напрямую не используют стратегию «разделяй и властвуй», некоторые способы разрешения коллизий косвенно опираются на эту идею. Например, длинные цепочки в методе цепочек могут преобразовываться в красно-черные деревья для повышения эффективности поиска.

Нетрудно заметить, что «разделяй и властвуй» - это «тихая» алгоритмическая идея, скрыто присутствующая внутри самых разных алгоритмов и структур данных.