mirror of
https://github.com/krahets/hello-algo.git
synced 2026-07-24 12:06:07 +00:00
First version.
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
# Разделяй и властвуй
|
||||
|
||||
<u>Разделяй и властвуй (divide and conquer)</u> -- это важная и распространенная стратегия в алгоритмах. Обычно она реализуется с помощью рекурсии и включает два этапа: разделение и объединение.
|
||||
|
||||
1. **Разделение (этап разбиения)**: рекурсивное разбиение исходной задачи на две или более подзадачи до тех пор, пока не будет достигнута наименьшая подзадача.
|
||||
2. **Объединение (этап слияния)**: начиная с решения наименьших подзадач, снизу вверх объединяются решения всех других подзадач, чтобы построить решение исходной задачи.
|
||||
|
||||
Сортировка слиянием является типичным примером применения стратегии «разделяй и властвуй» (см. рис. 12.1).
|
||||
|
||||
1. **Разделение**: рекурсивное разбиение исходного массива (исходной задачи) на два подмассива (подзадачи) до тех пор, пока в подмассивах не останется по одному элементу (наименьшая подзадача).
|
||||
2. **Объединение**: снизу вверх объединяются упорядоченные подмассивы (решения подзадач), чтобы получить упорядоченный исходный массив (решение исходной задачи).
|
||||
|
||||

|
||||
|
||||
## Определение задачи для метода «разделяй и властвуй»
|
||||
|
||||
Чтобы определить, подходит ли задача для решения методом «разделяй и властвуй», можно использовать следующие критерии:
|
||||
|
||||
1. **Задачу можно разбить**: исходную задачу можно разбить на более мелкие, аналогичные подзадачи, которые можно рекурсивно разделить аналогичным образом.
|
||||
2. **Подзадачи независимы**: подзадачи не пересекаются, не зависят друг от друга и могут быть решены независимо.
|
||||
3. **Решения подзадач можно объединить**: решение исходной задачи получается путем объединения решений подзадач.
|
||||
|
||||
Очевидно, что сортировка слиянием соответствует этим трем критериям.
|
||||
|
||||
1. **Задачу можно разбить**: рекурсивное разбиение массива (исходной задачи) на два подмассива (подзадачи).
|
||||
2. **Подзадачи независимы**: каждый подмассив можно отсортировать независимо (подзадачи можно решить независимо).
|
||||
3. **Решения подзадач можно объединить**: два упорядоченных подмассива (решения подзадач) можно объединить в один упорядоченный массив (решение исходной задачи).
|
||||
|
||||
## Повышение эффективности с помощью стратегии «разделяй и властвуй»
|
||||
|
||||
**Стратегия «разделяй и властвуй» позволяет не только эффективно решать алгоритмические задачи, но и повышать эффективность алгоритмов**. Алгоритмы быстрой сортировки, сортировки слиянием и пирамидальной сортировки быстрее, чем сортировка выбором, пузырьком и вставками, именно благодаря применению стратегии «разделяй и властвуй».
|
||||
|
||||
Возникает вопрос: **почему метод «разделяй и властвуй» повышает эффективность алгоритма, в чем его основная логика**? Иными словами, почему разбиение большой задачи на несколько подзадач, решение этих подзадач и объединение их решений в решение исходной задачи оказывается более эффективным, чем непосредственное решение исходной задачи? Этот вопрос можно обсудить с точки зрения количества операций и параллельных вычислений.
|
||||
|
||||
### Оптимизация количества операций
|
||||
|
||||
Возьмем, к примеру, сортировку пузырьком, которая требует времени $O(n^2)$ для обработки массива длиной $n$. Предположим, что мы разделили массив на два подмассива, как показано на рис. 12.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 \\
|
||||
n^2 - \frac{n^2}{2} - 2n & > 0 \\
|
||||
n(n - 4) & > 0
|
||||
\end{aligned}
|
||||
$$
|
||||
|
||||
**Это означает, что при $n > 4$ количество операций после разбиения меньше, и эффективность сортировки должна быть выше**. Обратите внимание, что временная сложность после разбиения остается квадратичной $O(n^2)$, но постоянный коэффициент в сложности уменьшается.
|
||||
|
||||
**Если продолжить разбиение подмассивов пополам, пока в них не останется по одному элементу**, то получится сортировка слиянием, временная сложность которой составляет $O(n \log n)$.
|
||||
|
||||
А что, **если мы установим несколько дополнительных точек разделения** и равномерно разделим исходный массив на $k$ подмассивов? Эта ситуация очень похожа на блочную сортировку, которая хорошо подходит для сортировки очень больших объемов данных, и теоретически ее временная сложность может достигать $O(n + k)$.
|
||||
|
||||
### Оптимизация параллельных вычислений
|
||||
|
||||
Известно, что подзадачи, созданные методом «разделяй и властвуй», независимы друг от друга, **поэтому их обычно можно решать параллельно**. Таким образом, этот метод не только снижает временную сложность алгоритма, **но и способствует параллельной оптимизации операционной системы**.
|
||||
|
||||
Параллельная оптимизация особенно эффективна в многоядерной или многопроцессорной среде, поскольку система может одновременно обрабатывать несколько подзадач, более полно используя вычислительные ресурсы, что значительно сокращает общее время выполнения.
|
||||
|
||||
Например, в блочной сортировке, изображенной на рис. 12.3, огромный объем данных равномерно распределяется по блокам. Задачи сортировки всех блоков можно распределить по вычислительным единицам, а затем объединить результаты.
|
||||
|
||||

