2026-rff_mp/VildyaevAV/task1.py

345 lines
6.5 KiB
Python
Raw Normal View History

2026-05-21 16:32:48 +00:00
import random
import time
import csv
import sys
sys.setrecursionlimit(30000)
# =========================
# LINKED LIST
# =========================
def ll_insert(head, name, phone):
current = head
while current:
if current["name"] == name:
current["phone"] = phone
return head
current = current["next"]
new_node = {
"name": name,
"phone": phone,
"next": head
}
return new_node
def ll_find(head, name):
current = head
while current:
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"]:
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:
result.append((current["name"], current["phone"]))
current = current["next"]
return sorted(result)
# =========================
# HASH TABLE
# =========================
TABLE_SIZE = 1000
def hash_func(name):
return sum(ord(c) for c in name) % TABLE_SIZE
def ht_insert(buckets, name, phone):
index = hash_func(name)
buckets[index] = ll_insert(buckets[index], name, phone)
def ht_find(buckets, name):
index = hash_func(name)
return ll_find(buckets[index], name)
def ht_delete(buckets, name):
index = hash_func(name)
buckets[index] = ll_delete(buckets[index], name)
def ht_list_all(buckets):
result = []
for bucket in buckets:
result.extend(ll_list_all(bucket))
return sorted(result)
# =========================
# BST
# =========================
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"]
if name < root["name"]:
return bst_find(root["left"], name)
return bst_find(root["right"], name)
def bst_min(node):
current = node
while current["left"]:
current = current["left"]
return current
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"]
temp = bst_min(root["right"])
root["name"] = temp["name"]
root["phone"] = temp["phone"]
root["right"] = bst_delete(root["right"], temp["name"])
return root
def bst_list_all(root):
if root is None:
return []
return (
bst_list_all(root["left"])
+ [(root["name"], root["phone"])]
+ bst_list_all(root["right"])
)
# =========================
# TEST DATA
# =========================
N = 10000
records = [
(f"User_{i:05d}", str(random.randint(100000, 999999)))
for i in range(N)
]
records_shuffled = records[:]
random.shuffle(records_shuffled)
records_sorted = sorted(records)
# =========================
# BENCHMARK
# =========================
results = [
["Structure", "Mode", "Operation", "Time"]
]
def benchmark_linked_list(records_input, mode):
global results
head = None
start = time.perf_counter()
for name, phone in records_input:
head = ll_insert(head, name, phone)
end = time.perf_counter()
results.append(["LinkedList", mode, "insert", end - start])
sample = random.sample(records_input, 100)
start = time.perf_counter()
for name, _ in sample:
ll_find(head, name)
end = time.perf_counter()
results.append(["LinkedList", mode, "find", end - start])
start = time.perf_counter()
for name, _ in sample[:50]:
head = ll_delete(head, name)
end = time.perf_counter()
results.append(["LinkedList", mode, "delete", end - start])
def benchmark_hash_table(records_input, mode):
global results
buckets = [None] * TABLE_SIZE
start = time.perf_counter()
for name, phone in records_input:
ht_insert(buckets, name, phone)
end = time.perf_counter()
results.append(["HashTable", mode, "insert", end - start])
sample = random.sample(records_input, 100)
start = time.perf_counter()
for name, _ in sample:
ht_find(buckets, name)
end = time.perf_counter()
results.append(["HashTable", mode, "find", end - start])
start = time.perf_counter()
for name, _ in sample[:50]:
ht_delete(buckets, name)
end = time.perf_counter()
results.append(["HashTable", mode, "delete", end - start])
def benchmark_bst(records_input, mode):
global results
root = None
start = time.perf_counter()
for name, phone in records_input:
root = bst_insert(root, name, phone)
end = time.perf_counter()
results.append(["BST", mode, "insert", end - start])
sample = random.sample(records_input, 100)
start = time.perf_counter()
for name, _ in sample:
bst_find(root, name)
end = time.perf_counter()
results.append(["BST", mode, "find", end - start])
start = time.perf_counter()
for name, _ in sample[:50]:
root = bst_delete(root, name)
end = time.perf_counter()
results.append(["BST", mode, "delete", end - start])
# =========================
# RUN TESTS
# =========================
benchmark_linked_list(records_shuffled, "random")
benchmark_linked_list(records_sorted, "sorted")
benchmark_hash_table(records_shuffled, "random")
benchmark_hash_table(records_sorted, "sorted")
benchmark_bst(records_shuffled, "random")
benchmark_bst(records_sorted, "sorted")
# =========================
# SAVE CSV
# =========================
with open("results.csv", "w", newline="") as f:
writer = csv.writer(f)
writer.writerows(results)
print("Done! Results saved to results.csv")