52 lines
10 KiB
Markdown
52 lines
10 KiB
Markdown
# Отчет по лабораторной работе "Структуры данных"
|
||
## 1. Введение
|
||
В ходе выполнения лабораторной работы были выполнены реализации трех структур для хранения и обработки данных телефонных номеров:
|
||
- Связный список
|
||
- Хеш-таблица
|
||
- Двоичное дерево поиска.
|
||
|
||
Практическая часть включала в себя такие операции как: добавление или обновление телефонного номера, удаление телефонного номера, поиск владельца телефонного номера и составление списка из кортежей вида (владелец, номер). Каждое выполнение функций проводилось с списоком из кортежей вида (владелецб номер), в котором было 1000 уникальных имен и еще 9000 имен, которые уже были использованны (всего 10000 кортежей). Каждое тестирование структур выполнялось для сортированного и не сортированного начального списка 10 раз.
|
||
## 2. Результаты измерений
|
||
Данные в таблице отражают среднее время в милисекундах выполнения структур.
|
||
| Структура | Начальный список | insert, мс | find, мс | delete, мс | create list, мс |
|
||
| :---: | :---: | ---: | ---: | ---: | ---: |
|
||
| LinkedList | not sorted | 165.61 | 1.767 | 3.418 | 31.795 |
|
||
| LinkedList | sorted | 171.01 | 1.720 | 3.440 | 21.378 |
|
||
| HashTable | not sorted | 17.15 | 0.278 | 0.320 | 48.080 |
|
||
| HashTable | sorted | 17.49 | 0.284 | 0.321 | 47.911 |
|
||
| BST | not sorted | 52.95 | 0.772 | 0.660 | 0.283 |
|
||
| BST | sorted | 162.70 | 1.809 | 1.564 | 1.626 |
|
||
|
||
Изходя из полученных значений можно построить столбчатую диаграмму:
|
||
|
||

|
||
## 3. Анализ полученных данных
|
||
### 3.1 Зависимость скорости работы BST от порядка ввода данных.
|
||
Из полученных данных можно заметить, что для BST порядок ввода сильно сказывается на результате скорости выполнения программы: при послутплении неотсортированных данных программа справляется примерно в 3 раза быстрее. Связано это с тем, что каждое новое значение, при сортированных данных, будет больше предыдущего, а соответственно будет каждый раз создаватся правый лист, из-за чего высота дерева становится равной количесвту всех уникальных имен, вседствии чего сложность возрастает до О(n), а двоичное дерево превращается в своебразный связный список.
|
||
|
||
### 3.2 Независимость скорости выполнения заполнения хеш-таблицы от порядка вводных данных
|
||
Из эксперемента можно заметить, что скорость заполнения хеш-таблицы сортированными и несортированными данными почти одинакова(разница менее 2%). Это объясняется наличием бакетов, которые разбивают все данные на N списков (В данной лабораторной работе N = 100) и не зависмо от способа подачи данных мы всегда получим N списков с одинаков наполнением.
|
||
Скорость выполнения вставки почти одинакова, так как и для случая сортированного и несортированного начального списка необходимо только определить нужный бакет и добавить в этот бакет кортеж (владелец, номер), то есть сложность операции О(1), что отражают результаты эксперемента.
|
||
Скорость выполнения поиска/удаления/составление списка почти одинаковы по тем же причинам: из-за наличия бакетов отрезаем часть лишних данных и уже работаем с оставшимеся, что значительно уменьшает время, а так как длина списока в бакете будет гораздо меньше длины списка исходных данных, что линейная сложность при переборе этого списка не сильно повлияет на время выполнения программы.
|
||
|
||
### 3.3 Медленность посика связного списка
|
||
Чтобы найти нужный элемент в связном списке необходимо перебрать все элементы стоящие до него, и если элемент находится где-то в конце такого списка, то придется перебрать почти все значения, на что уйдет явно больше премени чем при применениеи хеш-таблицы, которая отсекает большую часть ненужных данных, или двоичного дерева, которое составлено так, что не нужно будет перебирать все значения.
|
||
|
||
### 3.4 Принципы работы Удаления
|
||
### - Связный список:
|
||
В связном списке необходимо найти нужный словарь, значение ключа next содержит искомое имя. После этого мы меняем значение ключа next этого словаря на то, которое стоит в значении ключа next словаря, который мы собираемся удалить. Если мы хотим удалить запись, которой не существует, в таком случае перебираем весь связный спискок полностью и в случае ненахождения нужной записи возвращаем исходный список.
|
||
|
||
### - Хеш-таблица:
|
||
В начале ищем номер нужного бакета, и начинаем искать в бакете необходую запись: перебираем список кортежей, пока не найдем нужную запись. Если запись нашлась, то удалем ее и списка, если нет, то возвращаем исходные данные без изменений
|
||
|
||
### - Двоичное дерево посика:
|
||
Сначала ищем узел, который необходимо удалить, а затем действуем в зависимости от ситуации:
|
||
- 1) У узла нет потомков:
|
||
В такой ситуации просто удаляем наш узел(в данном случае лист)
|
||
- 2) У узла нет потомков справа или слева:
|
||
Если у узла есть только правые потомки, то на место этого узела помещаем узел, который расположен справа. Аналогично для случая с наличием левых потомков.
|
||
- 3) Если у узла есть и правые и левые потомки:
|
||
Находим самый маленький узел в правом поддереве этого узла, то есть идем сначала вправо от узла, а потом только влево, пока не дойдем до значения None.
|
||
Копируем значения этого наименьшего и подставляем эти данные в узел, который хотим удалить, не меняя значения под ключами left и right, а затем удаляем этот наименьший как описано в пунктах (1) и (2), так как этот узел или будет иметь только потомков вправа или не иметь их вообще
|
||
|
||
## Вывод: в ходе выполнения лабораторной были изучены 3 способа хранения и обработки данных. Из данных полученных из эксперементов можно выделить наилучшие способы применения этих структур. Если в программе необходимо часто пополнять данные, корректировать, искать и удалять их, то лучше всего подойдет хеш-таблица. Если необходимо часто собирать все данные в один сортированный список и исходные данные несортированные, то хеш-таблица будет тормозить, в этом случае лучше использовать двоичное дерего поиска, хоть они и показывают более худший результат в добавлении, посике и удалении(примерно в 2.5-3 раза), но формируют список они моментально: 0.283 мс. Если же исходные данные отсортированны и необходимо выполнять все те же операции но без удаления, то в таком случае наиболее эффективным будет связный список. |