[1]SokolovEN #278
BIN
SokolovEN/docs/performance_comparison.png
Normal file
BIN
SokolovEN/docs/performance_comparison.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 152 KiB |
109
SokolovEN/docs/results.csv
Normal file
109
SokolovEN/docs/results.csv
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
Структура,Режим,Операция,Время (сек)
|
||||
LinkedList,случайный,insert,8.347676099999717
|
||||
LinkedList,случайный,find,0.057291300000088086
|
||||
LinkedList,случайный,delete,0.033828600000106235
|
||||
HashTable,случайный,insert,0.019370900000012625
|
||||
HashTable,случайный,find,0.00013010000020585721
|
||||
HashTable,случайный,delete,6.919999987076153e-05
|
||||
BST,случайный,insert,0.045051300000068295
|
||||
BST,случайный,find,0.00039449999985663453
|
||||
BST,случайный,delete,0.0002380000000812288
|
||||
LinkedList,случайный,insert,8.37124969999968
|
||||
LinkedList,случайный,find,0.05748009999979331
|
||||
LinkedList,случайный,delete,0.033760199999960605
|
||||
HashTable,случайный,insert,0.019708000000264292
|
||||
HashTable,случайный,find,0.00012689999994108803
|
||||
HashTable,случайный,delete,6.789999997636187e-05
|
||||
BST,случайный,insert,0.04297489999999016
|
||||
BST,случайный,find,0.00036730000010720687
|
||||
BST,случайный,delete,0.00021289999995133257
|
||||
LinkedList,случайный,insert,8.501181300000098
|
||||
LinkedList,случайный,find,0.06136560000004465
|
||||
LinkedList,случайный,delete,0.033985800000209565
|
||||
HashTable,случайный,insert,0.018909500000063417
|
||||
HashTable,случайный,find,0.00012770000012096716
|
||||
HashTable,случайный,delete,6.809999968027114e-05
|
||||
BST,случайный,insert,0.040991700000176934
|
||||
BST,случайный,find,0.000367999999980384
|
||||
BST,случайный,delete,0.0002165999999306223
|
||||
LinkedList,случайный,insert,8.44069300000001
|
||||
LinkedList,случайный,find,0.05868799999961993
|
||||
LinkedList,случайный,delete,0.033578099999886035
|
||||
HashTable,случайный,insert,0.017991799999890645
|
||||
HashTable,случайный,find,0.00012880000031145755
|
||||
HashTable,случайный,delete,6.720000010318472e-05
|
||||
BST,случайный,insert,0.04100620000008348
|
||||
BST,случайный,find,0.0003681999996842933
|
||||
BST,случайный,delete,0.00021289999995133257
|
||||
LinkedList,случайный,insert,8.554321999999956
|
||||
LinkedList,случайный,find,0.059801599999900645
|
||||
LinkedList,случайный,delete,0.03381919999992533
|
||||
HashTable,случайный,insert,0.01814620000004652
|
||||
HashTable,случайный,find,0.0001274000001103559
|
||||
HashTable,случайный,delete,6.649999977526022e-05
|
||||
BST,случайный,insert,0.04181910000033895
|
||||
BST,случайный,find,0.0003727000002982095
|
||||
BST,случайный,delete,0.00021440000000438886
|
||||
LinkedList,отсортированный,insert,8.395491100000072
|
||||
LinkedList,отсортированный,find,0.061166899999989255
|
||||
LinkedList,отсортированный,delete,0.03749729999981355
|
||||
HashTable,отсортированный,insert,0.08801780000021608
|
||||
HashTable,отсортированный,find,0.00013059999992037774
|
||||
HashTable,отсортированный,delete,7.719999985056347e-05
|
||||
BST,отсортированный,insert,18.99293549999993
|
||||
BST,отсортированный,find,0.17561569999998028
|
||||
BST,отсортированный,delete,0.10195840000005774
|
||||
LinkedList,отсортированный,insert,8.345957999999882
|
||||
LinkedList,отсортированный,find,0.06071609999980865
|
||||
LinkedList,отсортированный,delete,0.03802029999997103
|
||||
HashTable,отсортированный,insert,0.017803299999741284
|
||||
HashTable,отсортированный,find,0.00013059999992037774
|
||||
HashTable,отсортированный,delete,7.66999996812956e-05
|
||||
BST,отсортированный,insert,19.05815190000021
|
||||
BST,отсортированный,find,0.17255539999996472
|
||||
BST,отсортированный,delete,0.10364929999968808
|
||||
LinkedList,отсортированный,insert,8.494904799999858
|
||||
LinkedList,отсортированный,find,0.06991719999996349
|
||||
LinkedList,отсортированный,delete,0.0375927000000047
|
||||
HashTable,отсортированный,insert,0.018229599999813217
|
||||
HashTable,отсортированный,find,0.00013249999983599992
|
||||
HashTable,отсортированный,delete,8.08000004326459e-05
|
||||
BST,отсортированный,insert,19.04517390000001
|
||||
BST,отсортированный,find,0.17560349999985192
|
||||
BST,отсортированный,delete,0.10177699999985634
|
||||
LinkedList,отсортированный,insert,8.241154399999687
|
||||
LinkedList,отсортированный,find,0.08371720000013738
|
||||
LinkedList,отсортированный,delete,0.05189399999972011
|
||||
HashTable,отсортированный,insert,0.09625940000023547
|
||||
HashTable,отсортированный,find,0.0001606000000720087
|
||||
HashTable,отсортированный,delete,8.960000013757963e-05
|
||||
BST,отсортированный,insert,19.152932399999827
|
||||
BST,отсортированный,find,0.17190189999973882
|
||||
BST,отсортированный,delete,0.09978479999972478
|
||||
LinkedList,отсортированный,insert,8.261084100000062
|
||||
LinkedList,отсортированный,find,0.060434499999701075
|
||||
LinkedList,отсортированный,delete,0.03753559999995559
|
||||
HashTable,отсортированный,insert,0.018136799999865616
|
||||
HashTable,отсортированный,find,0.00013009999975110986
|
||||
HashTable,отсортированный,delete,7.819999973435188e-05
|
||||
BST,отсортированный,insert,19.379212700000153
|
||||
BST,отсортированный,find,0.17449820000001637
|
||||
BST,отсортированный,delete,0.0995044000001144
|
||||
LinkedList,случайный,insert (СРЕДНЕЕ),8.443024419999892
|
||||
LinkedList,случайный,find (СРЕДНЕЕ),0.05892531999988933
|
||||
LinkedList,случайный,delete (СРЕДНЕЕ),0.033794380000017554
|
||||
LinkedList,отсортированный,insert (СРЕДНЕЕ),8.347718479999912
|
||||
LinkedList,отсортированный,find (СРЕДНЕЕ),0.06719037999991997
|
||||
LinkedList,отсортированный,delete (СРЕДНЕЕ),0.040507979999892994
|
||||
HashTable,случайный,insert (СРЕДНЕЕ),0.0188252800000555
|
||||
HashTable,случайный,find (СРЕДНЕЕ),0.00012818000013794517
|
||||
HashTable,случайный,delete (СРЕДНЕЕ),6.77799998811679e-05
|
||||
HashTable,отсортированный,insert (СРЕДНЕЕ),0.047689379999974336
|
||||
HashTable,отсортированный,find (СРЕДНЕЕ),0.0001368799998999748
|
||||
HashTable,отсортированный,delete (СРЕДНЕЕ),8.04999999672873e-05
|
||||
BST,случайный,insert (СРЕДНЕЕ),0.04236864000013156
|
||||
BST,случайный,find (СРЕДНЕЕ),0.0003741399999853456
|
||||
BST,случайный,delete (СРЕДНЕЕ),0.00021895999998378102
|
||||
BST,отсортированный,insert (СРЕДНЕЕ),19.125681280000027
|
||||
BST,отсортированный,find (СРЕДНЕЕ),0.17403493999991043
|
||||
BST,отсортированный,delete (СРЕДНЕЕ),0.10133477999988827
|
||||
|
257
SokolovEN/docs/СтруктурыДанных.py
Normal file
257
SokolovEN/docs/СтруктурыДанных.py
Normal file
|
|
@ -0,0 +1,257 @@
|
|||
import random
|
||||
import time
|
||||
import csv
|
||||
import sys
|
||||
|
||||
|
||||
sys.setrecursionlimit(20000)
|
||||
|
||||
|
||||
# 1. СВЯЗНЫЙ СПИСОК
|
||||
def ll_insert(head, name, phone):
|
||||
curr = head
|
||||
while curr:
|
||||
if curr['name'] == name:
|
||||
curr['phone'] = phone
|
||||
return head
|
||||
curr = curr['next']
|
||||
|
||||
new_node = {'name': name, 'phone': phone, 'next': None}
|
||||
if head is None:
|
||||
return new_node
|
||||
|
||||
curr = head
|
||||
while curr['next']:
|
||||
curr = curr['next']
|
||||
curr['next'] = new_node
|
||||
return head
|
||||
|
||||
|
||||
def ll_find(head, name):
|
||||
curr = head
|
||||
while curr:
|
||||
if curr['name'] == name:
|
||||
return curr['phone']
|
||||
curr = curr['next']
|
||||
return None
|
||||
|
||||
|
||||
def ll_delete(head, name):
|
||||
if head is None:
|
||||
return None
|
||||
if head['name'] == name:
|
||||
return head['next']
|
||||
|
||||
curr = head
|
||||
while curr['next']:
|
||||
if curr['next']['name'] == name:
|
||||
curr['next'] = curr['next']['next']
|
||||
return head
|
||||
curr = curr['next']
|
||||
return head
|
||||
|
||||
|
||||
def ll_list_all(head):
|
||||
res = []
|
||||
curr = head
|
||||
while curr:
|
||||
res.append((curr['name'], curr['phone']))
|
||||
curr = curr['next']
|
||||
res.sort(key=lambda x: x[0])
|
||||
return res
|
||||
|
||||
|
||||
|
||||
# 2. ХЕШ-ТАБЛИЦА
|
||||
BUCKET_COUNT = 1024
|
||||
|
||||
|
||||
def ht_insert(buckets, name, phone):
|
||||
idx = hash(name) % BUCKET_COUNT
|
||||
buckets[idx] = ll_insert(buckets[idx], name, phone)
|
||||
|
||||
|
||||
def ht_find(buckets, name):
|
||||
idx = hash(name) % BUCKET_COUNT
|
||||
return ll_find(buckets[idx], name)
|
||||
|
||||
|
||||
def ht_delete(buckets, name):
|
||||
idx = hash(name) % BUCKET_COUNT
|
||||
buckets[idx] = ll_delete(buckets[idx], name)
|
||||
|
||||
|
||||
def ht_list_all(buckets):
|
||||
res = []
|
||||
for head in buckets:
|
||||
curr = head
|
||||
while curr:
|
||||
res.append((curr['name'], curr['phone']))
|
||||
curr = curr['next']
|
||||
res.sort(key=lambda x: x[0])
|
||||
return res
|
||||
|
||||
|
||||
|
||||
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']
|
||||
elif name < root['name']:
|
||||
return bst_find(root['left'], name)
|
||||
else:
|
||||
return bst_find(root['right'], name)
|
||||
|
||||
|
||||
def _bst_find_min(node):
|
||||
curr = node
|
||||
while curr['left'] is not None:
|
||||
curr = curr['left']
|
||||
return curr
|
||||
|
||||
|
||||
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']
|
||||
elif root['right'] is None:
|
||||
return root['left']
|
||||
else:
|
||||
successor = _bst_find_min(root['right'])
|
||||
root['name'] = successor['name']
|
||||
root['phone'] = successor['phone']
|
||||
root['right'] = bst_delete(root['right'], successor['name'])
|
||||
return root
|
||||
|
||||
|
||||
def bst_list_all(root):
|
||||
res = []
|
||||
|
||||
def inorder(node):
|
||||
if node:
|
||||
inorder(node['left'])
|
||||
res.append((node['name'], node['phone']))
|
||||
inorder(node['right'])
|
||||
|
||||
inorder(root)
|
||||
return res
|
||||
|
||||
|
||||
|
||||
# ЭКСПЕРИМЕНТАЛЬНАЯ ЧАСТЬ
|
||||
def run_experiments():
|
||||
N = 10000
|
||||
base_records = [(f"User_{i:05d}", f"100{i:05d}") for i in range(N)]
|
||||
|
||||
records_sorted = sorted(base_records, key=lambda x: x[0])
|
||||
records_shuffled = base_records[:]
|
||||
random.shuffle(records_shuffled)
|
||||
|
||||
all_names = [r[0] for r in base_records]
|
||||
find_existing = random.sample(all_names, 100)
|
||||
find_non_existing = [f"Missing_{i}" for i in range(10)]
|
||||
delete_targets = random.sample(all_names, 50)
|
||||
|
||||
all_results = []
|
||||
structures = ["LinkedList", "HashTable", "BST"]
|
||||
data_modes = [("случайный", records_shuffled), ("отсортированный", records_sorted)]
|
||||
|
||||
for mode_name, records in data_modes:
|
||||
print(f"\n Режим: {mode_name}")
|
||||
for run in range(1, 6):
|
||||
print(f" запуск {run}/5")
|
||||
|
||||
|
||||
head = None
|
||||
t = time.perf_counter()
|
||||
for n, p in records: head = ll_insert(head, n, p)
|
||||
t_ins = time.perf_counter() - t
|
||||
|
||||
t = time.perf_counter()
|
||||
for n in find_existing + find_non_existing: ll_find(head, n)
|
||||
t_find = time.perf_counter() - t
|
||||
|
||||
t = time.perf_counter()
|
||||
for n in delete_targets: head = ll_delete(head, n)
|
||||
t_del = time.perf_counter() - t
|
||||
|
||||
all_results.append(["LinkedList", mode_name, "insert", t_ins])
|
||||
all_results.append(["LinkedList", mode_name, "find", t_find])
|
||||
all_results.append(["LinkedList", mode_name, "delete", t_del])
|
||||
|
||||
|
||||
buckets = [None] * BUCKET_COUNT
|
||||
t = time.perf_counter()
|
||||
for n, p in records: ht_insert(buckets, n, p)
|
||||
t_ins = time.perf_counter() - t
|
||||
|
||||
t = time.perf_counter()
|
||||
for n in find_existing + find_non_existing: ht_find(buckets, n)
|
||||
t_find = time.perf_counter() - t
|
||||
|
||||
t = time.perf_counter()
|
||||
for n in delete_targets: ht_delete(buckets, n)
|
||||
t_del = time.perf_counter() - t
|
||||
|
||||
all_results.append(["HashTable", mode_name, "insert", t_ins])
|
||||
all_results.append(["HashTable", mode_name, "find", t_find])
|
||||
all_results.append(["HashTable", mode_name, "delete", t_del])
|
||||
|
||||
|
||||
root = None
|
||||
t = time.perf_counter()
|
||||
for n, p in records: root = bst_insert(root, n, p)
|
||||
t_ins = time.perf_counter() - t
|
||||
|
||||
t = time.perf_counter()
|
||||
for n in find_existing + find_non_existing: bst_find(root, n)
|
||||
t_find = time.perf_counter() - t
|
||||
|
||||
t = time.perf_counter()
|
||||
for n in delete_targets: root = bst_delete(root, n)
|
||||
t_del = time.perf_counter() - t
|
||||
|
||||
all_results.append(["BST", mode_name, "insert", t_ins])
|
||||
all_results.append(["BST", mode_name, "find", t_find])
|
||||
all_results.append(["BST", mode_name, "delete", t_del])
|
||||
|
||||
|
||||
averages = []
|
||||
for struct in structures:
|
||||
for mode in ["случайный", "отсортированный"]:
|
||||
for op in ["insert", "find", "delete"]:
|
||||
times = [r[3] for r in all_results if r[0] == struct and r[1] == mode and r[2] == op]
|
||||
avg = sum(times) / len(times)
|
||||
averages.append([struct, mode, f"{op} (СРЕДНЕЕ)", avg])
|
||||
|
||||
final_csv_data = [["Структура", "Режим", "Операция", "Время (сек)"]] + all_results + averages
|
||||
|
||||
with open("results.csv", "w", newline="", encoding="utf-8-sig") as f:
|
||||
writer = csv.writer(f)
|
||||
writer.writerows(final_csv_data)
|
||||
|
||||
return all_results, averages
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raw_data, avg_data = run_experiments()
|
||||
|
||||
35
SokolovEN/docs/графики.py
Normal file
35
SokolovEN/docs/графики.py
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
import pandas as pd
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
|
||||
df = pd.read_csv("results.csv", encoding="utf-8-sig")
|
||||
df_avg = df[df["Операция"].str.contains("СРЕДНЕЕ")].copy()
|
||||
df_avg["Операция"] = df_avg["Операция"].str.replace(" (СРЕДНЕЕ)", "")
|
||||
|
||||
modes = ["случайный", "отсортированный"]
|
||||
operations = ["insert", "find", "delete"]
|
||||
structures = ["LinkedList", "HashTable", "BST"]
|
||||
|
||||
x = np.arange(len(structures))
|
||||
width = 0.35
|
||||
|
||||
fig, axes = plt.subplots(1, 3, figsize=(18, 5))
|
||||
|
||||
for i, op in enumerate(operations):
|
||||
ax = axes[i]
|
||||
for j, mode in enumerate(modes):
|
||||
mask = (df_avg["Операция"] == op) & (df_avg["Режим"] == mode)
|
||||
times = df_avg[mask]["Время (сек)"].values
|
||||
label = "Случайные данные" if mode == "случайный" else "Отсортированные данные"
|
||||
ax.bar(x + j * width, times, width, label=label)
|
||||
|
||||
ax.set_title(f"Операция: {op.upper()}")
|
||||
ax.set_xticks(x + width / 2)
|
||||
ax.set_xticklabels(structures)
|
||||
ax.set_ylabel("Время (сек)")
|
||||
ax.legend()
|
||||
ax.grid(axis="y", linestyle="--", alpha=0.7)
|
||||
|
||||
plt.tight_layout()
|
||||
plt.savefig("performance_comparison.png", dpi=300)
|
||||
plt.show()
|
||||
Loading…
Reference in New Issue
Block a user