mirror of
https://github.com/krahets/hello-algo.git
synced 2026-08-11 03:10:58 +00:00
build
This commit is contained in:
@@ -2,25 +2,25 @@
|
||||
comments: true
|
||||
---
|
||||
|
||||
# 12.1 Алгоритмы "разделяй и властвуй"
|
||||
# 12.1 Стратегия разделяй и властвуй
|
||||
|
||||
<u>Разделяй и властвуй (divide and conquer)</u> - это очень важная и широко используемая стратегия построения алгоритмов. Обычно она реализуется через рекурсию и включает два этапа: "разделение" и "решение".
|
||||
<u>Разделяй и властвуй (divide and conquer)</u> - это очень важная и широко используемая стратегия построения алгоритмов. Обычно она реализуется через рекурсию и включает два этапа: "разделение" и "объединение".
|
||||
|
||||
1. **Разделение (этап декомпозиции)**: рекурсивно разбить исходную задачу на две или более подзадачи, пока не будет достигнута наименьшая подзадача.
|
||||
2. **Решение (этап объединения)**: начиная с уже известных решений наименьших подзадач, снизу вверх объединять решения подзадач и тем самым получать решение исходной задачи.
|
||||
2. **Объединение (этап синтеза)**: начиная с уже известных решений наименьших подзадач, снизу вверх объединять решения подзадач и тем самым получать решение исходной задачи.
|
||||
|
||||
Как показано на рисунке 12-1, "сортировка слиянием" является одним из типичных примеров применения стратегии "разделяй и властвуй".
|
||||
|
||||
1. **Разделение**: рекурсивно разделить исходный массив (исходную задачу) на два подмассива (подзадачи), пока в подмассиве не останется только один элемент (наименьшая подзадача).
|
||||
2. **Решение**: снизу вверх объединять упорядоченные подмассивы (решения подзадач), чтобы получить упорядоченный исходный массив (решение исходной задачи).
|
||||
2. **Объединение**: снизу вверх объединять упорядоченные подмассивы (решения подзадач), чтобы получить упорядоченный исходный массив (решение исходной задачи).
|
||||
|
||||
{ class="animation-figure" }
|
||||
{ class="animation-figure" }
|
||||
|
||||
<p align="center"> Рисунок 12-1 Стратегия divide and conquer в сортировке слиянием </p>
|
||||
<p align="center"> Рисунок 12-1 Стратегия разделяй и властвуй в сортировке слиянием </p>
|
||||
|
||||
## 12.1.1 Как определить задачу divide and conquer
|
||||
## 12.1.1 Как определить задачу "разделяй и властвуй"
|
||||
|
||||
Чтобы понять, подходит ли задача для решения методом divide and conquer, обычно можно ориентироваться на следующие критерии.
|
||||
Чтобы понять, подходит ли задача для решения методом "разделяй и властвуй", обычно можно ориентироваться на следующие критерии.
|
||||
|
||||
1. **Задача раскладывается на части**: исходную задачу можно разбить на более мелкие и похожие подзадачи, причем такое разбиение можно применять рекурсивно.
|
||||
2. **Подзадачи независимы**: подзадачи не пересекаются, не зависят друг от друга и могут решаться независимо.
|
||||
@@ -32,11 +32,11 @@ comments: true
|
||||
2. **Подзадачи независимы**: каждый подмассив можно сортировать отдельно (то есть каждую подзадачу можно решать независимо).
|
||||
3. **Решения подзадач можно объединить**: два упорядоченных подмассива (решения подзадач) можно объединить в один упорядоченный массив (решение исходной задачи).
|
||||
|
||||
## 12.1.2 Повышение эффективности с помощью divide and conquer
|
||||
## 12.1.2 Повышение эффективности с помощью "разделяй и властвуй"
|
||||
|
||||
**Стратегия divide and conquer не только позволяет эффективно решать алгоритмические задачи, но и часто повышает эффективность самих алгоритмов**. Именно поэтому быстрая сортировка, сортировка слиянием и пирамидальная сортировка обычно работают быстрее, чем сортировка выбором, пузырьком и вставками.
|
||||
**Стратегия "разделяй и властвуй" не только позволяет эффективно решать алгоритмические задачи, но и часто повышает эффективность самих алгоритмов**. Именно поэтому быстрая сортировка, сортировка слиянием и пирамидальная сортировка обычно работают быстрее, чем сортировка выбором, пузырьком и вставками.
|
||||
|
||||
Тогда возникает естественный вопрос: **почему divide and conquer повышает эффективность алгоритма и какова логика этого на более глубоком уровне**? Иными словами, почему разбиение большой задачи на несколько подзадач, решение этих подзадач и последующее объединение их решений оказывается эффективнее, чем прямое решение исходной задачи? Этот вопрос можно рассмотреть с двух сторон: через число операций и через параллельные вычисления.
|
||||
Тогда возникает естественный вопрос: **почему стратегия "разделяй и властвуй" повышает эффективность алгоритма и какова внутренняя логика этого подхода**? Иными словами, почему разбиение большой задачи на несколько подзадач, решение этих подзадач и последующее объединение их решений оказывается эффективнее, чем прямое решение исходной задачи? Этот вопрос можно рассмотреть с двух сторон: через число операций и через параллельные вычисления.
|
||||
|
||||
### 1. Оптимизация числа операций
|
||||
|
||||
@@ -64,11 +64,11 @@ $$
|
||||
|
||||
Если пойти дальше и **продолжать делить каждый подмассив пополам**, пока в нем не останется только один элемент, то мы фактически получим "сортировку слиянием", чья временная сложность равна $O(n \log n)$ .
|
||||
|
||||
Можно пойти еще дальше и спросить: **что если задать несколько точек разделения** и равномерно разбить исходный массив на $k$ подмассивов? Такая ситуация очень похожа на "блочную сортировку", которая особенно хорошо подходит для сортировки очень больших объемов данных и теоретически может достигать временной сложности $O(n + k)$ .
|
||||
Можно пойти еще дальше и спросить: **что если задать несколько точек разделения** и равномерно разбить исходный массив на $k$ подмассивов? Такая ситуация очень похожа на блочную сортировку, которая особенно хорошо подходит для сортировки очень больших объемов данных и теоретически может достигать временной сложности $O(n + k)$ .
|
||||
|
||||
### 2. Оптимизация параллельных вычислений
|
||||
|
||||
Мы знаем, что подзадачи, порождаемые divide and conquer, являются независимыми, **а значит, их обычно можно решать параллельно**. Иначе говоря, divide and conquer не только может уменьшить временную сложность алгоритма, **но и хорошо сочетается с параллельной оптимизацией на уровне системы**.
|
||||
Мы знаем, что подзадачи, порождаемые стратегией "разделяй и властвуй", являются независимыми, **а значит, их обычно можно решать параллельно**. Иначе говоря, "разделяй и властвуй" не только может уменьшить временную сложность алгоритма, **но и хорошо сочетается с параллельной оптимизацией на уровне системы**.
|
||||
|
||||
Параллельная оптимизация особенно эффективна в среде с несколькими ядрами или несколькими процессорами, потому что система может одновременно обрабатывать разные подзадачи, лучше загружая вычислительные ресурсы и тем самым заметно сокращая общее время работы.
|
||||
|
||||
@@ -78,24 +78,24 @@ $$
|
||||
|
||||
<p align="center"> Рисунок 12-3 Параллельные вычисления в блочной сортировке </p>
|
||||
|
||||
## 12.1.3 Типичные применения divide and conquer
|
||||
## 12.1.3 Типичные применения стратегии "разделяй и властвуй"
|
||||
|
||||
С одной стороны, divide and conquer можно использовать для решения многих классических алгоритмических задач.
|
||||
С одной стороны, стратегию "разделяй и властвуй" можно использовать для решения многих классических алгоритмических задач.
|
||||
|
||||
- **Поиск ближайшей пары точек**: сначала множество точек делится на две части, затем ищется ближайшая пара в каждой части, а затем ближайшая пара, пересекающая границу между двумя частями.
|
||||
- **Умножение больших чисел**: например, алгоритм Карацубы, который раскладывает умножение больших чисел на несколько умножений и сложений меньших чисел.
|
||||
- **Умножение матриц**: например, алгоритм Штрассена, который раскладывает умножение больших матриц на несколько умножений и сложений матриц меньшего размера.
|
||||
- **Задача о Ханойской башне**: задача о Ханойской башне решается рекурсивно и является типичным примером применения divide and conquer.
|
||||
- **Подсчет инверсий**: если в последовательности предыдущее число больше следующего, то такая пара образует инверсию. Эту задачу можно решить с помощью идей divide and conquer, опираясь на сортировку слиянием.
|
||||
- **Задача о Ханойской башне**: задача о Ханойской башне решается рекурсивно и является типичным примером применения стратегии "разделяй и властвуй".
|
||||
- **Подсчет инверсий**: если в последовательности предыдущее число больше следующего, то такая пара образует инверсию. Эту задачу можно решить с помощью идей "разделяй и властвуй", опираясь на сортировку слиянием.
|
||||
|
||||
С другой стороны, divide and conquer очень широко применяется при проектировании алгоритмов и структур данных.
|
||||
С другой стороны, стратегия "разделяй и властвуй" очень широко применяется при проектировании алгоритмов и структур данных.
|
||||
|
||||
- **Двоичный поиск**: двоичный поиск делит отсортированный массив на две части по индексу середины, а затем, в зависимости от результата сравнения целевого значения со средним элементом, исключает одну из половин и повторяет ту же операцию на оставшемся интервале.
|
||||
- **Сортировка слиянием**: она уже была рассмотрена в начале этого раздела, поэтому не будем повторяться.
|
||||
- **Быстрая сортировка**: в ней выбирается опорное значение, после чего массив делится на два подмассива: один содержит элементы меньше опорного, а другой - больше. Затем такая же операция повторяется для обеих частей, пока в подмассиве не останется один элемент.
|
||||
- **Блочная сортировка**: ее основная идея заключается в распределении данных по нескольким блокам, сортировке элементов внутри каждого блока и последующем последовательном извлечении элементов из блоков для построения отсортированного массива.
|
||||
- **Деревья**: например, двоичные деревья поиска, AVL-деревья, красно-черные деревья, B-деревья, B+ деревья и т.д. Их операции поиска, вставки и удаления можно рассматривать как применение divide and conquer.
|
||||
- **Кучи**: куча является особым видом полного бинарного дерева, а такие операции, как вставка, удаление и упорядочивание, по сути содержат идеи divide and conquer.
|
||||
- **Хеш-таблицы**: хотя хеш-таблицы напрямую не используют divide and conquer, некоторые способы разрешения коллизий косвенно опираются на эту стратегию. Например, длинные цепочки в методе цепочек могут преобразовываться в красно-черные деревья для повышения эффективности поиска.
|
||||
- **Деревья**: например, двоичные деревья поиска, AVL-деревья, красно-черные деревья, B-деревья, B+ деревья и т.д. Их операции поиска, вставки и удаления можно рассматривать как применение стратегии "разделяй и властвуй".
|
||||
- **Кучи**: куча является особым видом полного двоичного дерева, а такие операции, как вставка, удаление и упорядочивание, по сути содержат идеи "разделяй и властвуй".
|
||||
- **Хеш-таблицы**: хотя хеш-таблицы напрямую не используют стратегию "разделяй и властвуй", некоторые способы разрешения коллизий косвенно опираются на эту идею. Например, длинные цепочки в методе цепочек могут преобразовываться в красно-черные деревья для повышения эффективности поиска.
|
||||
|
||||
Нетрудно заметить, что **divide and conquer - это "тихая" алгоритмическая идея**, скрыто присутствующая внутри самых разных алгоритмов и структур данных.
|
||||
Нетрудно заметить, что **"разделяй и властвуй" - это "тихая" алгоритмическая идея**, скрыто присутствующая внутри самых разных алгоритмов и структур данных.
|
||||
|
||||
Reference in New Issue
Block a user