код бинарного поиска python

Содержание

Бинарный (двоичный) поиск / Binary search на Python

Мы познакомились с линейным поиском, теперь настала очередь бинарного (двоичного).

В чем же он заключается?

Продолжаем поиск, когда находим искомое число, возвращаем его индекс, иначе делаем вывод, что такого числа нет в списке.

Как утверждается в этой статье, только 10% программистов способны написать двоичный поиск.

Поэтому рекомендую сначала реализовать самим на любимом ЯП, а потом прочитать дальше и поделиться результатом.

Нам же надо найти книгу, автор которой Пушкин.

Берем книгу посередине полки, смотрим, кто является ее автором. С первого раза мы потерпели неудачу, и автором данной книги оказался Тютчев.

Вспоминая, что книги отсортированы по автору, мы понимаем, что правее данной книги искомой нет, следовательно, надо искать левее.

Поэтому из поиска мы исключаем правую половину полки. Теперь возьмем книгу посередине левой половины полки и посмотрим, кто ее автор. Например, Лесков.

Значит, искомая книга находится правее. Далее берем книгу посреди оставшейся части полки. Если это та книга, которую мы искали, то все шикарно, иначе снова исключаем половину (левую или правую, в зависимости от автора) и тд.

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

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

Процедура будет принимать те же входные параметры, что и в линейном поиске:

Здесь мы на всякий случай сортируем список.

Искомый элемент найден, если значение середины “подсписка” lst[q] равно x.

Если lst[q] > x, мы исключаем все элементы справа от q.

Источник

Алгоритм бинарного поиска в Python

Узнайте об алгоритме бинарного поиска и о том, как его реализовать в программировании на Python.

Алгоритм Бинарного поиска является фундаментальным в информатике. Это очень умный алгоритм, который значительно сокращает время, необходимое для поиска элементов в больших наборах данных, по сравнению с менее эффективными подходами.

Алгоритмы поиска

Алгоритмы сортировки

Как работает Алгоритм Бинарного поиска?

Псевдокод для двоичного поиска

Это условие выхода является ключевым для этого алгоритма, и понимание того, почему это так, является хорошим признаком того, что вы понимаете весь алгоритм. По сути, у нас есть высокий указатель и низкий указатель, и мы проверяем элемент в середине этих двух указателей, чтобы увидеть, является ли он нашим элементом поиска. Если это так, отлично, мы выходим, в противном случае мы перемещаем либо высокий, либо низкий указатель таким образом, чтобы “зажать” наше значение.

Двоичный поиск в Python

Как только вы написали и поняли псевдокод, пришло время написать алгоритм на реальном языке программирования, таком как Python. Вы всегда должны иметь в виду конкретный пример, чтобы проверить, что ваша программа ведет себя так, как ожидалось. Итак, определите список (я часто называю его стог сена ) и элемент поиска ( игла ) и посмотрите, сможете ли вы заставить свою программу найти иглу в стоге сена. И помните: список должен быть отсортирован в первую очередь!

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

Источник

Двоичный поиск в Python

Из этого туториала Вы узнаете, как применить алгоритм двоичного поиска в Python, чтобы найти позицию индекса элемента в данном списке.

Что такое бинарный поиск в Python?

Бинарный поиск в Python – это алгоритм поиска определенного элемента в списке. Предположим, у нас есть список из тысяч элементов, и нужно получить индексную позицию определенного элемента. Мы можем очень быстро найти позицию индекса элемента, используя алгоритм двоичного поиска.

Существует множество поисковых алгоритмов, но наиболее популярным среди них является бинарный поиск.

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

Концепция двоичного поиска

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

Принцип «разделяй и властвуй» лежит в основе рекурсивного метода. В нем функция вызывается снова и снова, пока не найдет элемент в списке.

Набор операторов повторяется несколько раз, чтобы найти позицию индекса элемента в итеративном методе. Цикл while используется для выполнения этой задачи.

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

Рассмотрим пошаговую реализацию бинарного поиска.

У нас есть отсортированный список элементов, и мы ищем позицию индекса 45.

[12, 24, 32, 39, 45, 50, 54]

Итак, мы устанавливаем два указателя в нашем списке. Один указатель используется для обозначения меньшего значения, называемого низким, а второй указатель используется для обозначения самого высокого значения, называемого высоким.

