Экспоненциальный поиск - Exponential search

Экспоненциальный поиск
Учебный классАлгоритм поиска
Структура данныхМножество
Худший случай спектакльО(бревно я)
Лучший случай спектакльО(1)
Средний спектакльО(бревно я)
Худший случай космическая сложностьО(1)

В Информатика, экспоненциальный поиск (также называемый двойной поиск или же скачущий поиск или же Струзик поиск)[1] является алгоритм, сделано Джон Бентли и Эндрю Чи-Чи Яо в 1976 г. для поиска в отсортированных неограниченных / бесконечных списках.[2] Существует множество способов реализовать это, наиболее распространенным из которых является определение диапазона, в котором находится ключ поиска, и выполнение бинарный поиск в этом диапазоне. Это требует О (бревноя) куда я - это позиция ключа поиска в списке, если ключ поиска находится в списке, или позиция, где должен быть ключ поиска, если ключа поиска нет в списке.

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

Алгоритм

Экспоненциальный поиск позволяет выполнять поиск в отсортированном неограниченном списке по заданному входному значению («ключ» поиска). Алгоритм состоит из двух этапов. На первом этапе определяется диапазон, в котором находился бы ключ поиска, если бы он был в списке. На втором этапе по этому диапазону выполняется двоичный поиск. На первом этапе, предполагая, что список отсортирован в порядке возрастания, алгоритм ищет первый показатель степени, j, где значение 2j больше ключа поиска. Это значение, 2j становится верхней границей для двоичного поиска с предыдущей степенью 2, 2j - 1, являющаяся нижней границей двоичного поиска.[3]

// Возвращает позицию ключа в массиве arr длины size.шаблон <typename Т>int exponential_search(Т обр[], int размер, Т ключ){    если (размер == 0) {        возвращаться НЕ НАЙДЕН;    }    int граница = 1;    пока (граница < размер && обр[граница] < ключ) {        граница *= 2;    }    возвращаться binary_search(обр, ключ, граница/2, мин(граница + 1, размер));}

На каждом этапе алгоритм сравнивает значение ключа поиска со значением ключа в текущем индексе поиска. Если элемент в текущем индексе меньше, чем ключ поиска, алгоритм повторяется, переходя к следующему индексу поиска, удваивая его, вычисляя следующую степень двойки.[3] Если элемент в текущем индексе больше, чем ключ поиска, алгоритм теперь знает, что ключ поиска, если он вообще содержится в списке, находится в интервале, образованном предыдущим индексом поиска, 2j - 1, и текущий поисковый индекс, 2j. Затем выполняется двоичный поиск с результатом либо сбоя, если ключ поиска отсутствует в списке, либо положения ключа поиска в списке.

Спектакль

Первый этап алгоритма занимает О(бревноя) время, где я - это индекс, по которому в списке будет находиться ключ поиска. Это связано с тем, что при определении верхней границы для двоичного поиска цикл while выполняется точно раз. Поскольку список отсортирован, после удвоения поискового индекса раз алгоритм будет в поисковом индексе, который больше или равен я в качестве . Таким образом, первый этап алгоритма занимает О(бревноя) время.

Вторая часть алгоритма также занимает О(бревноя) время. Поскольку второй этап - это просто двоичный поиск, требуется О(бревноп) куда п размер искомого интервала. Размер этого интервала будет 2j - 2j - 1 где, как видно выше, j = журналя. Это означает, что размер искомого интервала равен 2.бревно я - 2бревно я - 1 = 2бревно я - 1. Это дает нам время выполнения журнала (2бревно я - 1) = журнал (я) - 1 = О(бревноя).

Это дает алгоритму общее время выполнения, рассчитанное путем суммирования времени выполнения двух этапов О(бревноя) + О(бревноя) = 2 О(бревноя) = О(бревноя).

Альтернативы

Бентли и Яо предложили несколько вариантов экспоненциального поиска.[2] Эти варианты состоят в выполнении двоичного поиска, в отличие от унарного поиска, при определении верхней границы двоичного поиска на втором этапе алгоритма. Это разбивает первый этап алгоритма на две части, что делает алгоритм в целом трехэтапным. Новый первый этап определяет значение , как и раньше, так что больше ключа поиска и ниже ключа поиска. Ранее, был определен унарным способом путем вычисления следующей степени двойки (т. е. прибавления 1 к j). В варианте предлагается, чтобы вместо этого удваивается (например, прыжок с 22 до 24 в отличие от 23). Первый такой, что больше, чем ключ поиска, образует гораздо более грубую верхнюю границу, чем раньше. Однажды это найден, алгоритм переходит ко второму этапу, и выполняется двоичный поиск на интервале, образованном и , что дает более точный показатель степени верхней границы j. Отсюда третий этап алгоритма выполняет двоичный поиск на интервале 2j - 1 и 2j, как прежде. Производительность этого варианта = О(бревноя).

Бентли и Яо обобщают этот вариант в одном, где любое число, k, бинарных поисков выполняются на первом этапе алгоритма, что дает k-вложенный вариант двоичного поиска. Асимптотическое время выполнения не меняется для вариантов, работающих в О(бревноя) времени, как и в исходном алгоритме экспоненциального поиска.

Кроме того, структура данных с плотной версией динамическое свойство пальца может быть дан, когда приведенный выше результат k-вложенный двоичный поиск используется в отсортированном массиве.[4] Используя это, количество сравнений, сделанных во время поиска, составляет log (d) + журнал журнал (d) + ... + О(бревно*d), куда d это разница в ранге между последним элементом, к которому был осуществлен доступ, и текущим элементом, к которому был осуществлен доступ.

Смотрите также

Рекомендации

  1. ^ Баеза-Йейтс, Рикардо; Сэлинджер, Алехандро (2010), «Алгоритмы быстрого пересечения для отсортированных последовательностей», в Elomaa, Tapio; Маннила, Хейкки; Орпонен, Пекка (ред.), Алгоритмы и приложения: очерки, посвященные Эско Укконену по случаю его 60-летия, Конспект лекций по информатике, 6060, Springer, стр. 45–61, Bibcode:2010LNCS.6060 ... 45B, Дои:10.1007/978-3-642-12476-1_3, ISBN  9783642124754.
  2. ^ а б Бентли, Джон Л.; Яо, Эндрю С. (1976). «Практически оптимальный алгоритм неограниченного поиска». Письма об обработке информации. 5 (3): 82–87. Дои:10.1016/0020-0190(76)90071-5. ISSN  0020-0190.
  3. ^ а б Йонссон, Хокан (19 апреля 2011 г.). «Экспоненциальный двоичный поиск». Получено 2014-03-24.
  4. ^ Андерссон, Арне; Торуп, Миккель (2007). «Динамические упорядоченные множества с экспоненциальными деревьями поиска». Журнал ACM. 54 (3): 13. arXiv:cs / 0210006. Дои:10.1145/1236457.1236460. ISSN  0004-5411.