forked from UNN/2026-rff_mp
Compare commits
140 Commits
8fb5738b50
...
053e635cda
| Author | SHA1 | Date | |
|---|---|---|---|
| 053e635cda | |||
| 0d86929b62 | |||
| 8124ef4551 | |||
| 8744999b03 | |||
| 01f0e5dd88 | |||
|
|
0c990ece48 | ||
|
|
9af52f3f7b | ||
|
|
9e70450c50 | ||
|
|
a7323e3762 | ||
| 7fe5c11997 | |||
| 969b9ee469 | |||
| 0c6a8bd4db | |||
| b849e3a7bc | |||
| 2e0eec1543 | |||
| 17fc44d83e | |||
| 4b24d66ab7 | |||
|
|
48d37c6f77 | ||
| 4a26e7aa89 | |||
| e0eb3ae13a | |||
| f983a6fa1d | |||
|
|
356e4b53dd | ||
| b7cea24df4 | |||
| 8221562750 | |||
| 789d8ef3bb | |||
|
|
6e433a36ae | ||
| a50fd0bfc1 | |||
|
|
de2b98bc01 | ||
| c53b093c38 | |||
| dd3b126d62 | |||
| 048b211945 | |||
| 6d05295507 | |||
| 55d8ed29c6 | |||
| af2d62a446 | |||
| fe5a8bea89 | |||
| b4b3140603 | |||
|
|
90503c7b92 | ||
|
|
bcde039ddd | ||
| ddc6d9b877 | |||
| e1e08990e0 | |||
|
|
fe50036baf | ||
|
|
8f2e46907f | ||
|
|
afa3504609 | ||
|
|
ccb7c7a5da | ||
|
|
6ef4820d9e | ||
| c3131ce0f6 | |||
| 8a523c9afb | |||
| e8ea43f9b3 | |||
|
|
57c8ef048f | ||
| c774f9182a | |||
| 194d822b62 | |||
|
|
589787851b | ||
| b34b2b76c8 | |||
| 46f73eaa47 | |||
| 5eab591f1a | |||
| 768a06fbb6 | |||
| 141bb2bbb5 | |||
| f7b4f75488 | |||
| 802b72d10b | |||
| 0cd1012949 | |||
| 6b2f019b11 | |||
| 5964cc81ab | |||
| 9f395a7b9a | |||
| 362b487266 | |||
| 8a4eb2ab7b | |||
| cc5764f86a | |||
| c276d52949 | |||
| a40c5f579a | |||
| 2ea1b50bc7 | |||
| d5450e0063 | |||
| b35fa6725b | |||
| de62717491 | |||
| 902ad5ef53 | |||
|
|
343a06519a | ||
| a2621ad508 | |||
| 95f3cd28df | |||
| 57adafbebd | |||
|
|
b881e05410 | ||
| d33fd62603 | |||
| e5733fd15d | |||
| 8dff4985b9 | |||
| 0f92398229 | |||
| 8c3a030957 | |||
| 6c0751dc68 | |||
| 5f779a102c | |||
| ad692ac5b8 | |||
| b4daf9ea72 | |||
| 71cb098a69 | |||
| c46e1aa8e2 | |||
| 595a3518d9 | |||
|
|
b98c87e4d5 | ||
|
|
41ad3771e8 | ||
|
|
de77a1109d | ||
| a0653117cd | |||
| 4428a8e88d | |||
| 41ce5b60cf | |||
| 195de5c70f | |||
| 60ecbdb35d | |||
|
|
3eab4cc3aa | ||
| 73cad3b59f | |||
| 1de0cee11d | |||
| 306299755c | |||
| 5dcd06963c | |||
| 65fea33bd4 | |||
|
|
ee26f74767 | ||
| 7000ccc96c | |||
|
|
7db86ec769 | ||
|
|
bef613db62 | ||
| a3c03ab3b4 | |||
| aadad1272e | |||
| 0c578f46e5 | |||
| b168cd4f7b | |||
| 391d8a79d1 | |||
|
|
ee723b700c | ||
| 87996f3d85 | |||
| 2a6f10cbf9 | |||
|
|
f2d51f5bc5 | ||
|
|
cb7dfdcf0d | ||
|
|
288f562fa0 | ||
|
|
ed603fc6dd | ||
| 27e1e98bf4 | |||
| 487ff6d741 | |||
| 9ad53dbe15 | |||
| fd82609af4 | |||
|
|
0ff7405de9 | ||
| 2e2a48fd30 | |||
|
|
34872ab84e | ||
| 3694f25de8 | |||
| b16d1f6731 | |||
| 9f68a759d8 | |||
| ca2a7eb3b6 | |||
| 7fec6872a1 | |||
|
|
fb021ba018 | ||
|
|
1d508ceb9b | ||
| 914063a196 | |||
|
|
f6a224a94a | ||
|
|
41acf4dab2 | ||
| b5469155fa | |||
| f15908a49d | |||
| 7c9c594771 | |||
| aca0eb0c84 |
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -7,6 +7,7 @@ __pycache__/
|
|||
# C extensions
|
||||
*.so
|
||||
|
||||
.DS_Store
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
build/
|
||||
|
|
|
|||
0
BudakovIS/428.md
Normal file
0
BudakovIS/428.md
Normal file
0
DerbenevRY/428.md
Normal file
0
DerbenevRY/428.md
Normal file
1
KuzminskiyAA/427.md
Normal file
1
KuzminskiyAA/427.md
Normal file
|
|
@ -0,0 +1 @@
|
|||
|
||||
0
KuznetsovAS/427.md
Normal file
0
KuznetsovAS/427.md
Normal file
0
MashinDD/429.txt
Normal file
0
MashinDD/429.txt
Normal file
1
MininaVD/427.txt
Normal file
1
MininaVD/427.txt
Normal file
|
|
@ -0,0 +1 @@
|
|||
427.txt
|
||||
1
MininaVD/MininaVD
Normal file
1
MininaVD/MininaVD
Normal file
|
|
@ -0,0 +1 @@
|
|||
427.txt
|
||||
0
MusinAA/428b.md
Normal file
0
MusinAA/428b.md
Normal file
1
MylnikovAS/427.md
Normal file
1
MylnikovAS/427.md
Normal file
|
|
@ -0,0 +1 @@
|
|||
|
||||
BIN
ProninVV/427.md
Normal file
BIN
ProninVV/427.md
Normal file
Binary file not shown.
BIN
ProninVV/file.txt
Normal file
BIN
ProninVV/file.txt
Normal file
Binary file not shown.
149
README.md
149
README.md
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
### Крайний срок приема работ 25.05.2026 до 14:00
|
||||
|
||||
## Задание 1 -- репозиторий
|
||||
## Задание 0 -- репозиторий [отдельный срок на создание PR с папкой: 28.02.2026]
|
||||
|
||||
0. Создай пользователя (логин — фамилия+инициалы слитно транслитом, как в терминал-классе).
|
||||
|
||||
|
|
@ -43,12 +43,157 @@
|
|||
|
||||
6. Отправь ветку **в свой форк** на Gitea:
|
||||
```bash
|
||||
git push origin IvanovII
|
||||
git push origin
|
||||
```
|
||||
|
||||
если просит, перед этим сделать git push --set-upstream origin
|
||||
|
||||
7. **Создай запрос на слияние (Pull Request):** На Gitea перейди в свой форк, выбери ветку `IvanovII`, нажмите **Запрос на слияние**. Убедитесь, что:
|
||||
- Базовый репозиторий: **учебный** (преподавателя)
|
||||
- Базовая ветка: **develop**
|
||||
- Сравниваемая ветка: **свой форк / IvanovII**
|
||||
|
||||
8. Отправь PR.
|
||||
|
||||
## Задание 1 -- структуры данных
|
||||
***Напоминание: под каждое задание вы создаете отдельную ветку***
|
||||
|
||||
>Для оформления результатов заведи папку **docs** в своей папке и сохраняй туда отчет (в любом формате от .doc до .md, а то и .jpnb). Вспомогательные файлы клади в подпапку **data** внутри **docs**
|
||||
|
||||
**Цель работы**
|
||||
|
||||
Реализовать три различные структуры данных «с нуля», применить их для хранения записей телефонного справочника и экспериментально сравнить производительность основных операций. Вы должны собственными руками написать код, чтобы понять внутреннее устройство связного списка, хеш-таблицы и двоичного дерева поиска, а также осознать их сильные и слабые стороны на практике.
|
||||
|
||||
**!! Задание выполнять в структурной (процедурной) парадигме, не используя классы. Главное реализовать структуры данных «руками» и сравнить их производительность.**
|
||||
|
||||
### Базовые операции (обязательны для всех):
|
||||
|
||||
`insert(name, phone)` -- добавить или обновить запись.
|
||||
|
||||
`find(name)` -- phone или None.
|
||||
|
||||
`delete(name)` -- удалить запись, игнорировать отсутствие.
|
||||
|
||||
`list_all()` -- список всех записей, отсортированный по имени (для BST in‑order обход; для списка и хеш‑таблицы — собрать и отсортировать явно).
|
||||
|
||||
#### 1. Связный список (LinkedListPhoneBook)
|
||||
|
||||
Узел представляется словарём: `{'name': 'Имя', 'phone': '123', 'next': None}.`
|
||||
|
||||
**Функции:**
|
||||
|
||||
`def ll_insert(head, name, phone)` — проходит до конца (или сразу добавляет в конец) и возвращает новую голову (если вставка в начало) или изменяет список по ссылке. Удобнее возвращать новую голову, если вставка может быть в начало.
|
||||
|
||||
`def ll_find(head, name)` — ищет узел, возвращает телефон или None.
|
||||
|
||||
`def ll_delete(head, name)` — удаляет узел, возвращает новую голову.
|
||||
|
||||
`def ll_list_all(head)` — собирает все записи в список и сортирует (сортировка вынесена отдельно).
|
||||
|
||||
#### 2. Хеш-таблица
|
||||
Хранится как список buckets фиксированной длины, каждый элемент — голова связного списка (или None).
|
||||
|
||||
**Функции:**
|
||||
|
||||
`def ht_insert(buckets, name, phone)` — вычисляет индекс, вызывает ll_insert для соответствующего бакета.
|
||||
|
||||
Аналогично `ht_find, ht_delete, ht_list_all` (последняя собирает все записи из всех бакетов и сортирует).
|
||||
|
||||
#### 3. Двоичное дерево поиска
|
||||
Узел — словарь: `{'name': 'Имя', 'phone': '123', 'left': None, 'right': None}.`
|
||||
|
||||
**Функции:**
|
||||
|
||||
`def bst_insert(root, name, phone)` — рекурсивно или итеративно вставляет, возвращает новый корень (если корень меняется).
|
||||
|
||||
`def bst_find(root, name)` — поиск.
|
||||
|
||||
`def bst_delete(root, name)` — удаление, возвращает новый корень.
|
||||
|
||||
`def bst_list_all(root)` — центрированный обход (рекурсивно собирает записи в отсортированном порядке).
|
||||
|
||||
### Экспериментальная часть (подробно об измерении времени)
|
||||
#### 1. Генерация тестовых данных
|
||||
Создайте список records из N элементов (например, N = 10000). Каждый элемент — кортеж (name, phone).
|
||||
|
||||
Имена генерируйте как `f"User_{i:05d}"` (равномерное распределение) или случайные слова из небольшого набора (чтобы были повторения и коллизии). Для проверки влияния порядка подготовьте два варианта одного и того же набора:
|
||||
|
||||
`records_shuffled` — случайный порядок.
|
||||
|
||||
`records_sorted` — отсортированный по имени (по алфавиту).
|
||||
|
||||
#### 2. Инструменты замера времени
|
||||
Используйте модуль **time**:
|
||||
|
||||
```python
|
||||
import time
|
||||
|
||||
start = time.perf_counter()
|
||||
# ... операции ...
|
||||
end = time.perf_counter()
|
||||
elapsed = end - start # время в секундах
|
||||
```
|
||||
|
||||
Для многократных замеров удобен `timeit`, но в этой задаче достаточно просто обернуть код в цикл и усреднить.
|
||||
|
||||
#### 3. Проведение замеров
|
||||
Для каждой структуры данных и для каждого режима входных данных (случайный / отсортированный) выполните:
|
||||
|
||||
- А. Вставка всех записей
|
||||
|
||||
Создайте пустую структуру.
|
||||
|
||||
Засеките время, выполните insert для каждой записи из входного списка.
|
||||
|
||||
Зафиксируйте общее время вставки.
|
||||
|
||||
- Б. Поиск 100 случайных записей
|
||||
|
||||
Возьмите 100 случайных имён из того же набора (гарантированно существующих) и 10 имён, которых нет (например, "None_{i}").
|
||||
|
||||
Засеките время на выполнение всех 110 вызовов find.
|
||||
|
||||
- В. Удаление 50 случайных записей
|
||||
|
||||
Выберите 50 случайных имён из набора.
|
||||
|
||||
Засеките время на выполнение delete для каждого.
|
||||
|
||||
|
||||
**!! Важно: после вставки структура остаётся заполненной, поиск и удаление выполняются на ней же. Если нужно повторить замер для другого порядка данных — создавайте новую структуру и заполняйте заново.**
|
||||
|
||||
#### 4. Сохранение результатов
|
||||
|
||||
**!! Каждый эксперимент повторить минимум 5 раз и записывать и среднее время, и все замеры.**
|
||||
|
||||
Соберите все замеры в словарь или список, затем сохраните в CSV-файл:
|
||||
|
||||
```python
|
||||
import csv
|
||||
|
||||
results = [
|
||||
["Структура", "Режим", "Операция", "Время (сек)"],
|
||||
["LinkedList", "случайный", "вставка", 0.123],
|
||||
...
|
||||
]
|
||||
|
||||
with open("results.csv", "w", newline="") as f:
|
||||
writer = csv.writer(f)
|
||||
writer.writerows(results)
|
||||
```
|
||||
|
||||
|
||||
#### 5. Анализ результатов
|
||||
Постройте график (столбчатая диаграмма или линейный график) — можно в Excel, Google Sheets или с помощью matplotlib в Python.
|
||||
|
||||
Сравните:
|
||||
|
||||
- Как порядок входных данных влияет на скорость вставки в BST (деградация до O(n) на отсортированных данных).
|
||||
|
||||
- Почему хеш-таблица почти не чувствительна к порядку.
|
||||
|
||||
- Почему связный список всегда медленен при поиске.
|
||||
|
||||
- Как удаление работает в каждой структуре.
|
||||
|
||||
* Вывод должен содержать ответ на вопрос: какую структуру и для каких задач (частые вставки, частый поиск, необходимость получать данные в порядке) стоит выбирать в реальной жизни.*
|
||||
0
SimonovaMS/428.md
Normal file
0
SimonovaMS/428.md
Normal file
0
SimonovaMS/428.txt
Normal file
0
SimonovaMS/428.txt
Normal file
0
SolovevDS/428b.md
Normal file
0
SolovevDS/428b.md
Normal file
1
VaravinVV/428b
Normal file
1
VaravinVV/428b
Normal file
|
|
@ -0,0 +1 @@
|
|||
428b
|
||||
0
VolkovVA/428b.md
Normal file
0
VolkovVA/428b.md
Normal file
0
YanyaevAA/428b.md
Normal file
0
YanyaevAA/428b.md
Normal file
1
YaroslavtsevAS/428.md
Normal file
1
YaroslavtsevAS/428.md
Normal file
|
|
@ -0,0 +1 @@
|
|||
428
|
||||
0
ZelentsovAV/428b.md
Normal file
0
ZelentsovAV/428b.md
Normal file
0
anikinvd/428.md
Normal file
0
anikinvd/428.md
Normal file
0
chizhikovaSM/428.md
Normal file
0
chizhikovaSM/428.md
Normal file
0
duznb/429.md.txt
Normal file
0
duznb/429.md.txt
Normal file
1
filippovavm/427
Normal file
1
filippovavm/427
Normal file
|
|
@ -0,0 +1 @@
|
|||
427
|
||||
0
fomichevks/426.md.txt
Normal file
0
fomichevks/426.md.txt
Normal file
1
ivanchenkoam/427.txt
Normal file
1
ivanchenkoam/427.txt
Normal file
|
|
@ -0,0 +1 @@
|
|||
856
|
||||
0
ivantsovma/428.txt
Normal file
0
ivantsovma/428.txt
Normal file
0
kolesovve/427.md
Normal file
0
kolesovve/427.md
Normal file
BIN
komissarovgo/427.md
Normal file
BIN
komissarovgo/427.md
Normal file
Binary file not shown.
1
konnovaea/429
Normal file
1
konnovaea/429
Normal file
|
|
@ -0,0 +1 @@
|
|||
429
|
||||
0
kornevma/426.md
Normal file
0
kornevma/426.md
Normal file
0
krasnovia/429.txt
Normal file
0
krasnovia/429.txt
Normal file
0
lomakinae/426
Normal file
0
lomakinae/426
Normal file
0
meosyam/428.md.txt
Normal file
0
meosyam/428.md.txt
Normal file
2
morozovns/1.py
Normal file
2
morozovns/1.py
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
print("Zadanie adin!!11!adin!11!")
|
||||
print("patch")
|
||||
1
morozovns/429
Normal file
1
morozovns/429
Normal file
|
|
@ -0,0 +1 @@
|
|||
429
|
||||
71
nehoroshevaa/Task 1/code/BinaryTree.py
Normal file
71
nehoroshevaa/Task 1/code/BinaryTree.py
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
#Узел — словарь: {'name': 'Имя', 'phone': '123', 'left': None, 'right': None}.
|
||||
def bst_insert(root, name, phone):
|
||||
#рекурсивно или итеративно вставляет, возвращает новый корень (если корень меняется).
|
||||
if root is None:
|
||||
return {'name': name,'phone': phone,'left': None,'right': None}
|
||||
|
||||
if name < root['name']:
|
||||
root['left'] = bst_insert(root['left'], name, phone)
|
||||
|
||||
elif name > root['name']:
|
||||
root['right'] = bst_insert(root['right'], name, phone)
|
||||
|
||||
else:
|
||||
root['phone'] = phone
|
||||
|
||||
return root
|
||||
|
||||
|
||||
def bst_find(root, name):
|
||||
if root is None:
|
||||
return None
|
||||
|
||||
if name == root['name']:
|
||||
return root['phone']
|
||||
|
||||
if name < root['name']:
|
||||
return bst_find(root['left'], name)
|
||||
|
||||
return bst_find(root['right'], name)
|
||||
|
||||
|
||||
def bst_delete(root, name):
|
||||
#удаление, возвращает новый корень.
|
||||
if root is None:
|
||||
return None
|
||||
|
||||
if name < root['name']:
|
||||
root['left'] = bst_delete(root['left'], name)
|
||||
|
||||
elif name > root['name']:
|
||||
root['right'] = bst_delete(root['right'], name)
|
||||
|
||||
else:
|
||||
if root['left'] is None:
|
||||
return root['right']
|
||||
|
||||
if root['right'] is None:
|
||||
return root['left']
|
||||
|
||||
min_node = root['right']
|
||||
while min_node['left'] is not None:
|
||||
min_node = min_node['left']
|
||||
|
||||
root['name'] = min_node['name']
|
||||
root['phone'] = min_node['phone']
|
||||
|
||||
root['right'] = bst_delete(root['right'], min_node['name'])
|
||||
|
||||
return root
|
||||
|
||||
|
||||
def bst_list_all(root):
|
||||
# центрированный обход (рекурсивно собирает записи в отсортированном порядке).
|
||||
if root is None:
|
||||
return []
|
||||
|
||||
return (
|
||||
bst_list_all(root['left']) +
|
||||
[(root['name'], root['phone'])] +
|
||||
bst_list_all(root['right'])
|
||||
)
|
||||
56
nehoroshevaa/Task 1/code/HashTable.py
Normal file
56
nehoroshevaa/Task 1/code/HashTable.py
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
#Аналогично ht_find, ht_delete, ht_list_all (последняя собирает все записи из всех бакетов и сортирует).
|
||||
from code.LinkedList import *
|
||||
|
||||
def create_buckets(size=1000):
|
||||
return [None] * size
|
||||
|
||||
def hash_function(name, bucket_size):
|
||||
hash_value = 0
|
||||
|
||||
for char in name:
|
||||
hash_value = (hash_value * 31 + ord(char)) % bucket_size
|
||||
|
||||
return hash_value
|
||||
|
||||
def ht_insert(buckets, name, phone):
|
||||
#вычисляет индекс, вызывает ll_insert для соответствующего бакета.
|
||||
if buckets is None:
|
||||
buckets = create_buckets()
|
||||
|
||||
index = hash_function(name, len(buckets))
|
||||
buckets[index] = ll_insert(buckets[index], name, phone)
|
||||
|
||||
return buckets
|
||||
|
||||
def ht_find(buckets, name):
|
||||
if not buckets:
|
||||
return None
|
||||
|
||||
index = hash_function(name, len(buckets))
|
||||
return ll_find(buckets[index], name)
|
||||
|
||||
def ht_delete(buckets, name):
|
||||
if not buckets:
|
||||
return buckets
|
||||
|
||||
index = hash_function(name, len(buckets))
|
||||
buckets[index] = ll_delete(buckets[index], name)
|
||||
|
||||
return buckets
|
||||
|
||||
def ht_list_all(buckets):
|
||||
if not buckets:
|
||||
return []
|
||||
|
||||
records = []
|
||||
|
||||
for bucket in buckets:
|
||||
current = bucket
|
||||
|
||||
while current is not None:
|
||||
records.append((current['name'], current['phone']))
|
||||
current = current['next']
|
||||
|
||||
records.sort(key=lambda x: x[0])
|
||||
|
||||
return records
|
||||
62
nehoroshevaa/Task 1/code/LinkedList.py
Normal file
62
nehoroshevaa/Task 1/code/LinkedList.py
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
def ll_insert(head, name, phone):
|
||||
#проходит до конца (или сразу добавляет в конец) и возвращает новую голову (если вставка в начало) или изменяет список по ссылке. Удобнее возвращать новую голову, если вставка может быть в начало.
|
||||
if head is None:
|
||||
return {'name': name, 'phone': phone, 'next': None}
|
||||
|
||||
current = head
|
||||
|
||||
while current is not None:
|
||||
if current['name'] == name:
|
||||
current['phone'] = phone
|
||||
return head
|
||||
|
||||
if current['next'] is None:
|
||||
current['next'] = {'name': name, 'phone': phone, 'next': None}
|
||||
return head
|
||||
|
||||
current = current['next']
|
||||
|
||||
|
||||
def ll_find(head, name):
|
||||
# ищет узел, возвращает телефон или None.
|
||||
current = head
|
||||
|
||||
while current is not None:
|
||||
if current['name'] == name:
|
||||
return current['phone']
|
||||
current = current['next']
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def ll_delete(head, name):
|
||||
# удаляет узел, возвращает новую голову.
|
||||
if head is None:
|
||||
return None
|
||||
|
||||
if head['name'] == name:
|
||||
return head['next']
|
||||
|
||||
current = head
|
||||
|
||||
while current['next'] is not None:
|
||||
if current['next']['name'] == name:
|
||||
current['next'] = current['next']['next']
|
||||
return head
|
||||
current = current['next']
|
||||
|
||||
return head
|
||||
|
||||
|
||||
def ll_list_all(head):
|
||||
#собирает все записи в список и сортирует (сортировка вынесена отдельно).
|
||||
result = []
|
||||
current = head
|
||||
|
||||
while current is not None:
|
||||
result.append((current['name'], current['phone']))
|
||||
current = current['next']
|
||||
|
||||
result.sort(key=lambda x: x[0])
|
||||
|
||||
return result
|
||||
0
nehoroshevaa/Task 1/code/__init__.py
Normal file
0
nehoroshevaa/Task 1/code/__init__.py
Normal file
138
nehoroshevaa/Task 1/exp.py
Normal file
138
nehoroshevaa/Task 1/exp.py
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
import sys
|
||||
sys.setrecursionlimit(20000)
|
||||
import time
|
||||
import random
|
||||
import csv
|
||||
|
||||
from code.LinkedList import *
|
||||
from code.HashTable import *
|
||||
from code.BinaryTree import *
|
||||
|
||||
|
||||
|
||||
def generate_data(n=10000):
|
||||
return [(f"User_{i:05d}", f"+7-900-{i:05d}") for i in range(n)]
|
||||
|
||||
|
||||
def prepare_data(n=10000):
|
||||
data = generate_data(n)
|
||||
|
||||
shuffled = data[:]
|
||||
random.shuffle(shuffled)
|
||||
|
||||
sorted_data = sorted(data, key=lambda x: x[0])
|
||||
|
||||
return shuffled, sorted_data
|
||||
|
||||
|
||||
|
||||
def measure_find(find_func, obj, data):
|
||||
exist = random.sample([x[0] for x in data], 100)
|
||||
fake = [f"None_{i}" for i in range(10)]
|
||||
names = exist + fake
|
||||
|
||||
start = time.perf_counter()
|
||||
|
||||
for name in names:
|
||||
find_func(obj, name)
|
||||
|
||||
return time.perf_counter() - start
|
||||
|
||||
|
||||
|
||||
def measure_delete(delete_func, obj, data):
|
||||
names = random.sample([x[0] for x in data], 50)
|
||||
|
||||
start = time.perf_counter()
|
||||
|
||||
for name in names:
|
||||
obj = delete_func(obj, name)
|
||||
|
||||
return time.perf_counter() - start
|
||||
|
||||
|
||||
|
||||
def test_linked_list(data):
|
||||
head = None
|
||||
|
||||
start = time.perf_counter()
|
||||
for name, phone in data:
|
||||
head = ll_insert(head, name, phone)
|
||||
insert_time = time.perf_counter() - start
|
||||
|
||||
find_time = measure_find(ll_find, head, data)
|
||||
delete_time = measure_delete(ll_delete, head, data)
|
||||
|
||||
return insert_time, find_time, delete_time
|
||||
|
||||
|
||||
|
||||
def test_hash_table(data):
|
||||
buckets = create_buckets(1000)
|
||||
|
||||
start = time.perf_counter()
|
||||
for name, phone in data:
|
||||
ht_insert(buckets, name, phone)
|
||||
insert_time = time.perf_counter() - start
|
||||
|
||||
find_time = measure_find(ht_find, buckets, data)
|
||||
delete_time = measure_delete(ht_delete, buckets, data)
|
||||
|
||||
return insert_time, find_time, delete_time
|
||||
|
||||
|
||||
def test_bst(data):
|
||||
root = None
|
||||
|
||||
start = time.perf_counter()
|
||||
for name, phone in data:
|
||||
root = bst_insert(root, name, phone)
|
||||
insert_time = time.perf_counter() - start
|
||||
|
||||
find_time = measure_find(bst_find, root, data)
|
||||
delete_time = measure_delete(bst_delete, root, data)
|
||||
|
||||
return insert_time, find_time, delete_time
|
||||
|
||||
|
||||
def run():
|
||||
|
||||
results = []
|
||||
results.append(["Structure", "Order", "Insert", "Find", "Delete"])
|
||||
|
||||
for i in range(5):
|
||||
|
||||
shuffled, sorted_data = prepare_data()
|
||||
|
||||
# -------- LinkedList --------
|
||||
i1, f1, d1 = test_linked_list(shuffled)
|
||||
results.append(["LinkedList", "shuffled", i1, f1, d1])
|
||||
|
||||
i1, f1, d1 = test_linked_list(sorted_data)
|
||||
results.append(["LinkedList", "sorted", i1, f1, d1])
|
||||
|
||||
# -------- HashTable --------
|
||||
i2, f2, d2 = test_hash_table(shuffled)
|
||||
results.append(["HashTable", "shuffled", i2, f2, d2])
|
||||
|
||||
i2, f2, d2 = test_hash_table(sorted_data)
|
||||
results.append(["HashTable", "sorted", i2, f2, d2])
|
||||
|
||||
# -------- BST --------
|
||||
i3, f3, d3 = test_bst(shuffled)
|
||||
results.append(["BST", "shuffled", i3, f3, d3])
|
||||
|
||||
i3, f3, d3 = test_bst(sorted_data)
|
||||
results.append(["BST", "sorted", i3, f3, d3])
|
||||
|
||||
|
||||
|
||||
with open("results.csv", "w", newline="") as f:
|
||||
writer = csv.writer(f)
|
||||
writer.writerows(results)
|
||||
|
||||
print("Готово! results.csv создан")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
run()
|
||||
BIN
nehoroshevaa/docs/data_task1/delete.png
Normal file
BIN
nehoroshevaa/docs/data_task1/delete.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 127 KiB |
BIN
nehoroshevaa/docs/data_task1/find.png
Normal file
BIN
nehoroshevaa/docs/data_task1/find.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 121 KiB |
BIN
nehoroshevaa/docs/data_task1/insert.png
Normal file
BIN
nehoroshevaa/docs/data_task1/insert.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 89 KiB |
51
nehoroshevaa/docs/data_task1/plot.py
Normal file
51
nehoroshevaa/docs/data_task1/plot.py
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
|
||||
import csv
|
||||
import matplotlib.pyplot as plt
|
||||
from collections import defaultdict
|
||||
|
||||
|
||||
data = []
|
||||
|
||||
with open("results.csv", "r") as f:
|
||||
reader = csv.reader(f)
|
||||
next(reader) # header
|
||||
for row in reader:
|
||||
structure, order, insert, find, delete = row
|
||||
data.append((structure, order, float(insert), float(find), float(delete)))
|
||||
|
||||
|
||||
def group(metric_index):
|
||||
result = defaultdict(list)
|
||||
for s, o, ins, f, d in data:
|
||||
key = (s, o)
|
||||
result[key].append([ins, f, d][metric_index])
|
||||
return result
|
||||
|
||||
|
||||
def save_plot(metric_name, index, filename):
|
||||
|
||||
grouped = group(index)
|
||||
|
||||
plt.figure()
|
||||
|
||||
labels = []
|
||||
|
||||
for (structure, order), values in grouped.items():
|
||||
label = f"{structure}-{order}"
|
||||
labels.append(label)
|
||||
plt.plot(values, label=label)
|
||||
|
||||
plt.title(metric_name)
|
||||
plt.xlabel("Run")
|
||||
plt.ylabel("Time (sec)")
|
||||
plt.legend()
|
||||
|
||||
plt.savefig(filename, dpi=300, bbox_inches="tight")
|
||||
plt.close()
|
||||
|
||||
|
||||
save_plot("INSERT TIME", 0, "insert.png")
|
||||
save_plot("FIND TIME", 1, "find.png")
|
||||
save_plot("DELETE TIME", 2, "delete.png")
|
||||
|
||||
print("Графики сохранены: insert.png, find.png, delete.png")
|
||||
31
nehoroshevaa/docs/data_task1/results.csv
Normal file
31
nehoroshevaa/docs/data_task1/results.csv
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
Structure,Order,Insert,Find,Delete
|
||||
LinkedList,shuffled,3.1266312,0.0240491,0.0153019
|
||||
LinkedList,sorted,2.1736874,0.0176649,0.0123909
|
||||
HashTable,shuffled,0.0102941,0.000103,5.22E-05
|
||||
HashTable,sorted,0.0093038,0.0001008,5.37E-05
|
||||
BST,shuffled,0.0154676,0.000154,9.03E-05
|
||||
BST,sorted,8.3014441,0.0768616,0.0345065
|
||||
LinkedList,shuffled,3.2182401,0.0256622,0.0177542
|
||||
LinkedList,sorted,2.2604362,0.0199027,0.0131383
|
||||
HashTable,shuffled,0.0110818,0.0001227,5.32E-05
|
||||
HashTable,sorted,0.0098066,0.0001021,5.52E-05
|
||||
BST,shuffled,0.0184675,0.0001531,9.83E-05
|
||||
BST,sorted,8.6233891,0.0829446,0.0509548
|
||||
LinkedList,shuffled,3.2111766,0.0260377,0.0221557
|
||||
LinkedList,sorted,2.6125727,0.0275846,0.0190955
|
||||
HashTable,shuffled,0.014219,0.0001666,0.0003187
|
||||
HashTable,sorted,0.0138165,0.0001425,7.94E-05
|
||||
BST,shuffled,0.0234246,0.0002257,0.0001382
|
||||
BST,sorted,8.9193103,0.0615153,0.0415436
|
||||
LinkedList,shuffled,3.4287802,0.0276346,0.0178373
|
||||
LinkedList,sorted,2.4205873,0.0211635,0.0157121
|
||||
HashTable,shuffled,0.0113899,0.0001118,5.63E-05
|
||||
HashTable,sorted,0.0116161,0.0001284,6.88E-05
|
||||
BST,shuffled,0.0221165,0.0001773,0.0001002
|
||||
BST,sorted,9.0077053,0.1054247,0.0477643
|
||||
LinkedList,shuffled,3.2640041,0.0345332,0.0232472
|
||||
LinkedList,sorted,2.827502,0.0201937,0.0141592
|
||||
HashTable,shuffled,0.0105407,0.0001501,8.18E-05
|
||||
HashTable,sorted,0.0102284,0.0001005,5.58E-05
|
||||
BST,shuffled,0.0166355,0.0001603,9.34E-05
|
||||
BST,sorted,8.2043019,0.0622669,0.0375809
|
||||
|
BIN
nehoroshevaa/docs/report_1.docx
Normal file
BIN
nehoroshevaa/docs/report_1.docx
Normal file
Binary file not shown.
BIN
nikolaevda/427.md
Normal file
BIN
nikolaevda/427.md
Normal file
Binary file not shown.
0
novikovsd/428
Normal file
0
novikovsd/428
Normal file
0
osininyai/427.md
Normal file
0
osininyai/427.md
Normal file
0
pogodinda/427.md.txt
Normal file
0
pogodinda/427.md.txt
Normal file
1
pomelovsd/427
Normal file
1
pomelovsd/427
Normal file
|
|
@ -0,0 +1 @@
|
|||
427
|
||||
BIN
raskatovia/429.md
Normal file
BIN
raskatovia/429.md
Normal file
Binary file not shown.
0
romanovpv/427.md
Normal file
0
romanovpv/427.md
Normal file
1
rybakovaa/428b.md
Normal file
1
rybakovaa/428b.md
Normal file
|
|
@ -0,0 +1 @@
|
|||
428b
|
||||
0
semyanovra/426.md
Normal file
0
semyanovra/426.md
Normal file
0
shahovaa/429.md
Normal file
0
shahovaa/429.md
Normal file
0
shalovsa/429.txt
Normal file
0
shalovsa/429.txt
Normal file
0
shekurovaa/429.md
Normal file
0
shekurovaa/429.md
Normal file
1
skorohodovsa/427
Normal file
1
skorohodovsa/427
Normal file
|
|
@ -0,0 +1 @@
|
|||
427
|
||||
4
skorohodovsa/main.py
Normal file
4
skorohodovsa/main.py
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
from math import sin
|
||||
|
||||
for i in range(10000):
|
||||
print(" " * round(50 * (1 + sin(i/100))), "Hello World!")
|
||||
0
smirnovad/429.md
Normal file
0
smirnovad/429.md
Normal file
6
sobininaas/429.rtf
Normal file
6
sobininaas/429.rtf
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
{\rtf1\ansi\ansicpg1251\cocoartf2761
|
||||
\cocoatextscaling0\cocoaplatform0{\fonttbl}
|
||||
{\colortbl;\red255\green255\blue255;}
|
||||
{\*\expandedcolortbl;;}
|
||||
\paperw11900\paperh16840\margl1440\margr1440\vieww11520\viewh8400\viewkind0
|
||||
}
|
||||
1
soldatkinao/428б.md
Normal file
1
soldatkinao/428б.md
Normal file
|
|
@ -0,0 +1 @@
|
|||
<EFBFBD>¥¦¨¬ ¢כ¢®₪ ×®¬ ₪ ם×א (ECHO) ¢×«מח¥.
|
||||
0
sorokinfi/427.md
Normal file
0
sorokinfi/427.md
Normal file
0
stepinim/428.md
Normal file
0
stepinim/428.md
Normal file
1
stepushovgs/427
Normal file
1
stepushovgs/427
Normal file
|
|
@ -0,0 +1 @@
|
|||
427
|
||||
0
svetlakovkyu/426
Normal file
0
svetlakovkyu/426
Normal file
1
talantsevgi/427.txt
Normal file
1
talantsevgi/427.txt
Normal file
|
|
@ -0,0 +1 @@
|
|||
732489234
|
||||
1
tseremonnikovaaa/427
Normal file
1
tseremonnikovaaa/427
Normal file
|
|
@ -0,0 +1 @@
|
|||
427
|
||||
1
volkovim/428b.md
Normal file
1
volkovim/428b.md
Normal file
|
|
@ -0,0 +1 @@
|
|||
428b
|
||||
1
zaharoves/429.md
Normal file
1
zaharoves/429.md
Normal file
|
|
@ -0,0 +1 @@
|
|||
|
||||
0
zverevem/429.txt
Normal file
0
zverevem/429.txt
Normal file
Loading…
Reference in New Issue
Block a user