diff --git a/novikovsd/answers.txt b/novikovsd/answers.txt deleted file mode 100644 index e69de29..0000000 diff --git a/novikovsd/docs/comparison.png b/novikovsd/docs/comparison.png deleted file mode 100644 index f5391f3..0000000 Binary files a/novikovsd/docs/comparison.png and /dev/null differ diff --git a/novikovsd/docs/data/results.csv b/novikovsd/docs/data/results.csv deleted file mode 100644 index 8f3fbef..0000000 --- a/novikovsd/docs/data/results.csv +++ /dev/null @@ -1,91 +0,0 @@ -Structure,Mode,Operation,Repeat,Time_sec -LinkedList,shuffled,insert,1,2.7093895999996676 -LinkedList,shuffled,find,1,0.03374979999989591 -LinkedList,shuffled,delete,1,0.013558000000102766 -LinkedList,shuffled,insert,2,2.7178337999998803 -LinkedList,shuffled,find,2,0.034134699999867735 -LinkedList,shuffled,delete,2,0.014517000000068947 -LinkedList,shuffled,insert,3,2.714019300000018 -LinkedList,shuffled,find,3,0.033463599999777216 -LinkedList,shuffled,delete,3,0.013073999999960506 -LinkedList,shuffled,insert,4,2.7287836000000425 -LinkedList,shuffled,find,4,0.03680309999981546 -LinkedList,shuffled,delete,4,0.015249600000061037 -LinkedList,shuffled,insert,5,2.722151500000109 -LinkedList,shuffled,find,5,0.03397850000010294 -LinkedList,shuffled,delete,5,0.015159399999902234 -LinkedList,sorted,insert,1,2.5469852999999603 -LinkedList,sorted,find,1,0.054332700000031764 -LinkedList,sorted,delete,1,0.013600199999928009 -LinkedList,sorted,insert,2,2.5274411999998847 -LinkedList,sorted,find,2,0.05538109999997687 -LinkedList,sorted,delete,2,0.014902900000379304 -LinkedList,sorted,insert,3,2.516689800000222 -LinkedList,sorted,find,3,0.05497689999992872 -LinkedList,sorted,delete,3,0.012883400000191614 -LinkedList,sorted,insert,4,2.528048000000126 -LinkedList,sorted,find,4,0.05493479999995543 -LinkedList,sorted,delete,4,0.012835600000016711 -LinkedList,sorted,insert,5,2.524865200000022 -LinkedList,sorted,find,5,0.05850929999996879 -LinkedList,sorted,delete,5,0.015247499999986758 -HashTable,shuffled,insert,1,0.014068699999825185 -HashTable,shuffled,find,1,0.00015149999990171636 -HashTable,shuffled,delete,1,7.469999991371878e-05 -HashTable,shuffled,insert,2,0.014089899999817135 -HashTable,shuffled,find,2,0.00014630000032411772 -HashTable,shuffled,delete,2,7.090000008247443e-05 -HashTable,shuffled,insert,3,0.013962699999865436 -HashTable,shuffled,find,3,0.00014389999978448031 -HashTable,shuffled,delete,3,6.919999987076153e-05 -HashTable,shuffled,insert,4,0.01387350000004517 -HashTable,shuffled,find,4,0.00014590000000680448 -HashTable,shuffled,delete,4,7.129999994504033e-05 -HashTable,shuffled,insert,5,0.014038799999980256 -HashTable,shuffled,find,5,0.00014629999986937037 -HashTable,shuffled,delete,5,7.400000004054164e-05 -HashTable,sorted,insert,1,0.01933809999991354 -HashTable,sorted,find,1,0.0001700000002529123 -HashTable,sorted,delete,1,8.489999981975416e-05 -HashTable,sorted,insert,2,0.014241200000014942 -HashTable,sorted,find,2,0.00016050000022005406 -HashTable,sorted,delete,2,7.110000024113106e-05 -HashTable,sorted,insert,3,0.013520700000299257 -HashTable,sorted,find,3,0.0001594999998815183 -HashTable,sorted,delete,3,6.890000031489762e-05 -HashTable,sorted,insert,4,0.014047699999991892 -HashTable,sorted,find,4,0.00015880000000834116 -HashTable,sorted,delete,4,6.900000016685226e-05 -HashTable,sorted,insert,5,0.013919299999997747 -HashTable,sorted,find,5,0.0001606000000720087 -HashTable,sorted,delete,5,7.239999968078337e-05 -BST,shuffled,insert,1,0.021964499999739928 -BST,shuffled,find,1,0.00016349999987141928 -BST,shuffled,delete,1,0.00017139999999926658 -BST,shuffled,insert,2,0.022091499999987718 -BST,shuffled,find,2,0.00016019999975469545 -BST,shuffled,delete,2,0.00015999999959603883 -BST,shuffled,insert,3,0.02204540000002453 -BST,shuffled,find,3,0.00016659999982948648 -BST,shuffled,delete,3,0.00015170000006037299 -BST,shuffled,insert,4,0.022226300000056654 -BST,shuffled,find,4,0.00016219999997701962 -BST,shuffled,delete,4,0.0001567000003888097 -BST,shuffled,insert,5,0.021780500000204484 -BST,shuffled,find,5,0.00015780000012455275 -BST,shuffled,delete,5,0.0001606000000720087 -BST,sorted,insert,1,6.614551799999845 -BST,sorted,find,1,0.0005606999998235551 -BST,sorted,delete,1,0.0634210999996867 -BST,sorted,insert,2,6.625495499999943 -BST,sorted,find,2,0.0005660000001626031 -BST,sorted,delete,2,0.06643010000016147 -BST,sorted,insert,3,6.6205589999999575 -BST,sorted,find,3,0.0005686999998033571 -BST,sorted,delete,3,0.06744570000000749 -BST,sorted,insert,4,6.639703100000133 -BST,sorted,find,4,0.0005636999999296677 -BST,sorted,delete,4,0.0661270999999033 -BST,sorted,insert,5,6.6624039000002995 -BST,sorted,find,5,0.0005601999996542872 -BST,sorted,delete,5,0.057285699999738426 diff --git a/novikovsd/hashtab.py b/novikovsd/hashtab.py deleted file mode 100644 index d889419..0000000 --- a/novikovsd/hashtab.py +++ /dev/null @@ -1,306 +0,0 @@ -import time -import random -import csv -import os -import sys - -sys.setrecursionlimit(30000) - -def ll_insert(head, name, phone): - curr = head - while curr is not None: - if curr['name'] == name: - curr['phone'] = phone - return head - curr = curr['next'] - new_node = {'name': name, 'phone': phone, 'next': head} - return new_node - - -def ll_find(head, name): - curr = head - while curr is not None: - if curr['name'] == name: - return curr['phone'] - curr = curr['next'] - return None - - -def ll_delete(head, name): - if head is None: - return None - if head['name'] == name: - return head['next'] - prev = head - curr = head['next'] - while curr is not None: - if curr['name'] == name: - prev['next'] = curr['next'] - return head - prev = curr - curr = curr['next'] - return head - - -def ll_list_all(head): - entries = [] - curr = head - while curr is not None: - entries.append((curr['name'], curr['phone'])) - curr = curr['next'] - entries.sort(key=lambda x: x[0]) - return entries - -def _hash(name, bucket_count): - h = 0 - for ch in name: - h = (h * 31 + ord(ch)) % bucket_count - return h - - -def ht_create(bucket_count=2000): - return [None] * bucket_count - - -def ht_insert(buckets, name, phone): - idx = _hash(name, len(buckets)) - buckets[idx] = ll_insert(buckets[idx], name, phone) - - -def ht_find(buckets, name): - idx = _hash(name, len(buckets)) - return ll_find(buckets[idx], name) - - -def ht_delete(buckets, name): - idx = _hash(name, len(buckets)) - buckets[idx] = ll_delete(buckets[idx], name) - - -def ht_list_all(buckets): - entries = [] - for head in buckets: - curr = head - while curr is not None: - entries.append((curr['name'], curr['phone'])) - curr = curr['next'] - entries.sort(key=lambda x: x[0]) - return entries - -def bst_insert(root, name, phone): - new_node = {'name': name, 'phone': phone, 'left': None, 'right': None} - if root is None: - return new_node - - parent = None - curr = root - while curr is not None: - parent = curr - if name < curr['name']: - curr = curr['left'] - elif name > curr['name']: - curr = curr['right'] - else: - curr['phone'] = phone - return root - - if name < parent['name']: - parent['left'] = new_node - else: - parent['right'] = new_node - return root - - -def bst_find(root, name): - while root is not None: - if name == root['name']: - return root['phone'] - elif name < root['name']: - root = root['left'] - else: - root = root['right'] - return None - - -def _bst_min_node(node): - while node and node['left'] is not None: - node = node['left'] - return node - - -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'] - min_node = _bst_min_node(root['right']) - root['name'] = min_node['name'] - root['phone'] = min_node['phone'] - root['right'] = bst_delete(root['right'], min_node['name']) - return root - - -def bst_list_all(root): - def inorder(node, res): - if node is None: - return - inorder(node['left'], res) - res.append((node['name'], node['phone'])) - inorder(node['right'], res) - result = [] - inorder(root, result) - return result - -def generate_test_data(n=10000): - records = [(f"User_{i:05d}", f"+7-999-{i:05d}") for i in range(n)] - records_sorted = records[:] - records_shuffled = records[:] - random.shuffle(records_shuffled) - return records_sorted, records_shuffled - -def measure_insert(struct_name, records): - start = time.perf_counter() - if struct_name == "LinkedList": - head = None - for name, phone in records: - head = ll_insert(head, name, phone) - obj = head - elif struct_name == "HashTable": - buckets = ht_create(bucket_count=2000) - for name, phone in records: - ht_insert(buckets, name, phone) - obj = buckets - elif struct_name == "BST": - root = None - for name, phone in records: - root = bst_insert(root, name, phone) - obj = root - else: - raise ValueError(f"Unknown structure: {struct_name}") - elapsed = time.perf_counter() - start - return elapsed, obj - -def measure_find(obj, struct_name, existing_names, nonexisting_names): - start = time.perf_counter() - for name in existing_names: - if struct_name == "LinkedList": - ll_find(obj, name) - elif struct_name == "HashTable": - ht_find(obj, name) - else: - bst_find(obj, name) - for name in nonexisting_names: - if struct_name == "LinkedList": - ll_find(obj, name) - elif struct_name == "HashTable": - ht_find(obj, name) - else: - bst_find(obj, name) - return time.perf_counter() - start - -def measure_delete(obj, struct_name, names_to_delete): - start = time.perf_counter() - if struct_name == "LinkedList": - for name in names_to_delete: - obj = ll_delete(obj, name) - elif struct_name == "HashTable": - for name in names_to_delete: - ht_delete(obj, name) - else: - for name in names_to_delete: - obj = bst_delete(obj, name) - elapsed = time.perf_counter() - start - return elapsed, obj - -def run_experiment(n=10000, repeats=5): - records_sorted, records_shuffled = generate_test_data(n) - existing_names = [name for name, _ in records_sorted[:100]] - nonexisting_names = [f"None_{i}" for i in range(10)] - all_names = [name for name, _ in records_sorted] - - structures = ["LinkedList", "HashTable", "BST"] - modes = [("shuffled", records_shuffled), ("sorted", records_sorted)] - - results = [] - for struct_name in structures: - for mode_name, records in modes: - for rep in range(repeats): - insert_time, obj = measure_insert(struct_name, records) - results.append([struct_name, mode_name, "insert", rep+1, insert_time]) - - find_time = measure_find(obj, struct_name, existing_names, nonexisting_names) - results.append([struct_name, mode_name, "find", rep+1, find_time]) - - random.seed(rep) - to_delete = random.sample(all_names, 50) - delete_time, obj = measure_delete(obj, struct_name, to_delete) - results.append([struct_name, mode_name, "delete", rep+1, delete_time]) - - return results - -def save_results_to_csv(results, filename="docs/data/results.csv"): - os.makedirs(os.path.dirname(filename), exist_ok=True) - with open(filename, 'w', newline='', encoding='utf-8') as f: - writer = csv.writer(f) - writer.writerow(["Structure", "Mode", "Operation", "Repeat", "Time_sec"]) - writer.writerows(results) - print(f"Результаты сохранены в {filename}") - - -def aggregate_results(results): - from collections import defaultdict - agg = defaultdict(list) - for row in results: - struct, mode, op, rep, t = row - agg[(struct, mode, op)].append(t) - means = {k: sum(v)/len(v) for k, v in agg.items()} - return means - - -def plot_results(means, output_dir="docs"): - try: - import matplotlib.pyplot as plt - import numpy as np - except ImportError: - print("Matplotlib не установлен. Графики не построены.") - return - - operations = ["insert", "find", "delete"] - structures = ["LinkedList", "HashTable", "BST"] - modes = ["shuffled", "sorted"] - - fig, axes = plt.subplots(1, 3, figsize=(15, 5)) - for idx, op in enumerate(operations): - ax = axes[idx] - x = np.arange(len(structures)) - width = 0.35 - shuffled_means = [means.get((struct, "shuffled", op), 0) for struct in structures] - sorted_means = [means.get((struct, "sorted", op), 0) for struct in structures] - ax.bar(x - width/2, shuffled_means, width, label='случайный порядок', color='skyblue') - ax.bar(x + width/2, sorted_means, width, label='отсортированный порядок', color='salmon') - ax.set_xticks(x) - ax.set_xticklabels(structures, rotation=15) - ax.set_ylabel('Время (сек)') - ax.set_title(f'{op.upper()}') - ax.legend() - ax.grid(axis='y', linestyle='--', alpha=0.7) - - plt.tight_layout() - plt.savefig(os.path.join(output_dir, "comparison.png"), dpi=150) - plt.show() - -if __name__ == "__main__": - results = run_experiment(n=10000, repeats=5) - save_results_to_csv(results) - means = aggregate_results(results) - print("\nСреднее время по операциям (сек):") - for (struct, mode, op), t in sorted(means.items()): - print(f"{struct:12} {mode:8} {op:6} : {t:.6f}") - plot_results(means) \ No newline at end of file