import time import random 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['next']: current = current['next'] current['next'] = new_node return head 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): records = [] current = head while current: records.append((current['name'], current['phone'])) current = current['next'] records.sort(key=lambda x: x[0]) return records def ht_insert(buckets, name, phone): index = hash(name) % len(buckets) buckets[index] = ll_insert(buckets[index], name, phone) return buckets def ht_find(buckets, name): index = hash(name) % len(buckets) return ll_find(buckets[index], name) def ht_delete(buckets, name): index = hash(name) % len(buckets) buckets[index] = ll_delete(buckets[index], name) return buckets def ht_list_all(buckets): records = [] for bucket in buckets: current = bucket while current: records.append((current['name'], current['phone'])) current = current['next'] records.sort(key=lambda x: x[0]) return records 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'] elif name < root['name']: return bst_find(root['left'], name) else: return bst_find(root['right'], name) def bst_min_node(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'] elif root['right'] is None: return root['left'] temp = bst_min_node(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): records = [] if root: records.extend(bst_list_all(root['left'])) records.append((root['name'], root['phone'])) records.extend(bst_list_all(root['right'])) return records def generate_records(n): records = [(f"User_{i:05d}", f"+7-999-{i:07d}") for i in range(n)] records_shuffled = records.copy() random.shuffle(records_shuffled) records_sorted = sorted(records, key=lambda x: x[0]) return records_shuffled, records_sorted def run_experiment(structure_name, records, insert_func, find_func, delete_func, list_all_func, buckets=None): if structure_name == "HashTable": buckets = [None] * 1000 start = time.perf_counter() if structure_name == "HashTable": for name, phone in records: buckets = insert_func(buckets, name, phone) else: root_or_head = None for name, phone in records: if structure_name == "LinkedList": root_or_head = insert_func(root_or_head, name, phone) else: root_or_head = insert_func(root_or_head, name, phone) insert_time = time.perf_counter() - start existing_names = [name for name, _ in records[:100]] nonexisting_names = [f"None_{i}" for i in range(10)] all_searches = existing_names + nonexisting_names random.shuffle(all_searches) start = time.perf_counter() for name in all_searches: if structure_name == "HashTable": find_func(buckets, name) else: find_func(root_or_head, name) find_time = time.perf_counter() - start delete_names = [records[i][0] for i in random.sample(range(len(records)), min(50, len(records)))] start = time.perf_counter() for name in delete_names: if structure_name == "HashTable": buckets = delete_func(buckets, name) else: root_or_head = delete_func(root_or_head, name) delete_time = time.perf_counter() - start return insert_time, find_time, delete_time def main(): N = 1000 records_shuffled, records_sorted = generate_records(N) results = [] for mode, records in [("случайный", records_shuffled), ("отсортированный", records_sorted)]: for run in range(5): ins_ll, find_ll, del_ll = run_experiment("LinkedList", records, ll_insert, ll_find, ll_delete, ll_list_all) results.append(["LinkedList", mode, "вставка", ins_ll, run+1]) results.append(["LinkedList", mode, "поиск", find_ll, run+1]) results.append(["LinkedList", mode, "удаление", del_ll, run+1]) ins_ht, find_ht, del_ht = run_experiment("HashTable", records, ht_insert, ht_find, ht_delete, ht_list_all) results.append(["HashTable", mode, "вставка", ins_ht, run+1]) results.append(["HashTable", mode, "поиск", find_ht, run+1]) results.append(["HashTable", mode, "удаление", del_ht, run+1]) ins_bst, find_bst, del_bst = run_experiment("BST", records, bst_insert, bst_find, bst_delete, bst_list_all) results.append(["BST", mode, "вставка", ins_bst, run+1]) results.append(["BST", mode, "поиск", find_bst, run+1]) results.append(["BST", mode, "удаление", del_bst, run+1]) with open("results.csv", "w", newline="", encoding="utf-8") as f: writer = csv.writer(f) writer.writerow(["Структура", "Режим", "Операция", "Время (сек)", "Повторение"]) writer.writerows(results) avg_results = {} for row in results: key = (row[0], row[1], row[2]) if key not in avg_results: avg_results[key] = [] avg_results[key].append(row[3]) with open("avg_results.csv", "w", newline="", encoding="utf-8") as f: writer = csv.writer(f) writer.writerow(["Структура", "Режим", "Операция", "Среднее время (сек)"]) for (struct, mode, op), times in avg_results.items(): writer.writerow([struct, mode, op, sum(times)/len(times)]) if __name__ == "__main__": main()