Загрузить файлы в «kalinovskiymi/docs/data»

This commit is contained in:
kalinovskiymi 2026-05-24 17:04:17 +00:00
parent f4a032747b
commit 4633efddae
3 changed files with 468 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

View File

@ -0,0 +1,91 @@
structure,order,operation,time,run
LinkedList,shuffled,insert,0.030281299999999955,1
LinkedList,shuffled,find,0.004695899999999975,1
LinkedList,shuffled,delete,0.0033233999999999764,1
LinkedList,shuffled,insert,0.0353907,2
LinkedList,shuffled,find,0.005563899999999955,2
LinkedList,shuffled,delete,0.0034716999999999665,2
LinkedList,shuffled,insert,0.01944009999999996,3
LinkedList,shuffled,find,0.002577700000000016,3
LinkedList,shuffled,delete,0.0018714000000000786,3
LinkedList,shuffled,insert,0.022181000000000006,4
LinkedList,shuffled,find,0.004234000000000071,4
LinkedList,shuffled,delete,0.0031284999999999785,4
LinkedList,shuffled,insert,0.02823869999999995,5
LinkedList,shuffled,find,0.004262699999999953,5
LinkedList,shuffled,delete,0.0031122999999999568,5
HashTable,shuffled,insert,0.000658699999999901,1
HashTable,shuffled,find,5.359999999998699e-05,1
HashTable,shuffled,delete,2.869999999999262e-05,1
HashTable,shuffled,insert,0.0008105999999999947,2
HashTable,shuffled,find,5.250000000001087e-05,2
HashTable,shuffled,delete,2.8000000000028002e-05,2
HashTable,shuffled,insert,0.0006085000000000118,3
HashTable,shuffled,find,5.270000000001662e-05,3
HashTable,shuffled,delete,2.76000000000165e-05,3
HashTable,shuffled,insert,0.0005973000000000228,4
HashTable,shuffled,find,5.179999999993523e-05,4
HashTable,shuffled,delete,2.740000000001075e-05,4
HashTable,shuffled,insert,0.0005963999999999414,5
HashTable,shuffled,find,5.250000000001087e-05,5
HashTable,shuffled,delete,2.7699999999963865e-05,5
BST,shuffled,insert,0.0025841999999999254,1
BST,shuffled,find,0.0001540000000000985,1
BST,shuffled,delete,0.00013839999999998298,1
BST,shuffled,insert,0.0025424000000000557,2
BST,shuffled,find,0.000152800000000064,2
BST,shuffled,delete,0.00013700000000005375,2
BST,shuffled,insert,0.0025473999999999775,3
BST,shuffled,find,0.00015370000000003436,3
BST,shuffled,delete,0.00013370000000001436,3
BST,shuffled,insert,0.0025645000000000806,4
BST,shuffled,find,0.00015940000000003174,4
BST,shuffled,delete,0.00013249999999997986,4
BST,shuffled,insert,0.0025673999999999975,5
BST,shuffled,find,0.00015799999999999148,5
BST,shuffled,delete,0.0007081999999999367,5
LinkedList,sorted,insert,0.04947849999999998,1
LinkedList,sorted,find,0.0053706999999999505,1
LinkedList,sorted,delete,0.003119800000000006,1
LinkedList,sorted,insert,0.05800839999999996,2
LinkedList,sorted,find,0.005768099999999943,2
LinkedList,sorted,delete,0.0038080000000000336,2
LinkedList,sorted,insert,0.05770470000000005,3
LinkedList,sorted,find,0.0049146999999999386,3
LinkedList,sorted,delete,0.003128599999999926,3
LinkedList,sorted,insert,0.05588850000000001,4
LinkedList,sorted,find,0.004705699999999924,4
LinkedList,sorted,delete,0.0031733000000000455,4
LinkedList,sorted,insert,0.05095189999999983,5
LinkedList,sorted,find,0.0028690999999998468,5
LinkedList,sorted,delete,0.0018724999999999437,5
HashTable,sorted,insert,0.0004965999999999582,1
HashTable,sorted,find,3.719999999995949e-05,1
HashTable,sorted,delete,2.10999999998851e-05,1
HashTable,sorted,insert,0.0004729999999999457,2
HashTable,sorted,find,3.5199999999901976e-05,2
HashTable,sorted,delete,2.0600000000037255e-05,2
HashTable,sorted,insert,0.00046370000000006684,3
HashTable,sorted,find,3.5699999999971865e-05,3
HashTable,sorted,delete,2.0400000000142526e-05,3
HashTable,sorted,insert,0.0004648999999998793,4
HashTable,sorted,find,3.520000000012402e-05,4
HashTable,sorted,delete,2.0600000000037255e-05,4
HashTable,sorted,insert,0.000461600000000173,5
HashTable,sorted,find,3.690000000000637e-05,5
HashTable,sorted,delete,2.1499999999896602e-05,5
BST,sorted,insert,0.09513269999999996,1
BST,sorted,find,0.006302800000000053,1
BST,sorted,delete,0.006097499999999867,1
BST,sorted,insert,0.12047529999999984,2
BST,sorted,find,0.006049799999999994,2
BST,sorted,delete,0.0062197999999999976,2
BST,sorted,insert,0.10559420000000008,3
BST,sorted,find,0.003817999999999877,3
BST,sorted,delete,0.004166000000000114,3
BST,sorted,insert,0.09572439999999993,4
BST,sorted,find,0.005789299999999997,4
BST,sorted,delete,0.006035599999999919,4
BST,sorted,insert,0.13064960000000014,5
BST,sorted,find,0.006988800000000017,5
BST,sorted,delete,0.006825800000000104,5
1 structure order operation time run
2 LinkedList shuffled insert 0.030281299999999955 1
3 LinkedList shuffled find 0.004695899999999975 1
4 LinkedList shuffled delete 0.0033233999999999764 1
5 LinkedList shuffled insert 0.0353907 2
6 LinkedList shuffled find 0.005563899999999955 2
7 LinkedList shuffled delete 0.0034716999999999665 2
8 LinkedList shuffled insert 0.01944009999999996 3
9 LinkedList shuffled find 0.002577700000000016 3
10 LinkedList shuffled delete 0.0018714000000000786 3
11 LinkedList shuffled insert 0.022181000000000006 4
12 LinkedList shuffled find 0.004234000000000071 4
13 LinkedList shuffled delete 0.0031284999999999785 4
14 LinkedList shuffled insert 0.02823869999999995 5
15 LinkedList shuffled find 0.004262699999999953 5
16 LinkedList shuffled delete 0.0031122999999999568 5
17 HashTable shuffled insert 0.000658699999999901 1
18 HashTable shuffled find 5.359999999998699e-05 1
19 HashTable shuffled delete 2.869999999999262e-05 1
20 HashTable shuffled insert 0.0008105999999999947 2
21 HashTable shuffled find 5.250000000001087e-05 2
22 HashTable shuffled delete 2.8000000000028002e-05 2
23 HashTable shuffled insert 0.0006085000000000118 3
24 HashTable shuffled find 5.270000000001662e-05 3
25 HashTable shuffled delete 2.76000000000165e-05 3
26 HashTable shuffled insert 0.0005973000000000228 4
27 HashTable shuffled find 5.179999999993523e-05 4
28 HashTable shuffled delete 2.740000000001075e-05 4
29 HashTable shuffled insert 0.0005963999999999414 5
30 HashTable shuffled find 5.250000000001087e-05 5
31 HashTable shuffled delete 2.7699999999963865e-05 5
32 BST shuffled insert 0.0025841999999999254 1
33 BST shuffled find 0.0001540000000000985 1
34 BST shuffled delete 0.00013839999999998298 1
35 BST shuffled insert 0.0025424000000000557 2
36 BST shuffled find 0.000152800000000064 2
37 BST shuffled delete 0.00013700000000005375 2
38 BST shuffled insert 0.0025473999999999775 3
39 BST shuffled find 0.00015370000000003436 3
40 BST shuffled delete 0.00013370000000001436 3
41 BST shuffled insert 0.0025645000000000806 4
42 BST shuffled find 0.00015940000000003174 4
43 BST shuffled delete 0.00013249999999997986 4
44 BST shuffled insert 0.0025673999999999975 5
45 BST shuffled find 0.00015799999999999148 5
46 BST shuffled delete 0.0007081999999999367 5
47 LinkedList sorted insert 0.04947849999999998 1
48 LinkedList sorted find 0.0053706999999999505 1
49 LinkedList sorted delete 0.003119800000000006 1
50 LinkedList sorted insert 0.05800839999999996 2
51 LinkedList sorted find 0.005768099999999943 2
52 LinkedList sorted delete 0.0038080000000000336 2
53 LinkedList sorted insert 0.05770470000000005 3
54 LinkedList sorted find 0.0049146999999999386 3
55 LinkedList sorted delete 0.003128599999999926 3
56 LinkedList sorted insert 0.05588850000000001 4
57 LinkedList sorted find 0.004705699999999924 4
58 LinkedList sorted delete 0.0031733000000000455 4
59 LinkedList sorted insert 0.05095189999999983 5
60 LinkedList sorted find 0.0028690999999998468 5
61 LinkedList sorted delete 0.0018724999999999437 5
62 HashTable sorted insert 0.0004965999999999582 1
63 HashTable sorted find 3.719999999995949e-05 1
64 HashTable sorted delete 2.10999999998851e-05 1
65 HashTable sorted insert 0.0004729999999999457 2
66 HashTable sorted find 3.5199999999901976e-05 2
67 HashTable sorted delete 2.0600000000037255e-05 2
68 HashTable sorted insert 0.00046370000000006684 3
69 HashTable sorted find 3.5699999999971865e-05 3
70 HashTable sorted delete 2.0400000000142526e-05 3
71 HashTable sorted insert 0.0004648999999998793 4
72 HashTable sorted find 3.520000000012402e-05 4
73 HashTable sorted delete 2.0600000000037255e-05 4
74 HashTable sorted insert 0.000461600000000173 5
75 HashTable sorted find 3.690000000000637e-05 5
76 HashTable sorted delete 2.1499999999896602e-05 5
77 BST sorted insert 0.09513269999999996 1
78 BST sorted find 0.006302800000000053 1
79 BST sorted delete 0.006097499999999867 1
80 BST sorted insert 0.12047529999999984 2
81 BST sorted find 0.006049799999999994 2
82 BST sorted delete 0.0062197999999999976 2
83 BST sorted insert 0.10559420000000008 3
84 BST sorted find 0.003817999999999877 3
85 BST sorted delete 0.004166000000000114 3
86 BST sorted insert 0.09572439999999993 4
87 BST sorted find 0.005789299999999997 4
88 BST sorted delete 0.006035599999999919 4
89 BST sorted insert 0.13064960000000014 5
90 BST sorted find 0.006988800000000017 5
91 BST sorted delete 0.006825800000000104 5

