[1]task1 #384

Merged
git_admin merged 2 commits from ivankinad/2026-rff_mp:task1 into develop 2026-09-05 06:46:08 +00:00
3 changed files with 421 additions and 0 deletions
Showing only changes of commit e6b4e51999 - Show all commits

View File

@ -0,0 +1,109 @@
Structure,Mode,Operation,Time (sec)
LinkedList,random,insert (trial 1),3.415125
LinkedList,random,find (trial 1),0.035397
LinkedList,random,delete (trial 1),0.017692
LinkedList,random,insert (trial 2),3.534952
LinkedList,random,find (trial 2),0.038819
LinkedList,random,delete (trial 2),0.021675
LinkedList,random,insert (trial 3),3.493529
LinkedList,random,find (trial 3),0.036592
LinkedList,random,delete (trial 3),0.018221
LinkedList,random,insert (trial 4),3.340745
LinkedList,random,find (trial 4),0.036098
LinkedList,random,delete (trial 4),0.017576
LinkedList,random,insert (trial 5),3.369741
LinkedList,random,find (trial 5),0.035302
LinkedList,random,delete (trial 5),0.017674
LinkedList,random,Insert (avg),3.430818
LinkedList,random,Find (avg),0.036442
LinkedList,random,Delete (avg),0.018568
LinkedList,sorted,insert (trial 1),3.118200
LinkedList,sorted,find (trial 1),0.037116
LinkedList,sorted,delete (trial 1),0.019387
LinkedList,sorted,insert (trial 2),3.338498
LinkedList,sorted,find (trial 2),0.036500
LinkedList,sorted,delete (trial 2),0.019001
LinkedList,sorted,insert (trial 3),3.136906
LinkedList,sorted,find (trial 3),0.037498
LinkedList,sorted,delete (trial 3),0.019219
LinkedList,sorted,insert (trial 4),3.253578
LinkedList,sorted,find (trial 4),0.036434
LinkedList,sorted,delete (trial 4),0.019333
LinkedList,sorted,insert (trial 5),3.207896
LinkedList,sorted,find (trial 5),0.038585
LinkedList,sorted,delete (trial 5),0.020473
LinkedList,sorted,Insert (avg),3.211016
LinkedList,sorted,Find (avg),0.037227
LinkedList,sorted,Delete (avg),0.019482
HashTable,random,insert (trial 1),0.010124
HashTable,random,find (trial 1),0.000093
HashTable,random,delete (trial 1),0.000052
HashTable,random,insert (trial 2),0.010397
HashTable,random,find (trial 2),0.000086
HashTable,random,delete (trial 2),0.000048
HashTable,random,insert (trial 3),0.009352
HashTable,random,find (trial 3),0.000081
HashTable,random,delete (trial 3),0.000046
HashTable,random,insert (trial 4),0.009326
HashTable,random,find (trial 4),0.000080
HashTable,random,delete (trial 4),0.000046
HashTable,random,insert (trial 5),0.010205
HashTable,random,find (trial 5),0.000081
HashTable,random,delete (trial 5),0.000046
HashTable,random,Insert (avg),0.009881
HashTable,random,Find (avg),0.000084
HashTable,random,Delete (avg),0.000048
HashTable,sorted,insert (trial 1),0.008975
HashTable,sorted,find (trial 1),0.000087
HashTable,sorted,delete (trial 1),0.000050
HashTable,sorted,insert (trial 2),0.009137
HashTable,sorted,find (trial 2),0.000086
HashTable,sorted,delete (trial 2),0.000050
HashTable,sorted,insert (trial 3),0.009460
HashTable,sorted,find (trial 3),0.000086
HashTable,sorted,delete (trial 3),0.000049
HashTable,sorted,insert (trial 4),0.008977
HashTable,sorted,find (trial 4),0.000085
HashTable,sorted,delete (trial 4),0.000049
HashTable,sorted,insert (trial 5),0.009416
HashTable,sorted,find (trial 5),0.000094
HashTable,sorted,delete (trial 5),0.000053
HashTable,sorted,Insert (avg),0.009193
HashTable,sorted,Find (avg),0.000087
HashTable,sorted,Delete (avg),0.000050
BST,random,insert (trial 1),0.031499
BST,random,find (trial 1),0.000274
BST,random,delete (trial 1),0.000153
BST,random,insert (trial 2),0.031806
BST,random,find (trial 2),0.000286
BST,random,delete (trial 2),0.000157
BST,random,insert (trial 3),0.031514
BST,random,find (trial 3),0.000267
BST,random,delete (trial 3),0.000150
BST,random,insert (trial 4),0.031758
BST,random,find (trial 4),0.000260
BST,random,delete (trial 4),0.000144
BST,random,insert (trial 5),0.031923
BST,random,find (trial 5),0.000262
BST,random,delete (trial 5),0.000145
BST,random,Insert (avg),0.031700
BST,random,Find (avg),0.000270
BST,random,Delete (avg),0.000150
BST,sorted,insert (trial 1),14.135551
BST,sorted,find (trial 1),0.123919
BST,sorted,delete (trial 1),0.054104
BST,sorted,insert (trial 2),13.781539
BST,sorted,find (trial 2),0.126835
BST,sorted,delete (trial 2),0.055120
BST,sorted,insert (trial 3),15.010563
BST,sorted,find (trial 3),0.117841
BST,sorted,delete (trial 3),0.056871
BST,sorted,insert (trial 4),14.378650
BST,sorted,find (trial 4),0.113316
BST,sorted,delete (trial 4),0.054129
BST,sorted,insert (trial 5),14.285981
BST,sorted,find (trial 5),0.112919
BST,sorted,delete (trial 5),0.057369
BST,sorted,Insert (avg),14.318457
BST,sorted,Find (avg),0.118966
BST,sorted,Delete (avg),0.055519
1 Structure Mode Operation Time (sec)
2 LinkedList random insert (trial 1) 3.415125
3 LinkedList random find (trial 1) 0.035397
4 LinkedList random delete (trial 1) 0.017692
5 LinkedList random insert (trial 2) 3.534952
6 LinkedList random find (trial 2) 0.038819
7 LinkedList random delete (trial 2) 0.021675
8 LinkedList random insert (trial 3) 3.493529
9 LinkedList random find (trial 3) 0.036592
10 LinkedList random delete (trial 3) 0.018221
11 LinkedList random insert (trial 4) 3.340745
12 LinkedList random find (trial 4) 0.036098
13 LinkedList random delete (trial 4) 0.017576
14 LinkedList random insert (trial 5) 3.369741
15 LinkedList random find (trial 5) 0.035302
16 LinkedList random delete (trial 5) 0.017674
17 LinkedList random Insert (avg) 3.430818
18 LinkedList random Find (avg) 0.036442
19 LinkedList random Delete (avg) 0.018568
20 LinkedList sorted insert (trial 1) 3.118200
21 LinkedList sorted find (trial 1) 0.037116
22 LinkedList sorted delete (trial 1) 0.019387
23 LinkedList sorted insert (trial 2) 3.338498
24 LinkedList sorted find (trial 2) 0.036500
25 LinkedList sorted delete (trial 2) 0.019001
26 LinkedList sorted insert (trial 3) 3.136906
27 LinkedList sorted find (trial 3) 0.037498
28 LinkedList sorted delete (trial 3) 0.019219
29 LinkedList sorted insert (trial 4) 3.253578
30 LinkedList sorted find (trial 4) 0.036434
31 LinkedList sorted delete (trial 4) 0.019333
32 LinkedList sorted insert (trial 5) 3.207896
33 LinkedList sorted find (trial 5) 0.038585
34 LinkedList sorted delete (trial 5) 0.020473
35 LinkedList sorted Insert (avg) 3.211016
36 LinkedList sorted Find (avg) 0.037227
37 LinkedList sorted Delete (avg) 0.019482
38 HashTable random insert (trial 1) 0.010124
39 HashTable random find (trial 1) 0.000093
40 HashTable random delete (trial 1) 0.000052
41 HashTable random insert (trial 2) 0.010397
42 HashTable random find (trial 2) 0.000086
43 HashTable random delete (trial 2) 0.000048
44 HashTable random insert (trial 3) 0.009352
45 HashTable random find (trial 3) 0.000081
46 HashTable random delete (trial 3) 0.000046
47 HashTable random insert (trial 4) 0.009326
48 HashTable random find (trial 4) 0.000080
49 HashTable random delete (trial 4) 0.000046
50 HashTable random insert (trial 5) 0.010205
51 HashTable random find (trial 5) 0.000081
52 HashTable random delete (trial 5) 0.000046
53 HashTable random Insert (avg) 0.009881
54 HashTable random Find (avg) 0.000084
55 HashTable random Delete (avg) 0.000048
56 HashTable sorted insert (trial 1) 0.008975
57 HashTable sorted find (trial 1) 0.000087
58 HashTable sorted delete (trial 1) 0.000050
59 HashTable sorted insert (trial 2) 0.009137
60 HashTable sorted find (trial 2) 0.000086
61 HashTable sorted delete (trial 2) 0.000050
62 HashTable sorted insert (trial 3) 0.009460
63 HashTable sorted find (trial 3) 0.000086
64 HashTable sorted delete (trial 3) 0.000049
65 HashTable sorted insert (trial 4) 0.008977
66 HashTable sorted find (trial 4) 0.000085
67 HashTable sorted delete (trial 4) 0.000049
68 HashTable sorted insert (trial 5) 0.009416
69 HashTable sorted find (trial 5) 0.000094
70 HashTable sorted delete (trial 5) 0.000053
71 HashTable sorted Insert (avg) 0.009193
72 HashTable sorted Find (avg) 0.000087
73 HashTable sorted Delete (avg) 0.000050
74 BST random insert (trial 1) 0.031499
75 BST random find (trial 1) 0.000274
76 BST random delete (trial 1) 0.000153
77 BST random insert (trial 2) 0.031806
78 BST random find (trial 2) 0.000286
79 BST random delete (trial 2) 0.000157
80 BST random insert (trial 3) 0.031514
81 BST random find (trial 3) 0.000267
82 BST random delete (trial 3) 0.000150
83 BST random insert (trial 4) 0.031758
84 BST random find (trial 4) 0.000260
85 BST random delete (trial 4) 0.000144
86 BST random insert (trial 5) 0.031923
87 BST random find (trial 5) 0.000262
88 BST random delete (trial 5) 0.000145
89 BST random Insert (avg) 0.031700
90 BST random Find (avg) 0.000270
91 BST random Delete (avg) 0.000150
92 BST sorted insert (trial 1) 14.135551
93 BST sorted find (trial 1) 0.123919
94 BST sorted delete (trial 1) 0.054104
95 BST sorted insert (trial 2) 13.781539
96 BST sorted find (trial 2) 0.126835
97 BST sorted delete (trial 2) 0.055120
98 BST sorted insert (trial 3) 15.010563
99 BST sorted find (trial 3) 0.117841
100 BST sorted delete (trial 3) 0.056871
101 BST sorted insert (trial 4) 14.378650
102 BST sorted find (trial 4) 0.113316
103 BST sorted delete (trial 4) 0.054129
104 BST sorted insert (trial 5) 14.285981
105 BST sorted find (trial 5) 0.112919
106 BST sorted delete (trial 5) 0.057369
107 BST sorted Insert (avg) 14.318457
108 BST sorted Find (avg) 0.118966
109 BST sorted Delete (avg) 0.055519