Далее мы вычисляем значение среднего элемента в массиве.

Теперь мы сравним искомый элемент со средним значением индекса. В этом случае 32 не равно 45. Поэтому нам нужно провести дальнейшее сравнение, чтобы найти элемент.

Если число, которое мы ищем, равно mid. Затем верните mid, иначе переходите к дальнейшему сравнению.

Число для поиска больше среднего числа, мы сравниваем n со средним элементом элементов справа от mid и устанавливаем low на low = mid + 1.

В противном случае сравните n со средним значением элементов слева от mid и установите high в high = mid – 1.

Повторяйте, пока не будет найден номер, который мы ищем.

Итерационный бинарный поиск в Python

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

Разберемся в следующей программе итерационного метода.

В приведенной выше программе:

Рассмотрим рекурсивный метод двоичного поиска.

Рекурсивный двоичный поиск

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

Вышеупомянутая программа аналогична предыдущей. Мы объявили рекурсивную функцию и ее базовое условие. Условие: наименьшее значение меньше или равно наибольшему значению.

В последней части мы написали нашу основную программу. Это то же самое, что и предыдущая программа, но с той лишь разницей, что мы передали два параметра в функцию binary_search().

Это потому, что мы не можем присвоить начальные значения low, high и mid в рекурсивной функции. Каждый раз, когда вызывается рекурсивный метод, значение этих переменных сбрасывается. Это даст неправильный результат.

Сложность

Сложность алгоритма двоичного поиска в лучшем случае составляет O (1). Это произойдет, если элемент, который мы ищем, найден при первом сравнении. O (logn) – это наихудшая и средняя сложность двоичного поиска, зависит от количества выполняемых поисков, чтобы найти элемент, который мы ищем.

Заключение

Мы обсудили оба метода, чтобы найти позицию индекса данного числа. Алгоритм двоичного поиска – самый эффективный и быстрый способ поиска элемента в списке. Он пропускает ненужное сравнение. Как следует из названия, поиск разделен на две части. Он фокусируется на той стороне списка, которая близка к номеру, который мы ищем.

Источник

Бинарный поиск в Python

В этом уроке мы рассмотрим бинарный поиск в Python, его идею, а также итеративную и рекурсивную реализацию.

Бинарный поиск в Python

Вступление

Бинарный поиск-это эффективный алгоритм поиска, который работает с отсортированными массивами. Он часто используется как один из первых примеров алгоритмов, работающих в логарифмическом времени ( O(logn) ) из-за его интуитивного поведения и является фундаментальным алгоритмом в информатике.

Бинарный поиск – Пример

Бинарный поиск работает по принципу “разделяй и властвуй” и опирается на то, что массив сортируется так, чтобы исключить половину возможных кандидатов на каждой итерации. Более конкретно, он сравнивает средний элемент отсортированного массива с элементом, который он ищет, чтобы решить, где продолжить поиск.

Если целевой элемент больше среднего элемента – он не может быть расположен в первой половине коллекции, поэтому он отбрасывается. То же самое происходит и наоборот.

Примечание: Если массив имеет четное число элементов, то не имеет значения, с какого из двух “средних” элементов мы начнем.

Давайте быстро рассмотрим пример, прежде чем мы продолжим объяснять, как работает бинарный поиск:

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

Если быть более точным, то количество элементов, которые нам нужно проверить в худшем случае, равно log 2 N где N – количество элементов в массиве.

Это оказывает тем большее влияние, чем больше массив:

Однако, если бы в нашем массиве было 10 000 000 элементов, нам нужно было бы проверить только 24 элемента. Это 0,0002%.

Реализация Бинарного Поиска

Двоичный поиск-это естественно рекурсивный алгоритм, поскольку один и тот же процесс повторяется на все меньших и меньших массивах до тех пор, пока не будет найден массив размером 1. Однако, конечно, существует и итеративная реализация, и мы покажем оба подхода.

Рекурсивный

Давайте начнем с рекурсивной реализации, так как это более естественно:

Давайте подробнее рассмотрим этот код. Мы выходим из рекурсии, если элемент start выше элемента end :

Это происходит потому, что такая ситуация возникает только тогда, когда элемент не существует в массиве. В результате мы получаем только один элемент в текущем суб-массиве, и этот элемент не совпадает с тем, который мы ищем.

Мы могли бы сделать это, используя другой подход:

