Ортогональный поиск — различия между версиями
(→Сбалансированное дерево поиска) |
(→Сбалансированное дерево поиска) |
||
Строка 28: | Строка 28: | ||
# Для каждого из полученных поддеревьев обратимся к массиву содержащихся в нем точек и запустим от него приведенную выше функцию <tex>range{\_}search(y_{min}, y_{max})</tex>. Все полученные таким образом точки и будут составлять ответ. | # Для каждого из полученных поддеревьев обратимся к массиву содержащихся в нем точек и запустим от него приведенную выше функцию <tex>range{\_}search(y_{min}, y_{max})</tex>. Все полученные таким образом точки и будут составлять ответ. | ||
− | Каждая из функций <tex>range{\_}search(y_{min}, y_{max})</tex> будет работать в худшем случае за <tex>O(\log n)</tex>, отсюда получаем итоговое время выполнения запроса <tex>O(\log^2 n)</tex>. | + | Каждая из функций <tex>range{\_}search(y_{min}, y_{max})</tex> будет работать в худшем случае за <tex>O(\log n)</tex>, отсюда получаем итоговое время выполнения запроса <tex>O(\log^2 n)</tex>. Что касается памяти, то в сбалансированном дереве поиска <tex>O(\log n)</tex> слоев, а каждый слой содержит массивы, содержащие в сумме ровно <tex>n</tex> точек, соответственно вся структура в целом занимает <tex>O(n\log n)</tex> памяти. |
+ | |||
+ | Такую структуру данных можно при необходимости обобщить на случай большей размерности. | ||
== Квадро дерево == | == Квадро дерево == | ||
== Инкрементальное квадро дерево == | == Инкрементальное квадро дерево == |
Версия 16:42, 19 мая 2012
Содержание
Простейший случай
Пусть дана прямая с точками на ней и отрезок. Точки даны в отсортированном порядке. Необходимо указать, какие из изначальных точек лежат на этом отрезке.
Данная задача решается с помощью функций из STL - upper_bound и lower_bound.
upper_bound возвращает наименьшее значение больше данного, lower_bound - наибольшее значение меньше данного.
Рассмотрим на примере:
Код реализации:
template<class RauIter, class OutIter, class Scalar> OutIter range_search(RauIter p, RauIter q, OutIter out) { return std::copy(lower_bound(p, q, l), upper_bound(p, q, r), out); }
Сбалансированное дерево поиска
Переходим к двумерному случаю. Пусть дано некоторое множество точек на плоскости. Нам необходимо ответить, какие именно из них лежат в некотором заданном прямоугольнике.
Для этого возьмем любое сбалансированное дерево поиска и наполним его точками
из множества. В качестве ключа будет использоваться -координата точки. Теперь модернизируем дерево: в каждой вершине дерева будем хранить отсортированный по -координате массив точек, которые содержатся в соответствующем поддереве. В такой структуре данных поиск точек в заданном прямоугольнике будет выглядеть следующим образом:- Выберем из дерева поиска те точки, запрос сверху в дереве отрезков. Из аналогии с деревом отрезков следует, что мы ответ мы получим в виде поддеревьев дерева поиска. -координата которых лежит в интервале . Сделаем это точно так же, как делается
- Для каждого из полученных поддеревьев обратимся к массиву содержащихся в нем точек и запустим от него приведенную выше функцию . Все полученные таким образом точки и будут составлять ответ.
Каждая из функций
будет работать в худшем случае за , отсюда получаем итоговое время выполнения запроса . Что касается памяти, то в сбалансированном дереве поиска слоев, а каждый слой содержит массивы, содержащие в сумме ровно точек, соответственно вся структура в целом занимает памяти.Такую структуру данных можно при необходимости обобщить на случай большей размерности.