Одной из часто встречающихся задач в программировании является построение множества, элементами которого являются значения из очень большого диапазона, поиска в нем и его модификации. Так как диапазон велик, невозможно для каждого из возможных значений хранить в памяти информацию о том, находится ли оно во множестве.
Основной операцией во множестве является поиск значения по ключу. Можно хранить все элементы, находящиеся во множестве в списке или массиве, и просто перебирать их, пока не найдется тот, который нужен, либо будет достигнут конец списка, однако такой способ может оказаться слишком медленным, если размер множества большой, ведь он тратит O(n) на поиск (п - размер множества). Возможным решением для ускорения может стать двоичный поиск, для его применения необходимо, чтобы элементы множества находились в памяти в отсортированном порядке, тогда на каждой итерации поиска отрезок, на котором может находиться искомый ключ будет уменьшаться в 2 раза, значит время поиска составит O(logn) [2].
Однако данные во множестве чаще всего не являются статическими, ключи добавляются и удаляются, структура также должна поддерживать эти операции. Чтобы добавить или удалить ключ в последовательный отсортированный блок памяти, необходимо сдвинуть все ключи, находящиеся после добавляемого/удаляемого ключа в памяти, на одну позицию, что может занять O(n) времени, сделав модификацию множества тяжелой операцией.
Выбирая между хранением ключей в случайном порядке и хранением в отсортированном, мы, по сути, выбираем между вариантом с быстрой (O(logn)) вставкой/удалением, но медленным (O(n)) поиском и вариантом с медленной (O(n)) вставкой/удалением, но быстрым (O(logn)) поиском.
Для решения задачи быстрой вставки/удаления и поиска ключа были созданы деревья поиска. Такие структуры позволяют достигнуть оценки O(logn) для всех необходимых операций и занимают O(n) памяти. Было изобретено множество различных сбалансированных деревьев поиска. В 1989 году Сидель Раймундом (Seidel Raimund) и Цецилия Арагон (Aragon Cecilia) создали декартово дерево, которое также называют дерамидой. Советские ученые Адельсон-Вельский и Ландис в 1962 году изобрели АВЛ-дерево, бинарное дерево, баланс в котором поддерживается за счет того, что разница высот левого и правого поддерева для каждой из вершин не превышает 1. Это свойство АВЛ-дерева делает его высоту примерно равной O(logn). В 1970 году Р Бейер и Э. МакКрейт создали B-дерево, сильно ветвящееся, сбалансированное дерево, которое может содержать несколько ключей в каждой из вершин, тем самым позволяющее уменьшить количество операций чтения с диска. Благодаря этой особенности B-деревья часто используются при построении индексов в базах данных [20]. Сбалансированные деревья поиска используют для решения следующих задач:
1. Так называемая «словарная проблема». Примером такого множества на практике может являться англо-русский словарь, в котором ключ - это слово на английском, а значение это перевод данного слова на русский, также хороший пример - это телефонная книга, где ключом является ФИО человека а значением - его телефонный номер. В программировании словари обычно называются ассоциативными массивами, и они уже реализованы в стандартных библиотеках (map в C++, TreeMap в Java).
2. Структура данных rope, представляющая из себя сбалансированное двоичное дерево. Эта структура для хранения больших строк, которая позволяет совершать многие операции вроде конкатенации, взятия подстроки на строках длины n с асимптотикой порядка O(logn). Эффективность достигается за счет того, что строка хранится в памяти не как массив из символов, а разбита на небольшие части, которые хранятся в узлах дерева rope.
3. Индексы в базах данных основаны на деревьях поиска, одним из наиболее часто используемых является В-дерево. Так как элементы в деревьях расположены в отсортированном порядке, они позволяют не только искать ключи с конкретными значениями, но и, например, искать наименьший ключ со значением больше заданного, или вычислять количество ключей из заданного диапазона.
Данная работа посвящена теоретическому и практическому сравнительному анализу сбалансированных деревьев поиска.
Объект исследования - процесс модификации и поиска во множестве.
Предметом исследования являются декартово дерево, рандомизированное дерево поиска, АВЛ-дерево, splay-дерево, В-дерево.
Целью бакалаврской работы является сравнение эффективности рассматриваемых деревьев поиска на различных задачах, выявление сильных и слабых сторон структур при использовании на практике.
Для достижения поставленной цели необходимо выполнить следующие задачи:
1. Рассмотреть задачи, решаемые с помощью деревьев поиска.
2. Рассмотреть различные деревья поиска.
3. Провести теоретический сравнительный анализ рассматриваемых структур на предмет эффективности.
4. Реализовать рассматриваемые деревья поиска на языке программирования C++.
5. Провести генерирование данных для тестирования деревьев на предмет производительности.
6. Провести тестирование на сгенерированных данных.
7. Осуществить сравнительный анализ деревьев поиска на сгенерированных данных.
Бакалаврская работа состоит из введения, двух глав и заключения.
В первой главе дано описание различных сбалансированных деревьев поиска, приведена асимптотическая оценка их работы.
Вторая глава посвящена тестированию рассмотренных структур на различных задачах и сравнительному анализу на основании результатов тестирования.
В ходе выполнения бакалаврской работы была рассмотрена задача поиска ключа во множестве и модификации этого множества путем добавления/удаления ключей. На протяжении многих лет для решения этой задачи создавались различные структуры данных, большая часть из которых является сбалансированными деревьями поиска. У деревьев поиска есть множество применений на практике, на их основе реализована структура данных ассоциативный массив в различных языках программирования, деревья используются при построении индексов в базах данных. Именно поэтому решение этой задачи очень важно.
Был рассмотрен принцип работы таких структур, как декартово дерево, рандомизированное бинарное дерево поиска, splay-дерево, АВЛ-дерево, B- дерево, позволяющих достаточно эффективно решать задачу поиска во множестве и его модификации, дана асимптотическая оценка сложности операции, производимых в этих деревьях.
После этого, был разработан алгоритм генерации данных для тестирования, затем на полученных данных было проведено тестирование.
Исходя из результатов тестирования был проведен сравнительный анализ рассматриваемых деревьев поиска на различных задачах. На практике, наиболее эффективным показало себя B-дерево. При выборе оптимального значения параметра t данная структура превосходит остальные в производительности.
Однако тестирование также показало, что структуры данных могут по- разному показывать себя на различных задачах относительно друг друга, поэтому при выборе структуры для решения конкретной задачи, всегда нужно проводить тестирование на данных, максимально приближенных к этой задаче, и по результатам этого тестирования совершать выбор.
1. Адельсон-Вельский Г. М., Ландис Е. М. Один алгоритм организации информации // Доклады АН СССР. - 1962. - Т 146, № 2. - С. 263-266. URL: http://www.mathnet.ru/links/20762a931307aefD2c107c3d8f6244b8/dan26964.pdf
2. Алгоритмы. Построение и анализ. Томас Кормен [и др.] - М.: «Вильямс», 2019. - 1328 с.
3. Вирт Н. Алгоритмы и структуры данных. - ДМК Пресс, 2011. - 272 с.
4. Кнут Д. Искусство программирования. Том 3. Сортировка и поиск. - Диалектика-Вильямс, 2019. - 832 с.
5. Левитин А. В. Алгоритмы. Введение в разработку и анализ. - М.: Вильямс, 2006. - 576 с.
6. АВЛ-дерево [Электронный ресурс]. - Режим доступа: https://neerc.ifmo.ru/wiki/index.php'.’titleАВ/ 1-дерево
7. АВЛ-деревья [Электронный ресурс]. - Режим доступа: https://habr.com/ru/post/150732/
8. Декартово дерево [Электронный ресурс]. - Режим доступа: http s: //neerc. ifmo .ru/wiki/index .php ‘.’titled! екартово_дерево
9. Декартово дерево: Часть 1. Описание, операции, применения [Электронный ресурс]. - Режим доступа: https://habr.com/ru/post/101818/
10. Рандомизированное бинарное дерево поиска [Электронный ресурс].
- Режим доступа:
https://neerc.ifmo.ru/wiki/index.php?title=Рандомизированное_бинарное_дерев о_поиска
11. Рандомизированные деревья поиска [Электронный ресурс]. - Режим доступа: https: //habr. com/ru/post/145388/
12. B-дерево [Электронный ресурс]. - Режим доступа: https: //neerc. ifmo .ru/wiki/index.php?title=В-дерево
13. Splay-дерево [Электронный ресурс]. https://neerc.ifmo.ru/wiki/index.php?title=Splay-gepeBO
14. Splay-деревья [Электронный ресурс]. - Режим доступа: https://habr.Com/ru/company/JetBrains-education/blog/210296/
15. Bruce Reed. The height of a random binary search tree, 2003. URL: https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.152.1289&rep=rep1&t ype=pdf
16. Daniel Sleator, Robert Tarjan. Self-Adjusting Binary Search Trees, 1985. URL: http://www.cs.cmu.edu/~sleator/papers/self-adjusting.pdf
17. Martinez Conrado, Roura Salvador. Randomized binary search trees,
1997. URL:
https: //www.researchgate.net/publication/220432012_Randomized_Binary_Search
Trees
18. Raimund Seidel, Cecilia R. Aragon. Randomized Search Trees, 1996. URL: https: //faculty.washington.edu/aragon/pubs/rst96 .pdf
19. Robert Tarjan. Data Structures and Networks Algorithms, 1987. URL: https: //doc.lagout.org/Others/Data%20Structures/Data%20Structures%20and%20 Network%20Algorithms%20%5BTarj an%201987-01-01 %5D.pdf
20. R. Bayer, E. McCreight. Organization and Maintenance of Large Ordered
Indexes, 1970. URL:
https://infolab.usc.edu/csci585/Spring2010/den_ar/indexing.pdf