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")