From dde7c1fce5019898b321f91a6893da6a292a7c36 Mon Sep 17 00:00:00 2001 From: VildyaevAV Date: Thu, 21 May 2026 19:32:48 +0300 Subject: [PATCH] [1] data structures --- VildyaevAV/docs/report.md | 0 VildyaevAV/results.csv | 19 +++ VildyaevAV/task1.py | 345 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 364 insertions(+) create mode 100644 VildyaevAV/docs/report.md create mode 100644 VildyaevAV/results.csv create mode 100644 VildyaevAV/task1.py diff --git a/VildyaevAV/docs/report.md b/VildyaevAV/docs/report.md new file mode 100644 index 0000000..e69de29 diff --git a/VildyaevAV/results.csv b/VildyaevAV/results.csv new file mode 100644 index 0000000..04d57be --- /dev/null +++ b/VildyaevAV/results.csv @@ -0,0 +1,19 @@ +Structure,Mode,Operation,Time +LinkedList,random,insert,2.179811800000607 +LinkedList,random,find,0.019349800000782125 +LinkedList,random,delete,0.01508280000052764 +LinkedList,sorted,insert,1.7312419000008958 +LinkedList,sorted,find,0.01827670000056969 +LinkedList,sorted,delete,0.01452439999775379 +HashTable,random,insert,0.13504540000212728 +HashTable,random,find,0.0014485000028798822 +HashTable,random,delete,0.0010058999978355132 +HashTable,sorted,insert,0.12148510000042734 +HashTable,sorted,find,0.0012095999991288409 +HashTable,sorted,delete,0.0008018999978958163 +BST,random,insert,0.016409800002293196 +BST,random,find,0.0001536999989184551 +BST,random,delete,9.40000027185306e-05 +BST,sorted,insert,15.077545899999677 +BST,sorted,find,0.05779409999740892 +BST,sorted,delete,0.03522280000106548 diff --git a/VildyaevAV/task1.py b/VildyaevAV/task1.py new file mode 100644 index 0000000..dc8dc4d --- /dev/null +++ b/VildyaevAV/task1.py @@ -0,0 +1,345 @@ +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") \ No newline at end of file -- 2.43.0