View File

@ -0,0 +1,377 @@
import sys
sys.setrecursionlimit(10000)
import time
import random
import csv
import os
import matplotlib.pyplot as plt
import numpy as np
def ll_insert(head, name, phone):
new_node = {'name': name, 'phone': phone, 'next': None}
if head is None:
return new_node
if head['name'] > name:
new_node['next'] = head
return new_node
current = head
while current['next'] is not None and current['next']['name'] < name:
current = current['next']
if current['name'] == name:
current['phone'] = phone
return head
new_node['next'] = current['next']
current['next'] = new_node
return head
def ll_find(head, name):
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
def ht_insert(buckets, name, phone):
index = hash(name) % len(buckets)
buckets[index] = ll_insert(buckets[index], name, phone)
def ht_find(buckets, name):
index = hash(name) % len(buckets)
return ll_find(buckets[index], name)
def ht_delete(buckets, name):
index = hash(name) % len(buckets)
buckets[index] = ll_delete(buckets[index], name)
def ht_list_all(buckets):
result = []
for bucket in buckets:
if bucket is not None:
current = bucket
while current is not None:
result.append((current['name'], current['phone']))
current = current['next']
result.sort(key=lambda x: x[0])
return result
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):
current = root
while current is not None:
if name == current['name']:
return current['phone']
elif name < current['name']:
current = current['left']
else:
current = current['right']
return None
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):
result = []
def inorder(node):
if node is not None:
inorder(node['left'])
result.append((node['name'], node['phone']))
inorder(node['right'])
inorder(root)
return result
def generate_records(n, mode='shuffled'):
names = [f"User_{i:05d}" for i in range(n)]
if mode == 'shuffled':
random.shuffle(names)
records = [(name, f"Phone_{i}") for i, name in enumerate(names)]
return records
def benchmark_insert(structure_type, records, buckets_size=512):
if structure_type == 'LinkedList':
head = None
start = time.perf_counter()
for name, phone in records:
head = ll_insert(head, name, phone)
end = time.perf_counter()
return end - start, head
elif structure_type == 'HashTable':
buckets = [None] * buckets_size
start = time.perf_counter()
for name, phone in records:
ht_insert(buckets, name, phone)
end = time.perf_counter()
return end - start, buckets
elif structure_type == 'BST':
root = None
start = time.perf_counter()
for name, phone in records:
root = bst_insert(root, name, phone)
end = time.perf_counter()
return end - start, root
def benchmark_find(structure_type, structure, names):
start = time.perf_counter()
if structure_type == 'LinkedList':
for name in names:
ll_find(structure, name)
elif structure_type == 'HashTable':
for name in names:
ht_find(structure, name)
elif structure_type == 'BST':
for name in names:
bst_find(structure, name)
end = time.perf_counter()
return end - start
def benchmark_delete(structure_type, structure, names):
start = time.perf_counter()
if structure_type == 'LinkedList':
head = structure
for name in names:
head = ll_delete(head, name)
end = time.perf_counter()
return end - start, head
elif structure_type == 'HashTable':
buckets = structure
for name in names:
ht_delete(buckets, name)
end = time.perf_counter()
return end - start, buckets
elif structure_type == 'BST':
root = structure
for name in names:
root = bst_delete(root, name)
end = time.perf_counter()
return end - start, root
def benchmark_list_all(structure_type, structure):
start = time.perf_counter()
if structure_type == 'LinkedList':
ll_list_all(structure)
elif structure_type == 'HashTable':
ht_list_all(structure)
elif structure_type == 'BST':
bst_list_all(structure)
end = time.perf_counter()
return end - start
def main():
random.seed(42)
N = 1000
REPETITIONS = 5
all_results = []
structures = ['LinkedList', 'HashTable', 'BST']
modes = ['shuffled', 'sorted']
os.makedirs('docs/data', exist_ok=True)
for mode in modes:
records = generate_records(N, mode)
find_names = [random.choice(records)[0] for _ in range(100)] + [f"None_{i}" for i in range(10)]
delete_names = [random.choice(records)[0] for _ in range(50)]
for struct in structures:
print(f"Тестирую {struct} на {mode} данных...")
for rep in range(REPETITIONS):
insert_time, structure = benchmark_insert(struct, records)
all_results.append([struct, mode, 'insert', insert_time, rep + 1])
find_time = benchmark_find(struct, structure, find_names)
all_results.append([struct, mode, 'find', find_time, rep + 1])
delete_time, _ = benchmark_delete(struct, structure, delete_names)
all_results.append([struct, mode, 'delete', delete_time, rep + 1])
with open('docs/data/results.csv', 'w', newline='') as f:
writer = csv.writer(f)
writer.writerow(['structure', 'order', 'operation', 'time', 'run'])
writer.writerows(all_results)
print("\nCSV сохранён в docs/data/results.csv")
data = {}
for row in all_results:
key = (row[0], row[1], row[2])
if key not in data:
data[key] = []
data[key].append(row[3])
averaged = []
for key, times in data.items():
avg_time = sum(times) / len(times)
averaged.append([key[0], key[1], key[2], avg_time])
print("\nУСРЕДНЁННЫЕ РЕЗУЛЬТАТЫ (сек):")
print(f"{'Структура':<15} {'Режим':<15} {'Операция':<10} {'Среднее время':<15}")
print("-" * 55)
for row in sorted(averaged, key=lambda x: (x[0], x[1], x[2])):
print(f"{row[0]:<15} {row[1]:<15} {row[2]:<10} {row[3]:<15.6f}")
structures_list = ['LinkedList', 'HashTable', 'BST']
operations_list = ['insert', 'find', 'delete']
fig, axes = plt.subplots(1, 3, figsize=(18, 6))
for i, op in enumerate(operations_list):
ax = axes[i]
x = np.arange(len(structures_list))
width = 0.35
shuffled_times = []
sorted_times = []
for struct in structures_list:
shuffled_times.append(
next(row[3] for row in averaged if row[0] == struct and row[1] == 'shuffled' and row[2] == op))
sorted_times.append(
next(row[3] for row in averaged if row[0] == struct and row[1] == 'sorted' and row[2] == op))
bars1 = ax.bar(x - width / 2, shuffled_times, width, label='Случайный', color='#3498db')
bars2 = ax.bar(x + width / 2, sorted_times, width, label='Отсортированный', color='#e74c3c')
for bar in bars1:
height = bar.get_height()
ax.text(bar.get_x() + bar.get_width() / 2., height + max(shuffled_times) * 0.01,
f'{height:.6f}', ha='center', va='bottom', fontsize=7)
for bar in bars2:
height = bar.get_height()
ax.text(bar.get_x() + bar.get_width() / 2., height + max(sorted_times) * 0.01,
f'{height:.6f}', ha='center', va='bottom', fontsize=7)
ax.set_xlabel('Структура данных')
ax.set_ylabel('Время (сек)')
ax.set_title(f'Операция: {op}')
ax.set_xticks(x)
ax.set_xticklabels(structures_list)
ax.legend()
ax.grid(axis='y', alpha=0.3)
if op == 'find':
ax.set_yscale('log')
plt.suptitle(f'Сравнение производительности структур данных (N = {N} записей)',
fontsize=14, fontweight='bold')
plt.tight_layout()
os.makedirs('docs', exist_ok=True)
plt.savefig('docs/benchmark_results.png', dpi=150, bbox_inches='tight')
plt.show()
print(f"График сохранён в docs/benchmark_results.png")
print("\nАНАЛИЗ РЕЗУЛЬТАТОВ")
print("\n1. Влияние порядка данных на BST:")
bst_shuffled_insert = next(
row[3] for row in averaged if row[0] == 'BST' and row[1] == 'shuffled' and row[2] == 'insert')
bst_sorted_insert = next(
row[3] for row in averaged if row[0] == 'BST' and row[1] == 'sorted' and row[2] == 'insert')
print(f" - Случайные данные: {bst_shuffled_insert:.6f} сек")
print(f" - Отсортированные данные: {bst_sorted_insert:.6f} сек")
if bst_shuffled_insert > 0:
print(f" - Замедление в {bst_sorted_insert / bst_shuffled_insert:.1f} раз")
print(" Причина: на отсортированных данных BST вырождается в связный список (глубина = N)")
print("\n2. Стабильность хеш-таблицы:")
ht_shuffled = next(
row[3] for row in averaged if row[0] == 'HashTable' and row[1] == 'shuffled' and row[2] == 'insert')
ht_sorted = next(row[3] for row in averaged if row[0] == 'HashTable' and row[1] == 'sorted' and row[2] == 'insert')
print(f" - Случайные: {ht_shuffled:.6f} сек")
print(f" - Отсортированные: {ht_sorted:.6f} сек")
print(" Причина: хеш-функция равномерно распределяет ключи независимо от порядка")
print("\n3. Медленный поиск в связном списке:")
ll_search = next(row[3] for row in averaged if row[0] == 'LinkedList' and row[1] == 'shuffled' and row[2] == 'find')
ht_search = next(row[3] for row in averaged if row[0] == 'HashTable' and row[1] == 'shuffled' and row[2] == 'find')
print(f" - LinkedList: {ll_search:.6f} сек")
print(f" - HashTable: {ht_search:.6f} сек")
if ht_search > 0:
print(f" - Хеш-таблица быстрее в {ll_search / ht_search:.1f} раз")
print(" Причина: поиск в списке всегда O(n), в хеш-таблице ~O(1)")
print("\n4. Удаление:")
for label in ['LinkedList', 'HashTable', 'BST']:
del_shuff = next(row[3] for row in averaged if row[0] == label and row[1] == 'shuffled' and row[2] == 'delete')
del_sort = next(row[3] for row in averaged if row[0] == label and row[1] == 'sorted' and row[2] == 'delete')
print(f" - {label:15}: случ.={del_shuff:.6f} сек, отсорт.={del_sort:.6f} сек")
print("\n5. Рекомендации:")
print(" - Частый поиск + вставки → Хеш-таблица")
print(" - Нужна сортировка «из коробки» → Сбалансированное BST (AVL/Красно-чёрное)")
print(" - Только добавление в конец → Связный список")
print(" - Обычный BST опасен на реальных частично упорядоченных данных!")
if __name__ == '__main__':
main()