312
ivankinad/task1/laba1.py Normal file
View File

@ -0,0 +1,312 @@
import csv
import random
import sys
import time
import threading
import matplotlib.pyplot as plt
sys.setrecursionlimit(30000)
threading.stack_size(64*1024*1024)
def ll_insert(head, name, phone):
"""Добавляет запись или обновляет телефон, если имя уже существует. Возвращает новую голову списка."""
current = head
while current is not None:
if current["name"] == name:
current["phone"] = phone
return head
current = current["next"]
fresh_node = {"name": name, "phone": phone, "next": head}
return fresh_node
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):
"""Удаляет узел по имени. Возвращает новую голову списка."""
current = head
previous = None
while current is not None:
if current["name"] == name:
if previous is None:
return current["next"]
else:
previous["next"] = current["next"]
return head
previous = current
current = current["next"]
return head
def ll_list_all(head):
"""Собирает все записи в список и сортирует их по имени."""
entries = []
current = head
while current is not None:
entries.append((current["name"], current["phone"]))
current = current["next"]
entries.sort(key=lambda item: item[0])
return entries
def ht_create(size=1000):
"""Создает пустую хеш-таблицу заданного размера."""
return [None] * size
def ht_insert(buckets, name, phone):
"""Вычисляет индекс бакета и вызывает ll_insert."""
bucket_idx = abs(hash(name)) % len(buckets)
buckets[bucket_idx] = ll_insert(buckets[bucket_idx], name, phone)
def ht_find(buckets, name):
"""Вычисляет индекс бакета и вызывает ll_find."""
bucket_idx = abs(hash(name)) % len(buckets)
return ll_find(buckets[bucket_idx], name)
def ht_delete(buckets, name):
"""Вычисляет индекс бакета и вызывает ll_delete."""
bucket_idx = abs(hash(name)) % len(buckets)
buckets[bucket_idx] = ll_delete(buckets[bucket_idx], name)
def ht_list_all(buckets):
"""Собирает записи из всех бакетов и сортирует их по имени."""
entries = []
for head_node in buckets:
current = head_node
while current is not None:
entries.append((current["name"], current["phone"]))
current = current["next"]
entries.sort(key=lambda item: item[0])
return entries
def bst_insert(root, name, phone):
"""Рекурсивно вставляет узел или обновляет телефон."""
if root is None:
return {"name": name, "phone": phone, "left": None, "right": None}
if name == root["name"]:
root["phone"] = phone
elif name < root["name"]:
root["left"] = bst_insert(root["left"], name, phone)
else:
root["right"] = bst_insert(root["right"], name, phone)
return root
def bst_find(root, name):
"""Рекурсивный поиск по дереву."""
if root is None:
return None
if name == root["name"]:
return root["phone"]
elif name < root["name"]:
return bst_find(root["left"], name)
else:
return bst_find(root["right"], name)
def bst_delete(root, name):
"""Рекурсивное удаление узла из BST."""
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"]
successor = root["right"]
while successor["left"] is not None:
successor = successor["left"]
root["name"] = successor["name"]
root["phone"] = successor["phone"]
root["right"] = bst_delete(root["right"], successor["name"])
return root
def bst_list_all(root):
"""Центрированный обход дерева для сбора записей."""
entries = []
def _inorder(node):
if node is not None:
_inorder(node["left"])
entries.append((node["name"], node["phone"]))
_inorder(node["right"])
_inorder(root)
return entries
def perform_benchmark():
total_records = 10000
random.seed(42)
ordered_records = [(f"User_{i:05d}", f"8-999-123-{i:04d}") for i in range(total_records)]
shuffled_records = ordered_records.copy()
random.shuffle(shuffled_records)
existing_searches = [random.choice(ordered_records)[0] for _ in range(100)]
non_existing_searches = [f"None_{i}" for i in range(10)]
search_queries = existing_searches + non_existing_searches
deletion_targets = [random.choice(ordered_records)[0] for _ in range(50)]
output_rows = [["Structure", "Mode", "Operation", "Time (sec)"]]
graph_entries = []
def execute_trial(structure_kind, data_mode, data_collection):
print(f"Starting: {structure_kind} | Mode: {data_mode}...")
insertion_measurements, search_measurements, deletion_measurements = [], [], []
for trial_num in range(1, 6):
if structure_kind == "LinkedList": container = None
elif structure_kind == "HashTable": container = ht_create(size=1000)
elif structure_kind == "BST": container = None
# А. Вставка
timer_start = time.perf_counter()
if structure_kind == "LinkedList":
for name, phone in data_collection: container = ll_insert(container, name, phone)
elif structure_kind == "HashTable":
for name, phone in data_collection: ht_insert(container, name, phone)
elif structure_kind == "BST":
for name, phone in data_collection: container = bst_insert(container, name, phone)
insert_elapsed = time.perf_counter() - timer_start
insertion_measurements.append(insert_elapsed)
output_rows.append([structure_kind, data_mode, f"insert (trial {trial_num})", f"{insert_elapsed:.6f}"])
# Б. Поиск
timer_start = time.perf_counter()
if structure_kind == "LinkedList":
for name in search_queries: ll_find(container, name)
elif structure_kind == "HashTable":
for name in search_queries: ht_find(container, name)
elif structure_kind == "BST":
for name in search_queries: bst_find(container, name)
search_elapsed = time.perf_counter() - timer_start
search_measurements.append(search_elapsed)
output_rows.append([structure_kind, data_mode, f"find (trial {trial_num})", f"{search_elapsed:.6f}"])
# В. Удаление
timer_start = time.perf_counter()
if structure_kind == "LinkedList":
for name in deletion_targets: container = ll_delete(container, name)
elif structure_kind == "HashTable":
for name in deletion_targets: ht_delete(container, name)
elif structure_kind == "BST":
for name in deletion_targets: container = bst_delete(container, name)
delete_elapsed = time.perf_counter() - timer_start
deletion_measurements.append(delete_elapsed)
output_rows.append([structure_kind, data_mode, f"delete (trial {trial_num})", f"{delete_elapsed:.6f}"])
# Запись средних значений
output_rows.append([structure_kind, data_mode, "Insert (avg)", f"{sum(insertion_measurements)/5:.6f}"])
output_rows.append([structure_kind, data_mode, "Find (avg)", f"{sum(search_measurements)/5:.6f}"])
output_rows.append([structure_kind, data_mode, "Delete (avg)", f"{sum(deletion_measurements)/5:.6f}"])
avg_insertion = sum(insertion_measurements) / 5
avg_search = sum(search_measurements) / 5
avg_deletion = sum(deletion_measurements) / 5
graph_entries.append((structure_kind, data_mode, avg_insertion, avg_search, avg_deletion))
# Запуск всех тестов
execute_trial("LinkedList", "random", shuffled_records)
execute_trial("LinkedList", "sorted", ordered_records)
execute_trial("HashTable", "random", shuffled_records)
execute_trial("HashTable", "sorted", ordered_records)
execute_trial("BST", "random", shuffled_records)
execute_trial("BST", "sorted", ordered_records)
# Сохранение в CSV
with open("benchmark_output.csv", "w", newline="", encoding="utf-8") as csv_file:
csv_writer = csv.writer(csv_file)
csv_writer.writerows(output_rows)
print("\n[Success] All benchmarks completed! Results saved to 'benchmark_output.csv'.")
# ВЫЗЫВАЕМ ФУНКЦИЮ ДЛЯ СОЗДАНИЯ ГРАФИКОВ
generate_performance_charts(graph_entries)
def generate_performance_charts(plot_data):
"""
Создает графики производительности структур данных.
Args:
plot_data: список кортежей (structure, mode, avg_insert, avg_find, avg_delete)
"""
if not plot_data:
print("Нет данных для построения графиков")
return
# Подготовка данных
structures = ['LinkedList', 'HashTable', 'BST']
modes = ['random', 'sorted']
operations = ['Insert', 'Find', 'Delete']
# Создаем фигуру с тремя подграфиками
fig, axes = plt.subplots(1, 3, figsize=(15, 5))
for idx, operation in enumerate(operations):
ax = axes[idx]
# Данные для текущей операции
x_positions = []
y_values = []
labels = []
for structure in structures:
for mode in modes:
# Находим данные для этой комбинации
for data in plot_data:
if data[0] == structure and data[1] == mode:
value = data[2 + idx] # 2=insert, 3=find, 4=delete
x_positions.append(len(x_positions))
y_values.append(value)
labels.append(f"{structure}\n{mode}")
# Создаем столбчатую диаграмму
bars = ax.bar(x_positions, y_values, color=['skyblue', 'lightcoral']*3)
# Настройка графика
ax.set_title(f'Операция: {operation}', fontsize=14, fontweight='bold')
ax.set_ylabel('Время (сек)', fontsize=12)
ax.set_xticks(x_positions)
ax.set_xticklabels(labels, rotation=45, ha='right', fontsize=10)
ax.grid(axis='y', alpha=0.3)
# Добавляем значения над столбцами
for bar, value in zip(bars, y_values):
ax.text(bar.get_x() + bar.get_width()/2, bar.get_height(),
f'{value:.4f}', ha='center', va='bottom', fontsize=8)
plt.tight_layout()
plt.savefig('performance_charts.png', dpi=300, bbox_inches='tight')
plt.show()
print("Графики сохранены в 'performance_charts.png'")
if __name__ == '__main__':
benchmark_thread = threading.Thread(target=perform_benchmark)
benchmark_thread.start()
benchmark_thread.join()
# Дополнительно: если графики не показались автоматически
# Можно вызвать функцию напрямую после завершения потока
print("\nПрограмма завершена. Проверьте файл 'performance_charts.png'")

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 KiB