|
||||
|
||||
## Типичные сценарии применения стратегии «разделяй и властвуй»
|
||||
|
||||
С одной стороны, стратегию «разделяй и властвуй» можно использовать для решения многих классических алгоритмических задач.
|
||||
|
||||
- **Поиск ближайшей пары точек**: этот алгоритм сначала делит множество точек на две части, затем находит ближайшую пару точек в каждой части, а затем находит ближайшую пару точек, охватывающую обе части.
|
||||
- **Умножение больших чисел**: например, алгоритм Карацубы, который разлагает умножение больших чисел на несколько операций умножения и сложения меньших чисел.
|
||||
- **Умножение матриц**: например, алгоритм Штрассена, который разлагает умножение больших матриц на несколько операций умножения и сложения матриц меньшего размера.
|
||||
- **Задача о Ханойских башнях**: эту задачу можно решить с помощью рекурсии, что является типичным применением стратегии «разделяй и властвуй».
|
||||
- **Задача о количестве инверсий**: если в последовательности предыдущее число больше последующего, то эти два числа образуют инверсию. Задачу о количестве инверсий можно решить с помощью подхода «разделяй и властвуй» и сортировки слиянием.
|
||||
|
||||
С другой стороны, стратегия «разделяй и властвуй» широко применяется в разработке алгоритмов и структур данных.
|
||||
|
||||
- **Двоичный поиск**: такой поиск делит отсортированный массив на две части по индексу среднего элемента. Затем, в зависимости от результата сравнения целевого значения со средним элементом, решает, какую половину исключить, и выполняет ту же операцию на оставшейся части.
|
||||
- **Сортировка слиянием**: уже была рассмотрена в начале этого раздела, не будем еще раз повторяться.
|
||||
- **Быстрая сортировка**: эта сортировка выбирает опорное значение, затем делит массив на два подмассива, элементы одного из которых меньше опорного значения, а элементы другого -- больше. Затем выполняет ту же операцию с обеими частями, пока в подмассиве не останется один элемент.
|
||||
- **Блочная сортировка**: основная идея этой сортировки заключается в распределении данных по нескольким блокам и сортировке элементов в каждом из них. Затем происходит последовательное извлечение элементов из каждого блока для построения отсортированного массива.
|
||||
- **Деревья**: например, двоичные деревья поиска, АВЛ-дерево, красно-черное дерево, B-дерево, дерево B+ и т. д. Операции поиска, вставки и удаления в них можно рассматривать как применение стратегии «разделяй и властвуй».
|
||||
- **Кучи**: куча -- это особый вид полного двоичного дерева, и такие операции, как вставка, удаление и упорядочивание, фактически подразумевают использование метода «разделяй и властвуй».
|
||||
- **Хеш-таблицы**: хотя хеш-таблицы напрямую не применяют подход «разделяй и властвуй», некоторые решения для разрешения коллизий в хешировании косвенно используют эту стратегию. Например, длинные цепочки в методе цепной адресации преобразуются в красно-черные деревья для повышения эффективности поиска.
|
||||
|
||||
Можно сказать, **что стратегия «разделяй и властвуй» -- это своего рода «скрытая» алгоритмическая идея**, присутствующая в различных алгоритмах и структурах данных.
|
||||
Reference in New Issue
Block a user