Остальная часть кода выполняет логику “проверить средний элемент, продолжить поиск в соответствующей половине массива”. Мы находим индекс среднего элемента и проверяем, соответствует ли ему искомый элемент:

Если это не так, мы проверяем, является ли элемент меньше или больше среднего элемента:

Давайте продолжим и запустим этот алгоритм с небольшой модификацией, чтобы он распечатал, над каким подмассивом он работает в данный момент:

Запуск этого кода приведет к:

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

И просто для удовольствия мы можем попробовать поискать некоторые большие массивы и посмотреть, сколько шагов требуется двоичному поиску, чтобы выяснить, существует ли число:

Повторяющийся

Итеративный подход очень прост и похож на рекурсивный. Здесь мы просто выполняем проверки в цикле while :

Давайте заполняем массив и ищем в нем элемент:

Запуск этого кода дает нам результат:

Вывод

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

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

Если мы сортируем массив и ищем элемент только один раз, то более эффективно просто выполнить линейный поиск по несортированному массиву.

Источник

Бинарный поиск в Python: визуальное введение

Добро пожаловать

В этой статье вы узнаете, как двоичный поиск алгоритм работает за кулисами и как вы можете реализовать его в Python.

В частности, вы узнаете:

🔹 Введение в двоичный поиск

Этот алгоритм используется для поиска элемента в упорядоченной последовательности (например: список, кортеж или строка).

Требования

Чтобы применить алгоритм двоичного поиска в последовательность, последовательность уже должна сортироваться в порядке возрастания. В противном случае алгоритм не найдет правильный ответ. Если это будет, это будет чистым совпадением.

💡 Совет: Вы можете отсортировать последовательность перед применением двоичного поиска со сортировочным алгоритмом, который соответствует вашим потребностям.

Ввод и вывод

Алгоритм (реализован как функция) нуждается в этих данных:

Эффективность

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

Давайте начнем погрузиться в этот алгоритм.

🔸 Визуальный прохождение

Мы применим алгоритм двоичного поиска в этот список:

💡 Совет: Обратите внимание, что список уже отсортирован. Он включал в себя индексы как визуальную ссылку.

Мы хотим найти индекс целого числа 67 Отказ

Интервал

Давайте притворяться, что мы – алгоритм. Как мы начинаем процесс?

Начнем с выбора двух границ интервала, где мы хотим искать. Мы хотим искать весь список, поэтому мы выбираем индекс 0 как нижняя граница и индекс 5 как верхняя граница:

Средний элемент

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

В этом случае (0 + 5)//2 это 2 потому что результат 5/2 это 2.5 И целочисленное разделение усекает десятичную часть.

Таким образом, средний элемент расположен в Индекс 2 и средний элемент – это число 6 :

Сравнение

Теперь нам нужно начать сравнивать средний элемент с нашим целевым элементом, чтобы увидеть, что нам нужно сделать дальше.

Просим: Средний элемент равен элементу, который мы ищем?

Итак, мы спрашиваем: Это средний элемент больше, чем элемент, который мы ищем?

Итак, Средний элемент меньше элемента, который мы ищем.

Откажитесь от элементов

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

Начните снова – выберите границы

Что мы делаем дальше? Мы отбросили элементы, и цикл повторяется снова.

Мы должны выбрать границы для нового интервала (см. Ниже). Но обратите внимание, что верхняя граница сохраняется неповрежденная, и изменяется только нижняя граница.

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

💡 Совет: Если средний элемент был больше элемента, который мы ищем, верхняя граница была бы изменена, и нижняя граница была бы не повреждена. Таким образом, мы бы отказались от верхней половины списка и продолжайте поиск в нижней половине.

Средний элемент

Теперь нам нужно найти индекс среднего элемента, добавляя нижнюю границу на верхнюю границу и делением результата на 2 с использованием целочисленного деления.

Результат (3 + 5)//2 это 4 Таким образом, средний элемент расположен в индекс 4 и средний элемент – 67 Отказ

Сравнение

Просим: Средний элемент равен элементу, который мы ищем?

Да, это! Итак, мы нашли элемент при индексе 4 Отказ Возвращается значение 4, и алгоритм был успешно завершен.

💡 Совет: Если элемент не был найден, процесс продолжил бы продолжил до тех пор, пока интервал больше не был действительным. Если элемент не был найден во всем списке, – был бы возвращен.

