[2] 1-st_ex

This commit is contained in:
agafonovdm 2026-05-25 12:56:25 +03:00
parent 057dfb01af
commit 153f2a092c
2 changed files with 109 additions and 49 deletions

View File

@ -1,6 +1,11 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import time import time
import random import random
import csv import csv
import sys
sys.setrecursionlimit(30000)
def ll_create_node(name, phone): def ll_create_node(name, phone):
return {'name': name, 'phone': phone, 'next': None} return {'name': name, 'phone': phone, 'next': None}
@ -59,7 +64,7 @@ def ll_list_all(head):
def hash_function(name, table_size): def hash_function(name, table_size):
return sum(ord(c) for c in name) % table_size return sum(ord(c) for c in name) % table_size
def ht_create_table(size=1000): def ht_create_table(size=2000):
return [None] * size return [None] * size
def ht_insert(table, name, phone): def ht_insert(table, name, phone):
@ -92,25 +97,36 @@ def bst_insert(root, name, phone):
if root is None: if root is None:
return bst_create_node(name, phone) return bst_create_node(name, phone)
if name < root['name']: current = root
root['left'] = bst_insert(root['left'], name, phone) while True:
elif name > root['name']: if name < current['name']:
root['right'] = bst_insert(root['right'], name, phone) if current['left'] is None:
else: current['left'] = bst_create_node(name, phone)
root['phone'] = phone break
else:
current = current['left']
elif name > current['name']:
if current['right'] is None:
current['right'] = bst_create_node(name, phone)
break
else:
current = current['right']
else:
current['phone'] = phone
break
return root return root
def bst_find(root, name): def bst_find(root, name):
if root is None: current = root
return None while current is not None:
if name < current['name']:
if name < root['name']: current = current['left']
return bst_find(root['left'], name) elif name > current['name']:
elif name > root['name']: current = current['right']
return bst_find(root['right'], name) else:
else: return current['phone']
return root['phone'] return None
def bst_find_min(node): def bst_find_min(node):
current = node current = node
@ -122,34 +138,63 @@ def bst_delete(root, name):
if root is None: if root is None:
return None return None
if name < root['name']: parent = None
root['left'] = bst_delete(root['left'], name) current = root
elif name > root['name']:
root['right'] = bst_delete(root['right'], name) while current is not None and current['name'] != name:
else: parent = current
if root['left'] is None: if name < current['name']:
return root['right'] current = current['left']
elif root['right'] is None: else:
return root['left'] current = current['right']
if current is None:
return root
if current['left'] is None or current['right'] is None:
if current['left'] is not None:
child = current['left']
else:
child = current['right']
min_node = bst_find_min(root['right']) if parent is None:
root['name'] = min_node['name'] return child
root['phone'] = min_node['phone']
root['right'] = bst_delete(root['right'], min_node['name']) if parent['left'] == current:
parent['left'] = child
else:
parent['right'] = child
else:
successor_parent = current
successor = current['right']
while successor['left'] is not None:
successor_parent = successor
successor = successor['left']
current['name'] = successor['name']
current['phone'] = successor['phone']
if successor_parent['left'] == successor:
successor_parent['left'] = successor['right']
else:
successor_parent['right'] = successor['right']
return root return root
def bst_list_all(root): def bst_list_all(root):
records = [] records = []
stack = []
current = root
def inorder(node): while stack or current is not None:
if node is None: while current is not None:
return stack.append(current)
inorder(node['left']) current = current['left']
records.append((node['name'], node['phone'])) current = stack.pop()
inorder(node['right']) records.append((current['name'], current['phone']))
current = current['right']
inorder(root)
return records return records
def generate_data(n=10000): def generate_data(n=10000):
@ -162,11 +207,7 @@ def generate_data(n=10000):
def run_experiment(structure_name, insert_func, find_func, delete_func, def run_experiment(structure_name, insert_func, find_func, delete_func,
list_all_func, init_func, records, n_find=100): list_all_func, init_func, records, n_find=100):
if structure_name == "HashTable": data = init_func()
data = init_func(1000)
else:
data = init_func()
names = [r[0] for r in records] names = [r[0] for r in records]
start = time.perf_counter() start = time.perf_counter()
@ -201,22 +242,22 @@ def run_experiment(structure_name, insert_func, find_func, delete_func,
return insert_time, find_time, delete_time return insert_time, find_time, delete_time
def main(): def main():
print("Генерация тестовых данных...") print("Generating test data...")
records_shuffled, records_sorted = generate_data(10000) records_shuffled, records_sorted = generate_data(10000)
results = [] results = []
structures = [ structures = [
("LinkedList", ll_insert, ll_find, ll_delete, ll_list_all, lambda: None), ("LinkedList", ll_insert, ll_find, ll_delete, ll_list_all, lambda: None),
("HashTable", ht_insert, ht_find, ht_delete, ht_list_all, lambda: ht_create_table(1000)), ("HashTable", ht_insert, ht_find, ht_delete, ht_list_all, lambda: ht_create_table(2000)),
("BST", bst_insert, bst_find, bst_delete, bst_list_all, lambda: None) ("BST", bst_insert, bst_find, bst_delete, bst_list_all, lambda: None)
] ]
for mode_name, records in [("random", records_shuffled), ("sorted", records_sorted)]: for mode_name, records in [("random", records_shuffled), ("sorted", records_sorted)]:
print(f"\nРежим: {mode_name}") print(f"\nMode: {mode_name}")
for struct_name, insert_f, find_f, delete_f, list_f, init_f in structures: for struct_name, insert_f, find_f, delete_f, list_f, init_f in structures:
print(f" Тестирование {struct_name}...") print(f" Testing {struct_name}...")
times = [] times = []
for run in range(5): for run in range(5):
@ -224,7 +265,7 @@ def main():
struct_name, insert_f, find_f, delete_f, list_f, init_f, records struct_name, insert_f, find_f, delete_f, list_f, init_f, records
) )
times.append((insert_t, find_t, delete_t)) times.append((insert_t, find_t, delete_t))
print(f" Запуск {run+1}: вставка={insert_t:.4f}s, поиск={find_t:.4f}s, удаление={delete_t:.4f}s") print(f" Run {run+1}: insert={insert_t:.4f}s, find={find_t:.4f}s, delete={delete_t:.4f}s")
avg_insert = sum(t[0] for t in times) / 5 avg_insert = sum(t[0] for t in times) / 5
avg_find = sum(t[1] for t in times) / 5 avg_find = sum(t[1] for t in times) / 5
@ -240,12 +281,12 @@ def main():
writer.writerows(results) writer.writerows(results)
print("\n" + "="*60) print("\n" + "="*60)
print("РЕЗУЛЬТАТЫ (среднее за 5 запусков):") print("RESULTS (average over 5 runs):")
print("="*60) print("="*60)
for row in results: for row in results:
print(f"{row[0]:12} | {row[1]:8} | {row[2]:8} | {row[3]:.6f} сек") print(f"{row[0]:12} | {row[1]:8} | {row[2]:8} | {row[3]:.6f} sec")
print("\nРезультаты сохранены в results.csv") print("\nResults saved to results.csv")
if __name__ == "__main__": if __name__ == "__main__":
main() main()

