2026-rff_mp/VolkovVA/cod.py

369 lines
10 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import random as rnd
import time
import csv
# СВЯЗНЫЙ СПИСОК
def ll_insert(head, name, phone):
new_node = {'name': name, 'phone': phone, 'next': None}
if head is None:
return new_node
current = head
while current is not None:
if current['name'] == name:
current['phone'] = phone
return head
if current['next'] is None:
break
current = 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 sort_records(lst):
n = len(lst)
for i in range(n):
for j in range(0, n-i-1):
if lst[j][0] > lst[j + 1][0]:
lst[j], lst[j + 1] = lst[j + 1], lst[j]
return lst
def ll_list_all(head):
record = []
current = head
while current is not None:
record += [(current['name'], current['phone'])]
current = current['next']
res = sort_records(record)
return res
# ХЕШ-ТАБЛИЦА
def def_hash(name, size):
hash_value = 0
for char in name:
hash_value += ord(char)
final_idx = hash_value % size
return final_idx
def ht_insert(buckets, name, phone):
size = len(buckets)
idx = def_hash(name, size)
buckets[idx] = ll_insert(buckets[idx], name, phone)
return buckets
def ht_find(buckets, name):
size = len(buckets)
idx = def_hash(name, size)
return ll_find(buckets[idx], name)
def ht_delete(buckets, name):
size = len(buckets)
idx = def_hash(name, size)
buckets[idx] = ll_delete(buckets[idx], name)
return buckets
def ht_list_all(buckets):
res = []
for head in buckets:
current = head
while current is not None:
res += [(current['name'], current['phone'])]
current = current['next']
return sort_records(res)
# ДВОИЧНОЕ ДЕРЕВО ПОИСКА
def bst_insert(root, name, phone):
new_node = {'name': name, 'phone': phone, 'left': None, 'right': None}
if root is None:
return new_node
current = root
while True:
if name == current['name']:
current['phone'] = phone
break
elif name < current['name']:
if current['left'] is None:
current['left'] = new_node
break
current = current['left']
else:
if current['right'] is None:
current['right'] = new_node
break
current = current['right']
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
p_node = None
current = root
while current is not None and current['name'] != name:
p_node = current
if name < current['name']:
current = current['left']
else:
current = current['right']
if current is None:
return root
if current['left'] is None and current['right'] is None:
if p_node is None:
return None
if p_node['left'] is current:
p_node['left'] = None
else:
p_node['right'] = None
return root
if current['left'] is None:
c_node = current['right']
elif current['right'] is None:
c_node = current['left']
else:
succ_parent = current
succ = current['right']
while succ['left']:
succ_parent = succ
succ = succ['left']
current['name'], current['phone'] = succ['name'], succ['phone']
if succ_parent['left'] is succ:
succ_parent['left'] = succ['right']
else:
succ_parent['right'] = succ['right']
return root
if p_node is None:
return c_node
if p_node['left'] is current:
p_node['left'] = c_node
else:
p_node['right'] = c_node
return root
def bst_list_all(root):
record = []
def helper(node):
if node is not None:
helper(node['left'])
nonlocal record
record += [(node['name'], node['phone'])]
helper(node['right'])
helper(root)
return record
# ЭКСПЕРИМЕНТАЛЬНАЯ ЧАСТЬ
if __name__ == '__main__':
N = 10000
records = []
for i in range(N):
name = f"User_{i:05d}"
phone = f"+7-{rnd.randint(100, 999)}-{rnd.randint(100, 999)}-{rnd.randint(1000, 9999)}"
records.append((name, phone))
records_shuffled = records[:]
rnd.shuffle(records_shuffled)
records_sorted = sorted(records, key=lambda x: x[0])
s_names = []
for i in range(100):
s_names.append(records_shuffled[i][0])
for i in range(10):
s_names.append(f"None_{i}")
d_names = []
sampled = rnd.sample(records_shuffled, 50)
for item in sampled:
d_names.append(item[0])
print("Начало замеров...")
results = [["Структура", "Режим", "Операция", "Время (сек)"]]
# ПРОВЕДЕНИЕ ЗАМЕРОВ
# СВЯЗНЫЙ СПИСОК
for mode_name, data in [("случайный", records_shuffled), ("отсортированный", records_sorted)]:
s_ins = 0
s_fnd=0
s_del=0
for _ in range(5):
ll = None
t1 = time.perf_counter()
for name, phone in data:
ll = ll_insert(ll, name, phone)
time_ins = time.perf_counter() - t1
s_ins += time_ins
results.append(["LinkedList", mode_name, "вставка", time_ins])
t1 = time.perf_counter()
for name in s_names:
ll_find(ll, name)
time_fnd = time.perf_counter() - t1
s_fnd += time_fnd
results.append(["LinkedList", mode_name, "поиск", time_fnd])
t1 = time.perf_counter()
for name in d_names:
ll = ll_delete(ll, name)
time_del = time.perf_counter() - t1
s_del += time_del
results.append(["LinkedList", mode_name, "удаление", time_del])
print(f" Связный список ({mode_name}) | Среднее за 5 замеров ")
print(f"Вставка: {s_ins/5:.5f} сек.")
print(f"Поиск: {s_fnd/5:.5f} сек.")
print(f"Удаление: {s_del/5:.5f} сек.")
print("-" * 40)
# ХЕШ-ТАБЛИЦА
for mode_name, data in [("случайный", records_shuffled), ("отсортированный", records_sorted)]:
s_ins = 0
s_fnd=0
s_del =0
for _ in range(5):
ht = [None] * 2000
t1 = time.perf_counter()
for name, phone in data:
ht = ht_insert(ht, name, phone)
time_ins = time.perf_counter() - t1
s_ins += time_ins
results.append(["HashTable", mode_name, "вставка", time_ins])
t1 = time.perf_counter()
for name in s_names:
ht_find(ht, name)
time_fnd = time.perf_counter() - t1
s_fnd += time_fnd
results.append(["HashTable", mode_name, "поиск", time_fnd])
t1 = time.perf_counter()
for name in d_names:
ht = ht_delete(ht, name)
time_del = time.perf_counter() - t1
s_del += time_del
results.append(["HashTable", mode_name, "удаление", time_del])
print(f" Хеш-таблица ({mode_name}) | Среднее за 5 замеров ")
print(f"Вставка: {s_ins/5:.5f} сек.")
print(f"Поиск: {s_fnd/5:.5f} сек.")
print(f"Удаление: {s_del/5:.5f} сек.")
print("-" * 40)
# ДЕРЕВО
for mode_name, data in [("случайный", records_shuffled), ("отсортированный", records_sorted)]:
s_ins = 0
s_fnd = 0
s_del = 0
for _ in range(5):
bst = None
t1 = time.perf_counter()
for name, phone in data:
bst = bst_insert(bst, name, phone)
time_ins = time.perf_counter() - t1
s_ins += time_ins
results.append(["BST", mode_name, "вставка", time_ins])
t1 = time.perf_counter()
for name in s_names:
bst_find(bst, name)
time_fnd = time.perf_counter() - t1
s_fnd += time_fnd
results.append(["BST", mode_name, "поиск", time_fnd])
t1 = time.perf_counter()
for name in d_names:
bst = bst_delete(bst, name)
time_del = time.perf_counter() - t1
s_del += time_del
results.append(["BST", mode_name, "удаление", time_del])
print(f"Двоичное дерево ({mode_name}) | Среднее за 5 замеров ")
print(f"Вставка: {s_ins/5:.5f} сек.")
print(f"Поиск: {s_fnd/5:.5f} сек.")
print(f"Удаление: {s_del/5:.5f} сек.")
print("-" * 40)
# Сохранение результатов
with open("docs/data/results.csv", "w", newline="", encoding="utf-8") as f:
writer = csv.writer(f)
writer.writerows(results)