[1] FINISH

This commit is contained in:
KuznetsovYuM 2026-05-22 17:25:04 +00:00
parent 152123768c
commit 82e3cba902
3 changed files with 141 additions and 0 deletions

View File

@ -0,0 +1,31 @@
Structure,Mode,Repeat,Insert (sec),Search (sec),Delete (sec)
LinkedList,random,1,4.391112,0.026905,0.012824
LinkedList,random,2,4.845220,0.031560,0.030583
LinkedList,random,3,4.461536,0.030224,0.013461
LinkedList,random,4,4.562402,0.028962,0.014101
LinkedList,random,5,4.491418,0.040197,0.018795
LinkedList,sorted,1,3.728189,0.023831,0.010369
LinkedList,sorted,2,3.681244,0.023794,0.011584
LinkedList,sorted,3,3.710309,0.025346,0.011397
LinkedList,sorted,4,3.687962,0.027130,0.010611
LinkedList,sorted,5,3.713101,0.026431,0.011425
HashTable,random,1,0.056713,0.000387,0.000268
HashTable,random,2,0.053692,0.000412,0.000199
HashTable,random,3,0.053167,0.001272,0.000238
HashTable,random,4,0.059468,0.000414,0.000174
HashTable,random,5,0.052122,0.000918,0.000205
HashTable,sorted,1,0.054478,0.000406,0.000157
HashTable,sorted,2,0.052836,0.000398,0.000190
HashTable,sorted,3,0.052295,0.000410,0.000177
HashTable,sorted,4,0.053164,0.000447,0.000169
HashTable,sorted,5,0.051903,0.000399,0.000179
BST,random,1,0.024767,0.000204,0.000125
BST,random,2,0.025908,0.000222,0.000119
BST,random,3,0.025214,0.000223,0.000113
BST,random,4,0.021233,0.000183,0.000111
BST,random,5,0.022941,0.000277,0.000140
BST,sorted,1,8.967227,0.081463,0.047105
BST,sorted,2,8.873885,0.076518,0.042572
BST,sorted,3,8.827521,0.066650,0.055038
BST,sorted,4,8.722978,0.090392,0.045578
BST,sorted,5,9.053348,0.088699,0.054090
1 Structure Mode Repeat Insert (sec) Search (sec) Delete (sec)
2 LinkedList random 1 4.391112 0.026905 0.012824
3 LinkedList random 2 4.845220 0.031560 0.030583
4 LinkedList random 3 4.461536 0.030224 0.013461
5 LinkedList random 4 4.562402 0.028962 0.014101
6 LinkedList random 5 4.491418 0.040197 0.018795
7 LinkedList sorted 1 3.728189 0.023831 0.010369
8 LinkedList sorted 2 3.681244 0.023794 0.011584
9 LinkedList sorted 3 3.710309 0.025346 0.011397
10 LinkedList sorted 4 3.687962 0.027130 0.010611
11 LinkedList sorted 5 3.713101 0.026431 0.011425
12 HashTable random 1 0.056713 0.000387 0.000268
13 HashTable random 2 0.053692 0.000412 0.000199
14 HashTable random 3 0.053167 0.001272 0.000238
15 HashTable random 4 0.059468 0.000414 0.000174
16 HashTable random 5 0.052122 0.000918 0.000205
17 HashTable sorted 1 0.054478 0.000406 0.000157
18 HashTable sorted 2 0.052836 0.000398 0.000190
19 HashTable sorted 3 0.052295 0.000410 0.000177
20 HashTable sorted 4 0.053164 0.000447 0.000169
21 HashTable sorted 5 0.051903 0.000399 0.000179
22 BST random 1 0.024767 0.000204 0.000125
23 BST random 2 0.025908 0.000222 0.000119
24 BST random 3 0.025214 0.000223 0.000113
25 BST random 4 0.021233 0.000183 0.000111
26 BST random 5 0.022941 0.000277 0.000140
27 BST sorted 1 8.967227 0.081463 0.047105
28 BST sorted 2 8.873885 0.076518 0.042572
29 BST sorted 3 8.827521 0.066650 0.055038
30 BST sorted 4 8.722978 0.090392 0.045578
31 BST sorted 5 9.053348 0.088699 0.054090

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

View File