View File

@ -0,0 +1,19 @@
Structure,Mode,Operation,Time_seconds
LinkedList,random,insert,3.115811080000276
LinkedList,random,find,0.02396312000018952
LinkedList,random,delete,0.016048219999720458
HashTable,random,insert,0.18448304000012286
HashTable,random,find,0.0012929600005008978
HashTable,random,delete,0.0009329200001957361
BST,random,insert,0.017231119999996734
BST,random,find,0.00014155999961076304
BST,random,delete,9.299999983340968e-05
LinkedList,sorted,insert,2.780292439999903
LinkedList,sorted,find,0.02136590000045544
LinkedList,sorted,delete,0.014907859999584615
HashTable,sorted,insert,0.16707750000023225
HashTable,sorted,find,0.0012113199998566415
HashTable,sorted,delete,0.0008899600001313956
BST,sorted,insert,3.844869280000421
BST,sorted,find,0.031808019999880345
BST,sorted,delete,0.016554539999560802
1 Structure Mode Operation Time_seconds
2 LinkedList random insert 3.115811080000276
3 LinkedList random find 0.02396312000018952
4 LinkedList random delete 0.016048219999720458
5 HashTable random insert 0.18448304000012286
6 HashTable random find 0.0012929600005008978
7 HashTable random delete 0.0009329200001957361
8 BST random insert 0.017231119999996734
9 BST random find 0.00014155999961076304
10 BST random delete 9.299999983340968e-05
11 LinkedList sorted insert 2.780292439999903
12 LinkedList sorted find 0.02136590000045544
13 LinkedList sorted delete 0.014907859999584615
14 HashTable sorted insert 0.16707750000023225
15 HashTable sorted find 0.0012113199998566415
16 HashTable sorted delete 0.0008899600001313956
17 BST sorted insert 3.844869280000421
18 BST sorted find 0.031808019999880345
19 BST sorted delete 0.016554539999560802