🔹 Код прохождения

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

Заголовок

Здесь у нас есть заголовок функции:

Требуется два аргумента:

Начальный интервал

Следующая строка устанавливает начальные нижние и верхние границы:

Начальная нижняя граница – индекс 0 И начальная верхняя граница является последним показателем последовательности.

Петля

Мы повторим процесс, пока существует допустимый интервал, а нижняя граница меньше или равно верхней границе.

💡 Совет: Помните, что границы являются индексами.

Средний элемент

На каждой итерации нам нужно найти индекс среднего элемента. Для этого мы добавляем нижние и верхние границы и разделите результат на 2 с использованием целочисленного деления.

💡 Совет: Мы используем целочисленное отделение в случае, если список или интервал содержит даже количество элементов. Например, если у списка было 6 элементов, и мы не использовали целочисленное разделение, Средний будет результатом (0 + 5)/2 который является 2.5 Отказ Индекс не может быть поплавка, поэтому мы обрезаем десятичную часть, используя // и выберите элемент по индексу 2 Отказ

Сравнение

С этими условными условиями (см. Ниже), мы определяем, что делать в зависимости от значения среднего элемента Данные [середина] Отказ Мы сравниваем его с целевым элементом, который мы ищем.

Элемент не найден

И у нас есть окончательная реализация двоичного алгоритма поиска:

🔸 особые случаи

Это некоторые конкретные случаи, которые вы можете найти, как вы начинаете работать с этим алгоритмом:

Повторные элементы

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

Элемент не найден

Пустая последовательность

Недоставленная последовательность

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

Этот пример возвращает правильный результат:

💡 Совет: Подумайте, почему первый пример возвращает правильный результат. Подсказка: это чистое совпадение о том, что порядок элементов происходит, чтобы воплотить алгоритм достичь правильного индекса, но пошаговый процесс оценивает 0 Тогда 2 и, наконец, 6 Отказ В этом конкретном случае для этого конкретного элемента правильный индекс найден, даже если последовательность не отсортирована.

🔹 более сложный пример

Теперь, когда вы более знакомы с алгоритмом и его реализацией Python, здесь у нас есть более сложный пример:

Мы хотим найти индекс элемента 45 В этом списке с помощью двоичного поиска:

Первая итерация

Нижние и верхние границы выбираются:

Выбран средний элемент ( 26 ):

Но средний элемент ( 26 ) не является элементом, который мы ищем, он меньше, чем 45 :

Вторая итерация

Таким образом, мы можем отменить все элементы, которые меньше среднего элемента и выберите новые границы. Новая нижняя граница ( 27 ) – это элемент, расположенный сразу справа от предыдущего среднего элемента:

💡 Совет: Помните, что список уже отсортирован.

Выбран новый средний элемент ( 30 ):

Средний элемент ( 30 ) не является элементом, который мы ищем, он меньше, чем 45 :

Третья итерация

Мы можем отменить элементы, меньшие или равные 30 которые уже не отбрасываются. Нижняя граница обновляется до 32 :

Здесь у нас есть интересный случай: средний элемент является одним из границ текущего интервала, потому что (7 + 8)//2 это 7 Отказ

Средний элемент ( 32 ) не является элементом, который мы ищем ( 45 ), он меньше.

Четвертая итерация

Мы можем отменить элементы, меньшие или равные 32 которые уже не отбрасываются.

Здесь у нас есть еще один очень интересный случай: интервал имеет только один элемент.

Средний элемент – единственный элемент в интервале, потому что (8 + 8)//2 это 8 поэтому индекс среднего элемента – 8 и средний элемент – 45 Отказ

Теперь средний элемент – это элемент, который мы ищем, 45 :

Так что ценность 8 (индекс) возвращается:

🔸 дополнительная практика

Если вы хотите получить дополнительную практику с этим алгоритмом, попробуйте объяснить, как алгоритм работает за кулисами, когда он применяется к этому списку, чтобы найти целое число 90 :

Я действительно надеюсь, тебе понравилась моя статья и обнаружила, что это полезно. Теперь вы можете реализовать алгоритм двоичного поиска в Python. Проверьте мой онлайн курс « Алгоритмы поиска и сортировки Python: практический подход ». Следуй за мной на Twitter Отказ ⭐️.

Источник

Большой информационный справочник
Adblock
detector