@ -0,0 +1,110 @@
# Отчёт по лабораторной работе
## «Сравнение производительности структур данных на примере телефонного справочника»
**Выполнил:** студент группы ...
**Цель работы:** реализовать три структуры данных (связный список, хеш-таблицу, двоичное дерево поиска) «с нуля» и экспериментально сравнить их производительность при операциях вставки, поиска и удаления записей телефонного справочника.
---
## 1. Условия эксперимента
- **Количество записей:** \( N = 10\,000 \)
- **Каждая запись:** уникальное имя вида `User_XYZW` и случайный телефон
- **Два режима подачи данных:**
- *Случайный порядок* записи перемешаны
- *Отсортированный порядок* записи идут строго по возрастанию имени
- **Измеряемые операции:**
- Вставка всех \( N \) записей
- Поиск 100 существующих + 10 несуществующих имён
- Удаление 50 случайных существующих записей
- **Повторения:** каждый эксперимент повторён 5 раз, результаты усреднены
- **Инструмент замера:** `time.perf_counter()` (секунды)
Все структуры реализованы вручную на Python без использования встроенных типов (кроме базовых списков для хеш-таблицы). Код находится в файле `phonebook_structures.py`.
---
## 2. Результаты измерений
В таблице приведены **средние значения** времени (в секундах) по 5 запускам.
| Структура | Режим | Вставка (с) | Поиск (с) | Удаление (с) |
|----------------|--------------|-------------|-----------|---------------|
| Связный список | случайный | 4.5503 | 0.0316 | 0.0180 |
| Связный список | отсортир. | 3.7042 | 0.0253 | 0.0111 |
| Хеш-таблица | случайный | 0.0550 | 0.00068 | 0.000217 |
| Хеш-таблица | отсортир. | 0.0529 | 0.00041 | 0.000174 |
| BST (ДДП) | случайный | 0.0240 | 0.000222 | 0.000122 |
| BST (ДДП) | отсортир. | 8.8890 | 0.0807 | 0.0489 |
*Графическое представление результатов приведено на рисунке 1.*
![Сравнение производительности структур данных](performance_comparison.png)
*Рисунок 1 Время выполнения операций для трёх структур в разных режимах подачи данных (логарифмическая шкала по вертикали для наглядности).*
---
## 3. Анализ результатов
### 3.1. Влияние порядка данных на BST
Двоичное дерево поиска при вставке отсортированных данных вырождается в линейный список каждый новый узел становится правым потомком предыдущего. Высота дерева достигает \( N \), и сложность всех операций падает с \( O(\log N) \) до \( O(N) \). Эксперимент ярко это подтверждает:
- **Вставка** на отсортированных данных заняла **8.889 с** это в **370 раз** медленнее, чем на случайных (0.024 с).
- **Поиск** замедлился в **360 раз** (0.0807 с против 0.000222 с).
- **Удаление** замедлилось в **400 раз** (0.0489 с против 0.000122 с).
Такой эффект делает обычное двоичное дерево непригодным для данных, поступающих в упорядоченном виде, если не применять балансировку.
### 3.2. Стабильность хеш-таблицы
Хеш-таблица использует хеш-функцию, которая равномерно распределяет имена по корзинам независимо от их исходного порядка. Поэтому производительность почти не меняется:
- Вставка: ~0.055 с (случайный) и ~0.053 с (отсортированный) разница менее 5%.
- Поиск: 0.00068 с против 0.00041 с небольшие колебания связаны со случайными коллизиями.
- Удаление: также стабильно.
Это соответствует теоретической сложности \( O(1) \) в среднем для всех операций.
### 3.3. Связный список ожидаемо медленный
Линейный поиск и вставка в конец дают сложность \( O(N) \) для всех операций:
- Вставка на случайных данных: **4.55 с** почти в 200 раз медленнее, чем у хеш-таблицы.
- Поиск: **0.0316 с** на два порядка медленнее, чем у BST на случайных данных.
- Отсортированный порядок даёт небольшой выигрыш во вставке (3.7 с), потому что при вставке в конец не нужно сравнивать имена для поиска дубликатов? На самом деле в текущей реализации при вставке всё равно выполняется проход по всем элементам для проверки существования имени, поэтому разница не принципиальна.
Связный список абсолютно не подходит для больших объёмов данных, если нужен частый поиск.
### 3.4. Сравнение удаления
- **Связный список** удаление требует линейного поиска, время ~0.018 с (сопоставимо с поиском).
- **Хеш-таблица** удаление за \( O(1) \) в среднем: ~0.0002 с.
- **BST** на случайных данных очень быстрое удаление (~0.00012 с), но на отсортированных падает до 0.049 с (из-за вырождения).
---
## 4. Выводы и практические рекомендации
На основе полученных результатов можно сформулировать следующие правила выбора структуры данных:
| Если важно... | Рекомендуемая структура |
|------------------------------------------------|---------------------------------------------|
| Максимальная скорость поиска, вставки, удаления и порядок данных заранее неизвестен | **Хеш-таблица** (с хорошей хеш-функцией) |
| Нужно часто выводить данные в отсортированном виде, и данные поступают в случайном порядке | **Сбалансированное дерево** (AVL, красно-чёрное) |
| Данные поступают в отсортированном виде, но нужен отсортированный вывод | **Плохое обычное BST** использовать нельзя только после перемешивания или с балансировкой |
| Объём данных очень мал (< 100 записей) и простота реализации важнее скорости | **Связный список** |
**Конкретные выводы по эксперименту:**
1. **Хеш-таблица** показала стабильно высокую производительность во всех режимах. Это лучший выбор для телефонного справочника, если не требуется выдача записей в алфавитном порядке (в задании `list_all()` сортирует отдельно, что приемлемо).
2. **Двоичное дерево поиска** на случайных данных работает почти так же быстро, как хеш-таблица, но полностью деградирует на отсортированных. Это демонстрирует необходимость использования самобалансирующихся деревьев в реальных приложениях (например, `dict` в Python внутри реализован как хеш-таблица, а `SortedDict` как дерево).
3. **Связный список** непригоден для практического использования при \( N > 1000 \) из-за линейной сложности основных операций.
**Итог:** для телефонного справочника с типичной нагрузкой (много поисков, частые вставки) оптимальной структурой является **хеш-таблица**. Если же требуется постоянно поддерживать данные в отсортированном виде (например, для автодополнения), то следует применять **сбалансированное дерево поиска**.
---
*Дата выполнения эксперимента:* 22 мая 2026 г.
*Файлы результатов:* `experiment_results.csv`, `performance_comparison.png`