Существует множество способов реализации List
.В стандартных библиотеках Java есть ArrayList
, LinkedList
, CopyOnWriteArrayList
и т. Д., А также множество других реализаций, помимо этих ( VLists , циклические буферы, асимметричные списки биномов, расширяемые массивы, 2-3 пальца и т. Д.).Идея обеспечения бинарного поиска заключается в том, что, хотя не все реализации List поддерживают произвольный доступ, тем, кому это действительно нужно, было бы полезно иметь общую реализацию бинарного поиска, чтобы авторам каждой структуры данных не приходилось переопределять ее с нуля.Например, если я реализую сумасшедшую новую структуру списка, которая поддерживает произвольный доступ, если я реализую интерфейс List, я могу автоматически получать двоичный поиск, доступный из класса Collections.
Интересно, что метод binarySearch
написантакой, что он смотрит на тип List
и видит, реализует ли он интерфейс RandomAccess
, прежде чем он фактически выполняет бинарный поиск.Если в списке не реализовано RandomAccess
, вместо стандартного двоичного поиска метод использует модифицированный двоичный поиск с итераторами, который гарантированно выполнит не более O (n) итераций и O (log n) сравнений.Идея состоит в том, чтобы отслеживать, где приземлился последний зонд, затем идти вперед или назад на соответствующее количество шагов, чтобы найти следующее местоположение зонда, и т. Д. Тогда полная работа будет не более n / 2 + n / 4 + n/ 8 + n / 16 + ... = 2n, так что в худшем случае это только вдвое хуже, чем при линейном поиске в худшем случае.
Короче говоря, предоставление общей реализации binarySearch
Не всегда можно быстро найти что-то в Списке, но для структур, которые поддерживают быстрый доступ, это может иметь огромное значение и сэкономить много времени для разработчиков.Кроме того, постепенное ухудшение модифицированного бинарного поиска, выполняемого за время O (n), означает, что реализация никогда не будет намного хуже, чем стандартное линейное сканирование.
Это рассуждение аналогичнообоснование разработки алгоритмов C ++, которые работают с общими диапазонами значений.Эффективность этих алгоритмов может быть намного хуже, чем у специализированной версии алгоритма для каждой структуры данных, но наличие общей версии означает, что любые новые контейнеры, поддерживающие итераторы, могут автоматически иметь множество функциональных возможностей, помимо того, чтоуказано в интерфейсе.
Надеюсь, это поможет!