Изменения

Перейти к: навигация, поиск

Поисковые структуры данных

11 634 байта добавлено, 22:03, 16 января 2019
Тип
'''Поисковая структура данных''' {{---}} любая структура данных реализующая эффективный поиск конкретных элементов множества, например, конкретной записи в базе данных.
ПростейшийПростейшей, наиболее общийобщей, но менее эффективный эффективной поисковой структурой является простая неупорядоченный неупорядоченная последовательная всех элементов. Расположив элементы в такой список, неизбежно возникнет ряд операций, которые потребуют линейного времени, в худшем случае, а также в средней случае. Используемые в реальной жизни поисковые структуры данных позволяют совершать операции более быстро, однако они ограничены запросами некоторого конкретного вида. Кроме того, поскольку стоимость построение таких структур, по крайней мере пропорционально пропорциональна <tex>n</tex>, они окупятсяих построение окупится, даже если поступает лишь несколько запросов.
=== Тип === '''Статическиепоисковые структуры данных''' (англ. ''Offline search structures'' поисковые структуры данных ) предназначены для ответа на запросы на фиксированной базе данных; . '''Динамическиепоисковые структуры''' (англ. ''Online search structures' поисковые структуры ') также позволяют вставки, удаления или модификации элементов между последовательными запросами. В динамическом случае, необходимо также учитывать стоимость изменения структуры данных. Любую динамическую структуру данных можно сделать статической, если запретить вставку и удаление. Также если множество ключей известно, то можно его заранее упорядочить так, чтобы избежать худших случаев в поисках в структурах данных.
=== Время работы ===
=== Сравнение структур данных ===
Сравним эффективность поисковых структур данных для реализации интерфейса [[Упорядоченное множество|упорядоченного множества]]. Время работы методов <tex>Predecessor</tex> и <tex>Successor</tex> совпадает с временем работы <tex>Search</tex>. <tex>n</tex> {{---}} количество хранимых чисел, каждое из которых представляется с помощью <tex>w</tex> битов.
{| class="wikitable"
! colspan="2" | Search
! colspan="2" | Память
! rowspan="2" | Описание
|-
! style="background: #ddffdd;" | Среднее
! style="background: #ffdddd;" | Худшее
! style="background: #ddffdd;" | Среднее
! style="background: #ffdddd;" | Худшее
! style="background: #ddffdd;" | Среднее
! style="background: #ffdddd;" | Худшее
! style="background: #ddffdd;" | Среднее
! style="background: #ffdddd;" | Худшее
|-
! Среднее! Худшее! Среднее! Худшее! Среднее! Худшее! Среднее! Худшееcolspan="9" align="center" | Динамические структуры данных
|-
| Неотсортированный массив
| colspanalign="2center" style="background: #ddffdd;" | <tex>O(1)</tex>| align="center" style="background: #ddffddffdddd;" | <tex>O(1n)</tex>| colspanalign="2center" style="background: #ddffdd;" | <tex>O(1)</tex>| align="center" style="background: #ffdddd;" | <tex>O(n)</tex>
| colspan="2" align="center" style="background: #ffdddd;" | <tex>O(n)</tex>
| colspan="2" align="center" style="background: #ffffdd;" | <tex>O(n)</tex>
| align="center" | Наивная реализация, использующая [[Динамический массив|динамический массив]]. Добавление происходит в конец массива, а для поиска элемента просто проходим по всему массиву.
|-
| Отсортированный массив
| colspan="2" align="center" style="background: #ffffdd;" | <tex>O(\log n)</tex>
| colspan="2" align="center" style="background: #ffffdd;" | <tex>O(n)</tex>
| align="center" | То же самое, но теперь массив отсортирован. Поиск ускоряется за счёт возможности применить [[Целочисленный двоичный поиск|двоичный поиск]]. Вставка замедляется из-за необходимости поддерживать инвариант отсортированности.
|-
| Неотсортированный [[Список|список]]
| colspan="2" align="center" style="background: #ddffdd;" | <tex>O(1)</tex>
| colspan="2" align="center" style="background: #ffddddddffdd;" | <tex>O(n1)</tex>
| colspan="2" align="center" style="background: #ffdddd;" | <tex>O(n)</tex>
| colspan="2" align="center" style="background: #ffffdd;" | <tex>O(n)</tex>
| align="center" rowspan="2" | Аналогично массиву, но храним данные в [[Список|списке]].
|-
| Отсортированный [[Список|список]]
| colspan="2" align="center" style="background: #ffdddd;" | <tex>O(n)</tex>
| colspan="2" align="center" style="background: #ffddddddffdd;" | <tex>O(n1)</tex>
| colspan="2" align="center" style="background: #ffdddd;" | <tex>O(n)</tex>
| colspan="2" align="center" style="background: #ffffdd;" | <tex>O(n)</tex>
| align="center" style="background: #ffdddd;" | <tex>O(n)</tex>
| colspan="2" align="center" style="background: #ffffdd;" | <tex>O(n)</tex>
| align="center" | Бинарное дерево поиска обладает следующим свойством: если <tex>x</tex> {{---}} узел бинарного дерева с ключом <tex>k</tex>, то все узлы в левом поддереве должны иметь ключи, меньшие <tex>k</tex>, а в правом поддереве большие <tex>k</tex>.
|-
| [[Рандомизированное бинарное дерево поиска]]
| align="center" style="background: #ffffdd;" | <tex>O(\log n)</tex>
| align="center" style="background: #ffdddd;" | <tex>O(n)</tex>
| align="center" style="background: #ffffdd;" | <tex>O(\log n)</tex>
| align="center" style="background: #ffdddd;" | <tex>O(n)</tex>
| align="center" style="background: #ffffdd;" | <tex>O(\log n)</tex>
| align="center" style="background: #ffdddd;" | <tex>O(n)</tex>
| colspan="2" align="center" style="background: #ffffdd;" | <tex>O(n)</tex>
| align="center" | Вариант [[Дерево поиска, наивная реализация|двоичного дерево поиска]] с добавлением инвариата "случайности", что уменьнашает ожидаемую высоту дерева.
|-
|[[АВЛ-дерево]]
| colspan="2" align="center" style="background: #ffffdd;" | <tex>O(\log n)</tex>
| colspan="2" align="center" style="background: #ffffdd;" | <tex>O(n)</tex>
| align="center" | Сбалансированное [[Дерево поиска, наивная реализация|двоичное дерево поиска]], в котором поддерживается следующее свойство: для каждой его вершины высота её двух поддеревьев различается не более чем на <tex>1</tex>.
|-
|[[2-3 дерево]]
| colspan="2" align="center" style="background: #ffffdd;" | <tex>O(\log n)</tex>
| colspan="2" align="center" style="background: #ffffdd;" | <tex>O(n)</tex>
| align="center" | Структура данных, представляющая собой сбалансированное дерево поиска, такое что из каждого узла может выходить две или три ветви и глубина всех листьев одинакова. Является частным случаем [[B-дерево#B.2B-.D0.B4.D0.B5.D1.80.D0.B5.D0.B2.D0.BE|B+ дерева]].
|-
|[[B-дерево]]
| colspan="2" align="center" style="background: #ffffdd;" | <tex>O(\log n)</tex>
| colspan="2" align="center" style="background: #ffffdd;" | <tex>O(n)</tex>
| align="center" | Cильноветвящееся сбалансированное дерево поиска, позволяющее проводить поиск, добавление и удаление элементов за <tex>O(\log n)</tex>. B-дерево с <tex>n</tex> узлами имеет высоту <tex>O(\log n)</tex>. Количество детей узлов может быть от нескольких до тысяч (обычно степень ветвления B-дерева определяется характеристиками устройства (дисков), на котором производится работа с деревом). В-деревья также могут использоваться для реализации многих операций над динамическими множествами за время <tex>O(\log n)</tex>
|-
|[[Красно-черное дерево]]
| colspan="2" align="center" style="background: #ffffdd;" | <tex>O(\log n)</tex>
| colspan="2" align="center" style="background: #ffffdd;" | <tex>O(n)</tex>
| align="center" | Сбалансированное [[Дерево поиска, наивная реализация|двоичное дерево поиска]], в котором баланс осуществляется на основе "цвета" узла дерева, который принимает только два значения: "красный" (англ. ''red'') и "чёрный" (англ. ''black''). При этом все листья дерева являются фиктивными и не содержат данных, но относятся к дереву и являются чёрными.
|-
| [[Декартово дерево]]
| align="center" style="background: #ffdddd;" | <tex>O(n)</tex>
| colspan="2" align="center" style="background: #ffffdd;" | <tex>O(n)</tex>
| align="center" | Бинарное дерево, в узлах которого хранится пары <tex> (x,y) </tex>, где <tex>x</tex> {{---}} это ключ, а <tex>y</tex> {{---}} это приоритет. Также оно является [[Дерево поиска, наивная реализация|двоичным деревом поиска]] по <tex>x</tex> и [[Двоичная куча|пирамидой]] по <tex>y</tex>. Предполагая, что все <tex>x</tex> и все <tex>y</tex> являются различными, получаем, что если некоторый элемент дерева содержит <tex>(x_0,y_0)</tex>, то у всех элементов в левом поддереве <tex>x < x_0</tex>, у всех элементов в правом поддереве <tex> x > x_0</tex>, а также и в левом, и в правом поддереве имеем: <tex> y < y_0</tex>.
|-
|[[Splay-дерево]]
| colspan="2" align="center" style="background: #ffffdd;" | <tex>O(\log n)</tex>| colspan="2" align="center" style="background: #ffffddffdddd;" | <tex>O(\log n)</tex>| colspan="2" align="center" style="background: #ffffdd;" | <tex>O(\log n)</tex>| colspan="2" align="center" style="background: #ffffddffdddd;" | <tex>O(n)</tex>|-|[[Tango-дерево]]| colspan="2" align="center" style="background: #ddffddffffdd;" | <tex>O(\log \log n)</tex>| colspan="2" align="center" style="background: #ddffddffdddd;" | <tex>O(\log \log n)</tex>| colspan="2" align="center" style="background: #ddffdd;" | <tex>O(\log \log n)</tex>
| colspan="2" align="center" style="background: #ffffdd;" | <tex>O(n)</tex>
| align="center" | [[Дерево поиска, наивная реализация|Двоичное дерево поиска]]. Оно позволяет находить быстрее те данные, которые использовались недавно, за счёт '''перемещения к корню''' (англ. ''Move to root''). Относится к разряду сливаемых деревьев. Сплей-дерево было придумано Робертом Тарьяном и Даниелем Слейтером в 1983 году.
|-
|[[Дерево ван Эмде Боаса]]
| colspan="2" align="center" style="background: #ffffdd;" | <tex>O(\log kw)</tex>| colspan="2" align="center" style="background: #ffffdd;" | <tex>O(\log kw)</tex>| colspan="2" align="center" style="background: #ffffdd;" | <tex>O(\log kw)</tex>| colspan="2" align="center" style="background: #ffdddd;" | <tex>O(2^kw)</tex>| align="center" | Cтруктура данных, представляющая собой [[Дерево поиска, наивная реализация|дерево поиска]], позволяющее хранить целые неотрицательные числа в интервале <tex>[0;2^w)</tex> и осуществлять над ними все соответствующие дереву поиска операции. Проще говоря, данная структура позволяет хранить <tex>w</tex>-битные числа.Особенностью этой структуры является то, что все операции выполняются за <tex>O(\log w)</tex>, что асимптотически лучше, чем <tex>O(\log n)</tex> в большинстве других деревьев поиска, где <tex>n</tex> {{---}} количество элементов в дереве.
|-
| [[Список с пропусками]]
| align="center" style="background: #ffffdd;" | <tex>O(\log n)</tex>
| align="center" style="background: #ffdddd;" | <tex>O(n)</tex>
| colspan="2" align="center" style="background: #ffffdd;" | <tex>O(n)</tex> | align="center" style="background: #ffdddd;" | Вероятностная структура данных, основанная на нескольких отсортированных односвязных списках.Отсортированный связный список является простейшей структурой с временем поиска <tex>O\Theta(n )</tex>. Добавление дополнительных уровней, обеспечивающих быстрый доступ через несколько элементов, помогает улучшить асимптотику до <tex>\Theta(\log (n))</tex>
|-
|[[Fusion tree]]
| colspan="2" align="center" style="background: #ffffdd;" | <tex>O(\log_{w} n)</tex>
| colspan="2" align="center" style="background: #ffffdd;" | <tex>O(n)</tex>
| align="center" | Дерево поиска, позволяющее хранить <tex>n</tex> <tex>w</tex>-битных чисел, используя <tex>O(n)</tex> памяти, и выполнять операции поиска за время <tex>O(\log_{w} n)</tex>. Эта структура данных была впервые предложена в 1990 году М. Фредманом (M. Fredman) и Д. Уиллардом (D. Willard).
|-
| [[Сверхбыстрый цифровой бор|Цифровой бор]]
| colspan="2" align="center" style="background: #ffdddd;" | <tex>O(w)</tex>
| colspan="2" align="center" style="background: #ffdddd;" | <tex>O(w)</tex>
| colspan="2" align="center" style="background: #ffdddd;" | <tex>O(w)</tex>
| colspan="2" align="center" style="background: #ffdddd;" | <tex>O(n \cdot w)</tex>
| align="center" | [[Бор]], в котором в качестве строк используются двоичные записи чисел, включая ведущие нули. Таким образом он имеет глубину <tex>w</tex>.
|-
| [[Сверхбыстрый цифровой бор|Быстрый цифровой бор]]
| colspan="2" align="center" style="background: #ffdddd;" | <tex>O(w)</tex>
| colspan="2" align="center" style="background: #ffdddd;" | <tex>O(w)</tex>
| colspan="2" align="center" style="background: #ffffdd;" | <tex>O(\log w)</tex>
| colspan="2" align="center" style="background: #ffdddd;" | <tex>O(n \cdot w)</tex>
| align="center" | Улучшеная версия структуры цифрового бора.
|-
|[[Сверхбыстрый цифровой бор]]| align="center" style="background: #ffffdd;" | <tex>O(\log w)</tex>| align="center" style="background: #ffdddd;" | <tex>O(w)</tex>
| align="center" style="background: #ffffdd;" | <tex>O(\log w)</tex>
| align="center" style="background: #ffdddd;" | <tex>O(w)</tex>
| align="center" style="background: #ffffdd;" | <tex>O(\log w)</tex>
| align="center" style="background: #ffdddd;" | <tex>O(w)</tex>
| colspan="2" align="center" style="background: #ffffdd;" | <tex>O(\log w)</tex>
| colspan="2" align="center" style="background: #ffffdd;" | <tex>O(n)</tex>
| align="center" | Улучшеная версия структуры быстрого цифрового бора.
|-
!
! colspan="9" align="center" | Статические структуры данных
|-
|[[Tango-дерево]]
| colspan="2" align="center" style="background: #e5e5e5;" | -
| colspan="2" align="center" style="background: #e5e5e5;" | -
| colspan="2" align="center" style="background: #ddffdd;" | <tex>O(\log \log n)</tex>
| colspan="2" align="center" style="background: #ffffdd;" | <tex>O(n)</tex>
| align="center" | [[Дерево поиска, наивная реализация|Двоичное дерево поиска]], которое изобрели Эрик Д. Демейн, Дион Хармон, Джон Яконо и Михаи Патраску в 2004 году. Не поддерживает операции вставки и удаления, но перестраивается по ходу поисковых запросов, чтобы отвечать на них как можно оптимальней. Это лучшая известная реализация на данный момент.
|}
==См. Такжетакже==
*[[:Сортировка|Сортировка]]*[[:Приоритетные_кучи|Поиск подстроки в строке]]*[[Приоритетные кучиочереди]]
== Источники информации ==
* [[wikipedia:en:Search_data_structure|Wikidedia {{---}} Search data structure]]
* [http://habrahabr.ru/post/188010/ Habrahabr {{---}} Знай сложности алгоритмов ]
[[Категория: Дискретная математика и алгоритмы]]
[[Категория: Деревья поиска]]
[[Категория: Структуры данных]]
Анонимный участник

Навигация