"Информатика (базовый и углублённый уровни) (в 2 частях)", Поляков К.Ю., Еремин Е.А.
Двоичный поиск помогает быстро найти значение в упорядоченном массиве. На каждом шаге искомое число сравнивают со средним элементом и оставляют только ту половину, в которой оно ещё может находиться. Поэтому диапазон поиска быстро сокращается, а число сравнений растёт примерно как логарифм длины массива. Метод требует, чтобы данные заранее были расположены по возрастанию или убыванию.
Текст подготовлен нейронной сетью по теме параграфа и не заменяет учебник — важные факты и формулировки сверяйте с ним.
Двоичный поиск — способ найти элемент в упорядоченной последовательности, каждый раз отбрасывая половину оставшегося диапазона. В отличие от проверки элементов подряд, алгоритм сразу исключает много кандидатов. Это помогает быстро искать значения в больших массивах.
Упорядоченная последовательность — последовательность, элементы которой расположены по возрастанию или убыванию. Это обязательное условие двоичного поиска: только порядок позволяет определить, где может находиться искомое значение. Без него нельзя безопасно отбросить половину элементов.
Середина диапазона — элемент, с которым на каждом шаге сравнивают искомое значение, чтобы выбрать одну из половин для дальнейшего поиска. Например, если массив возрастающий и искомое число меньше значения в середине, искать нужно слева. Проверка середины определяет направление следующего шага.
Границы поиска — индексы начала и конца той части последовательности, где ещё может находиться искомый элемент. Сначала они охватывают весь массив, затем сдвигаются после каждого сравнения. По границам понятно, какие индексы ещё не исключены и завершился ли поиск.
Сначала диапазоном поиска делают весь массив: его границы показывают, что пока возможен любой индекс. Затем находят середину и сравнивают её значение с искомым. Это сравнение полезно потому, что упорядоченность сообщает, по какую сторону от середины могут быть подходящие элементы.
Если значения совпали, найденный элемент уже проверен, поэтому алгоритм может остановиться. Если массив расположен по возрастанию и искомое значение меньше среднего, справа от середины находятся только не меньшие значения; значит, там искать незачем. Если оно больше среднего, исключают левую часть по той же причине.
После выбора половины её границы становятся новыми границами поиска. Проверенный средний элемент тоже исключают, если он не совпал: повторная проверка не даст новой информации. Так диапазон уменьшается примерно вдвое на каждом шаге, а не на один элемент, как при обычном последовательном просмотре.
Алгоритм продолжают, пока значение не найдено или диапазон не опустел. В первом случае ответом служит индекс совпавшего элемента. Во втором левая граница оказывается правее правой, то есть ни одного допустимого индекса больше нет; это доказывает, что искомое значение отсутствует.
Если в массиве n элементов, двоичному поиску в худшем случае требуется порядка log₂ n сравнений, потому что число возможных элементов каждый раз делится примерно пополам. Например, для тысячи элементов достаточно около десяти шагов, тогда как линейный поиск может проверить все тысячу. Однако двоичный поиск выгоден лишь при готовом упорядоченном массиве: подготовка данных сортировкой тоже требует времени.
| Свойство | Линейный поиск | Двоичный поиск |
|---|---|---|
| Нужно ли упорядочивать последовательность | Нет | Да |
| Как выбирается следующий элемент для проверки | По очереди, один за другим | Элемент в середине текущего диапазона |
| Как сокращается диапазон возможных индексов | Обычно на один индекс за проверку | Примерно вдвое за проверку |
| Порядок числа сравнений в худшем случае | n | log₂ n |
| Когда предпочтительно применять | Для коротких или неупорядоченных данных | Для больших уже упорядоченных данных |
Таблица помогает выбрать способ поиска с учётом состояния данных и размера массива. Если порядок не задан, линейный поиск надёжнее, а сортировка ради одного поиска может не окупиться. Для большого отсортированного массива обычно выгоднее двоичный метод.
В массиве [2, 5, 8, 12, 16, 23, 38] нужно найти 16 и записать проверяемые элементы. Индексы массива идут от 0 до 6, поэтому сначала середина имеет индекс 3. После каждого сравнения оставляем только ту часть, где число 16 ещё может находиться.
Проверенные элементы: 12, 23, 16. Ответ: число найдено по индексу 4.
Точное значение искомого числа не задано, поэтому нельзя назвать конкретные элементы массива, которые будут проверены. Но можно определить ход поиска: каждый раз середина делит текущий отрезок индексов, а сравнение указывает, в какую часть двигаться. Поскольку число отсутствует, совпадения не будет, и в конце все возможные индексы исключатся.
Ответ: число отсутствует. Конкретная последовательность проверяемых значений зависит от того, где оно должно было бы находиться относительно элементов массива.
Нужно оценить максимальное число сравнений двоичного поиска и сопоставить его с линейным. При каждом шаге число кандидатов сокращается примерно вдвое, а 1024 = 2¹⁰. Поэтому после десяти делений от исходного диапазона остаётся единичный кандидат, который при необходимости проверяют.
Ответ: для двоичного поиска оценка составляет около 10 сравнений, для линейного — до 1024. Точное число для двоичного метода зависит от принятого варианта выбора середины и от того, найдено ли значение.
Для понимания двоичного поиска нужны понятия массива и индекса: границы обозначают номера элементов, которые ещё могут подойти. Также необходимо уметь сравнивать значения и понимать, что значит расположить последовательность по порядку. Без этих знаний нельзя выбрать середину и определить сторону поиска.
Метод применяется при работе с отсортированными данными, например в больших массивах. Он также помогает изучать сложность алгоритмов: на его примере видно, как деление задачи пополам приводит к логарифмическому росту числа сравнений. Это позволяет сравнивать эффективность разных способов решения.
Почему двоичный поиск нельзя применять к неотсортированному массиву?
Без упорядоченности сравнение с серединой не показывает, в какой половине находится искомое значение. Если отбросить одну из половин, нужный элемент можно потерять.
Как выбрать середину диапазона, если в нём чётное число элементов?
Можно взять любой из двух центральных элементов, например элемент с индексом (левая граница + правая граница) // 2. Главное — одинаково обновлять границы после сравнения, чтобы диапазон обязательно уменьшался.
Как понять, что искомого элемента в массиве нет?
Если значение не совпало с серединой, алгоритм продолжает поиск в подходящей половине. Когда левая граница становится больше правой, диапазон пуст и такого элемента в массиве нет.
Почему двоичный поиск требует меньше сравнений, чем линейный?
Линейный поиск проверяет элементы по одному, а двоичный после каждого сравнения отбрасывает примерно половину возможных вариантов. Поэтому число проверок растёт логарифмически, а не пропорционально длине массива.
Что делать, если в массиве есть несколько одинаковых искомых элементов?
Обычный двоичный поиск может найти любой из них, не обязательно первый или последний. Чтобы найти крайний элемент, после совпадения нужно продолжить поиск в соответствующей половине, сохраняя найденный индекс.
§ 65. Двоичный поиск