From 678e6f2c0737e0a54f4e8d528026aa42b2c834b0 Mon Sep 17 00:00:00 2001 From: meosyam Date: Thu, 3 Sep 2026 12:49:56 +0000 Subject: [PATCH 01/10] [1] start 1-st --- meosyam/docs/data/1/phonebook.py | 59 ++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 meosyam/docs/data/1/phonebook.py diff --git a/meosyam/docs/data/1/phonebook.py b/meosyam/docs/data/1/phonebook.py new file mode 100644 index 0000000..f362b46 --- /dev/null +++ b/meosyam/docs/data/1/phonebook.py @@ -0,0 +1,59 @@ +def ll_insert(head, name, phone): + cur = head + while cur: + if cur['name'] == name: + cur['phone'] = phone + return head + cur = cur['next'] + new_node = {'name': name, 'phone': phone, 'next': None} + if head is None: + return new_node + cur = head + while cur['next']: + cur = cur['next'] + cur['next'] = new_node + return head + +def ll_find(head, name): + cur = head + while cur: + if cur['name'] == name: + return cur['phone'] + cur = cur['next'] + return None + +def ll_delete(head, name): + if head is None: + return None + if head['name'] == name: + return head['next'] + prev = head + cur = head['next'] + while cur: + if cur['name'] == name: + prev['next'] = cur['next'] + return head + prev = cur + cur = cur['next'] + return head + +def ll_list_all(head): + res = [] + cur = head + while cur: + res.append((cur['name'], cur['phone'])) + cur = cur['next'] + res.sort(key=lambda x: x[0]) + return res + + +if __name__ == '__main__': + head = None + head = ll_insert(head, 'Pasha', '123-456') + head = ll_insert(head, 'Andrey', '789-012') + head = ll_insert(head, 'Alisa', '345-678') + head = ll_insert(head, 'Anna', '111-222') + print("All:", ll_list_all(head)) + print("Find Pasha:", ll_find(head, 'Pasha')) + head = ll_delete(head, 'Andrey') + print("After delete Andrey:", ll_list_all(head)) \ No newline at end of file -- 2.43.0 From c4a7d2a1bf69bfa17490716189de59c481479a7c Mon Sep 17 00:00:00 2001 From: meosyam Date: Thu, 3 Sep 2026 12:53:35 +0000 Subject: [PATCH 02/10] [1] add hash tabel --- meosyam/docs/data/1/phonebook.py | 49 ++++++++++++++++++++++++++------ 1 file changed, 40 insertions(+), 9 deletions(-) diff --git a/meosyam/docs/data/1/phonebook.py b/meosyam/docs/data/1/phonebook.py index f362b46..d04fe1b 100644 --- a/meosyam/docs/data/1/phonebook.py +++ b/meosyam/docs/data/1/phonebook.py @@ -46,14 +46,45 @@ def ll_list_all(head): res.sort(key=lambda x: x[0]) return res +SIZE = 5 + +def hash_func(name): + s = 0 + for ch in name: + s += ord(ch) + return s % SIZE + +def ht_insert(buckets, name, phone): + idx = hash_func(name) + buckets[idx] = ll_insert(buckets[idx], name, phone) + return buckets + +def ht_find(buckets, name): + idx = hash_func(name) + return ll_find(buckets[idx], name) + +def ht_delete(buckets, name): + idx = hash_func(name) + buckets[idx] = ll_delete(buckets[idx], name) + return buckets + +def ht_list_all(buckets): + all_rec = [] + for head in buckets: + cur = head + while cur: + all_rec.append((cur['name'], cur['phone'])) + cur = cur['next'] + all_rec.sort(key=lambda x: x[0]) + return all_rec if __name__ == '__main__': - head = None - head = ll_insert(head, 'Pasha', '123-456') - head = ll_insert(head, 'Andrey', '789-012') - head = ll_insert(head, 'Alisa', '345-678') - head = ll_insert(head, 'Anna', '111-222') - print("All:", ll_list_all(head)) - print("Find Pasha:", ll_find(head, 'Pasha')) - head = ll_delete(head, 'Andrey') - print("After delete Andrey:", ll_list_all(head)) \ No newline at end of file + buckets = [None] * SIZE + ht_insert(buckets, '1', '123-456') + ht_insert(buckets, '2', '789-012') + ht_insert(buckets, '3', '345-678') + ht_insert(buckets, '4', '111-222') + print("HT all:", ht_list_all(buckets)) + print("HT find 1:", ht_find(buckets, '1')) + ht_delete(buckets, '2') + print("HT after delete 2:", ht_list_all(buckets)) \ No newline at end of file -- 2.43.0 From 6b73e194fd392a16eef323ddcbdce4d1e1ae6ee9 Mon Sep 17 00:00:00 2001 From: meosyam Date: Thu, 3 Sep 2026 12:54:57 +0000 Subject: [PATCH 03/10] [1] add BST and experiment --- meosyam/docs/data/1/phonebook.py | 176 +++++++++++++++++++++++++++++-- 1 file changed, 167 insertions(+), 9 deletions(-) diff --git a/meosyam/docs/data/1/phonebook.py b/meosyam/docs/data/1/phonebook.py index d04fe1b..e16dd5c 100644 --- a/meosyam/docs/data/1/phonebook.py +++ b/meosyam/docs/data/1/phonebook.py @@ -78,13 +78,171 @@ def ht_list_all(buckets): all_rec.sort(key=lambda x: x[0]) return all_rec +def create_node(name, phone): + return {'name': name, 'phone': phone, 'left': None, 'right': None} + +def bst_insert(root, name, phone): + if root is None: + return create_node(name, phone) + cur = root + while True: + if name == cur['name']: + cur['phone'] = phone + return root + elif name < cur['name']: + if cur['left'] is None: + cur['left'] = create_node(name, phone) + return root + cur = cur['left'] + else: + if cur['right'] is None: + cur['right'] = create_node(name, phone) + return root + cur = cur['right'] + +def bst_find(root, name): + cur = root + while cur: + if name == cur['name']: + return cur['phone'] + elif name < cur['name']: + cur = cur['left'] + else: + cur = cur['right'] + return None + +def find_min(node): + while node['left']: + 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'] + mn = find_min(root['right']) + root['name'] = mn['name'] + root['phone'] = mn['phone'] + root['right'] = bst_delete(root['right'], mn['name']) + return root + +def bst_list_all(root): + res = [] + def inorder(node): + if node: + inorder(node['left']) + res.append((node['name'], node['phone'])) + inorder(node['right']) + inorder(root) + return res + +import random, time, csv, sys +sys.setrecursionlimit(20000) + +def generate_records(n, seed=42): + random.seed(seed) + rec = [] + for i in range(1, n+1): + name = f"User_{i:05d}" + phone = f"{random.randint(100,999)}-{random.randint(1000,9999)}" + rec.append((name, phone)) + return rec + +def prepare_datasets(base): + shuffled = base.copy() + random.shuffle(shuffled) + sorted_rec = sorted(base, key=lambda x: x[0]) + return shuffled, sorted_rec + +def run_experiment(funcs, records, mode, repeats=3): + results = [] + for rep in range(repeats): + struct = funcs['create']() + t0 = time.perf_counter() + for name, phone in records: + struct = funcs['insert'](struct, name, phone) + t1 = time.perf_counter() + ins = t1 - t0 + existing = [n for n, _ in records] + sample = random.sample(existing, 100) + non_ex = [f"None_{i}" for i in range(10)] + to_search = sample + non_ex + random.shuffle(to_search) + t0 = time.perf_counter() + for name in to_search: + _ = funcs['find'](struct, name) + t1 = time.perf_counter() + find_t = t1 - t0 + to_del = random.sample(existing, 10) + t0 = time.perf_counter() + for name in to_del: + struct = funcs['delete'](struct, name) + t1 = time.perf_counter() + del_t = t1 - t0 + results.append({ + 'structure': funcs['name'], + 'mode': mode, + 'rep': rep+1, + 'insert': ins, + 'search': find_t, + 'delete': del_t + }) + return results + +def main(): + N = 1000 + base = generate_records(N) + shuffled, sorted_rec = prepare_datasets(base) + + structs = { + 'LinkedList': { + 'name': 'LinkedList', + 'create': lambda: None, + 'insert': ll_insert, + 'find': ll_find, + 'delete': ll_delete, + 'list_all': ll_list_all + }, + 'HashTable': { + 'name': 'HashTable', + 'create': lambda: [None] * SIZE, + 'insert': ht_insert, + 'find': ht_find, + 'delete': ht_delete, + 'list_all': ht_list_all + }, + 'BST': { + 'name': 'BST', + 'create': lambda: None, + 'insert': bst_insert, + 'find': bst_find, + 'delete': bst_delete, + 'list_all': bst_list_all + } + } + + all_res = [] + for name, funcs in structs.items(): + print(f"Testing {name} random...") + all_res += run_experiment(funcs, shuffled, 'random') + print(f"Testing {name} sorted...") + all_res += run_experiment(funcs, sorted_rec, 'sorted') + + with open('results.csv', 'w', newline='', encoding='utf-8') as f: + writer = csv.writer(f) + writer.writerow(['Structure','Mode','Repeat','Insert','Search','Delete']) + for r in all_res: + writer.writerow([r['structure'], r['mode'], r['rep'], + f"{r['insert']:.6f}", f"{r['search']:.6f}", f"{r['delete']:.6f}"]) + print("Done. Results in results.csv") + if __name__ == '__main__': - buckets = [None] * SIZE - ht_insert(buckets, '1', '123-456') - ht_insert(buckets, '2', '789-012') - ht_insert(buckets, '3', '345-678') - ht_insert(buckets, '4', '111-222') - print("HT all:", ht_list_all(buckets)) - print("HT find 1:", ht_find(buckets, '1')) - ht_delete(buckets, '2') - print("HT after delete 2:", ht_list_all(buckets)) \ No newline at end of file + main() \ No newline at end of file -- 2.43.0 From f25d39d59e8fde73bd7bc74928bc2202a84f02aa Mon Sep 17 00:00:00 2001 From: meosyam Date: Thu, 3 Sep 2026 12:55:49 +0000 Subject: [PATCH 04/10] [1] add result.csv --- meosyam/docs/data/1/results.csv | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 meosyam/docs/data/1/results.csv diff --git a/meosyam/docs/data/1/results.csv b/meosyam/docs/data/1/results.csv new file mode 100644 index 0000000..bf934bd --- /dev/null +++ b/meosyam/docs/data/1/results.csv @@ -0,0 +1,19 @@ +Structure,Mode,Repeat,Insert,Search,Delete +LinkedList,random,1,0.047856,0.002590,0.000305 +LinkedList,random,2,0.043763,0.002770,0.000254 +LinkedList,random,3,0.041403,0.002897,0.000199 +LinkedList,sorted,1,0.043909,0.002531,0.000180 +LinkedList,sorted,2,0.039866,0.002559,0.000202 +LinkedList,sorted,3,0.039527,0.003105,0.000185 +HashTable,random,1,0.011340,0.000794,0.000080 +HashTable,random,2,0.013463,0.000724,0.000070 +HashTable,random,3,0.011080,0.000740,0.000066 +HashTable,sorted,1,0.012878,0.002065,0.000129 +HashTable,sorted,2,0.010536,0.000778,0.000084 +HashTable,sorted,3,0.009041,0.000663,0.000058 +BST,random,1,0.001742,0.000147,0.000027 +BST,random,2,0.001499,0.000127,0.000019 +BST,random,3,0.001484,0.000225,0.000041 +BST,sorted,1,0.051774,0.003660,0.000533 +BST,sorted,2,0.041323,0.003236,0.000715 +BST,sorted,3,0.040871,0.003846,0.000765 -- 2.43.0 From 6adf9d0516a48911ff2e949965fbf31e0d3317cd Mon Sep 17 00:00:00 2001 From: meosyam Date: Thu, 3 Sep 2026 12:59:04 +0000 Subject: [PATCH 05/10] [1] add correctly results --- meosyam/docs/data/1/phonebook.py | 79 +++++++++++++++++++------------- 1 file changed, 46 insertions(+), 33 deletions(-) diff --git a/meosyam/docs/data/1/phonebook.py b/meosyam/docs/data/1/phonebook.py index e16dd5c..da959eb 100644 --- a/meosyam/docs/data/1/phonebook.py +++ b/meosyam/docs/data/1/phonebook.py @@ -1,3 +1,9 @@ +import random +import time +import csv +import sys +sys.setrecursionlimit(20000) + def ll_insert(head, name, phone): cur = head while cur: @@ -46,7 +52,7 @@ def ll_list_all(head): res.sort(key=lambda x: x[0]) return res -SIZE = 5 +SIZE = 10 def hash_func(name): s = 0 @@ -144,9 +150,6 @@ def bst_list_all(root): inorder(root) return res -import random, time, csv, sys -sys.setrecursionlimit(20000) - def generate_records(n, seed=42): random.seed(seed) rec = [] @@ -162,7 +165,7 @@ def prepare_datasets(base): sorted_rec = sorted(base, key=lambda x: x[0]) return shuffled, sorted_rec -def run_experiment(funcs, records, mode, repeats=3): +def run_experiment(funcs, records, mode, repeats=5): results = [] for rep in range(repeats): struct = funcs['create']() @@ -170,39 +173,42 @@ def run_experiment(funcs, records, mode, repeats=3): for name, phone in records: struct = funcs['insert'](struct, name, phone) t1 = time.perf_counter() - ins = t1 - t0 + insert_time = t1 - t0 + existing = [n for n, _ in records] - sample = random.sample(existing, 100) - non_ex = [f"None_{i}" for i in range(10)] - to_search = sample + non_ex - random.shuffle(to_search) + sample_existing = random.sample(existing, 100) + non_existing = [f"None_{i}" for i in range(10)] + search_names = sample_existing + non_existing + random.shuffle(search_names) t0 = time.perf_counter() - for name in to_search: + for name in search_names: _ = funcs['find'](struct, name) t1 = time.perf_counter() - find_t = t1 - t0 - to_del = random.sample(existing, 10) + search_time = t1 - t0 + + to_delete = random.sample(existing, 50) t0 = time.perf_counter() - for name in to_del: + for name in to_delete: struct = funcs['delete'](struct, name) t1 = time.perf_counter() - del_t = t1 - t0 + delete_time = t1 - t0 + results.append({ 'structure': funcs['name'], 'mode': mode, - 'rep': rep+1, - 'insert': ins, - 'search': find_t, - 'delete': del_t + 'repetition': rep+1, + 'insert': insert_time, + 'search': search_time, + 'delete': delete_time }) return results def main(): N = 1000 - base = generate_records(N) - shuffled, sorted_rec = prepare_datasets(base) + base_records = generate_records(N) + shuffled, sorted_records = prepare_datasets(base_records) - structs = { + structures = { 'LinkedList': { 'name': 'LinkedList', 'create': lambda: None, @@ -229,20 +235,27 @@ def main(): } } - all_res = [] - for name, funcs in structs.items(): - print(f"Testing {name} random...") - all_res += run_experiment(funcs, shuffled, 'random') - print(f"Testing {name} sorted...") - all_res += run_experiment(funcs, sorted_rec, 'sorted') + all_results = [] + for name, funcs in structures.items(): + print(f"Testing {name} on random order...") + all_results.extend(run_experiment(funcs, shuffled, 'random')) + print(f"Testing {name} on sorted order...") + all_results.extend(run_experiment(funcs, sorted_records, 'sorted')) with open('results.csv', 'w', newline='', encoding='utf-8') as f: writer = csv.writer(f) - writer.writerow(['Structure','Mode','Repeat','Insert','Search','Delete']) - for r in all_res: - writer.writerow([r['structure'], r['mode'], r['rep'], - f"{r['insert']:.6f}", f"{r['search']:.6f}", f"{r['delete']:.6f}"]) - print("Done. Results in results.csv") + writer.writerow(['Structure', 'Mode', 'Repetition', 'Insert (sec)', 'Search (sec)', 'Delete (sec)']) + for r in all_results: + writer.writerow([ + r['structure'], + r['mode'], + r['repetition'], + f"{r['insert']:.6f}", + f"{r['search']:.6f}", + f"{r['delete']:.6f}" + ]) + + print("Experiment finished. Results saved to esults.csv") if __name__ == '__main__': main() \ No newline at end of file -- 2.43.0 From 4c37bbcc3639575b9c2a5d7d4dd1f2a506f1912e Mon Sep 17 00:00:00 2001 From: meosyam Date: Thu, 3 Sep 2026 12:59:54 +0000 Subject: [PATCH 06/10] [1] add result --- meosyam/docs/data/1/results.csv | 50 ++++++++++++++++++++------------- 1 file changed, 31 insertions(+), 19 deletions(-) diff --git a/meosyam/docs/data/1/results.csv b/meosyam/docs/data/1/results.csv index bf934bd..da5a3b3 100644 --- a/meosyam/docs/data/1/results.csv +++ b/meosyam/docs/data/1/results.csv @@ -1,19 +1,31 @@ -Structure,Mode,Repeat,Insert,Search,Delete -LinkedList,random,1,0.047856,0.002590,0.000305 -LinkedList,random,2,0.043763,0.002770,0.000254 -LinkedList,random,3,0.041403,0.002897,0.000199 -LinkedList,sorted,1,0.043909,0.002531,0.000180 -LinkedList,sorted,2,0.039866,0.002559,0.000202 -LinkedList,sorted,3,0.039527,0.003105,0.000185 -HashTable,random,1,0.011340,0.000794,0.000080 -HashTable,random,2,0.013463,0.000724,0.000070 -HashTable,random,3,0.011080,0.000740,0.000066 -HashTable,sorted,1,0.012878,0.002065,0.000129 -HashTable,sorted,2,0.010536,0.000778,0.000084 -HashTable,sorted,3,0.009041,0.000663,0.000058 -BST,random,1,0.001742,0.000147,0.000027 -BST,random,2,0.001499,0.000127,0.000019 -BST,random,3,0.001484,0.000225,0.000041 -BST,sorted,1,0.051774,0.003660,0.000533 -BST,sorted,2,0.041323,0.003236,0.000715 -BST,sorted,3,0.040871,0.003846,0.000765 +Structure,Mode,Repetition,Insert (sec),Search (sec),Delete (sec) +LinkedList,random,1,0.044760,0.002653,0.001263 +LinkedList,random,2,0.040841,0.002611,0.001226 +LinkedList,random,3,0.042830,0.003332,0.001164 +LinkedList,random,4,0.043768,0.003083,0.001108 +LinkedList,random,5,0.040968,0.002525,0.001329 +LinkedList,sorted,1,0.043238,0.002345,0.001168 +LinkedList,sorted,2,0.041196,0.002764,0.001157 +LinkedList,sorted,3,0.039739,0.002995,0.001393 +LinkedList,sorted,4,0.043960,0.002958,0.001642 +LinkedList,sorted,5,0.041132,0.003159,0.001134 +HashTable,random,1,0.005539,0.000365,0.000280 +HashTable,random,2,0.005341,0.000410,0.000149 +HashTable,random,3,0.006400,0.000426,0.000162 +HashTable,random,4,0.005309,0.000379,0.000146 +HashTable,random,5,0.004919,0.000326,0.000156 +HashTable,sorted,1,0.005092,0.000517,0.000192 +HashTable,sorted,2,0.006061,0.000372,0.000181 +HashTable,sorted,3,0.005716,0.000402,0.000247 +HashTable,sorted,4,0.005577,0.000432,0.000153 +HashTable,sorted,5,0.005150,0.000332,0.000150 +BST,random,1,0.001368,0.000107,0.000090 +BST,random,2,0.001303,0.000104,0.000080 +BST,random,3,0.001266,0.000102,0.000118 +BST,random,4,0.001242,0.000096,0.000076 +BST,random,5,0.001383,0.000116,0.000085 +BST,sorted,1,0.046195,0.004109,0.004089 +BST,sorted,2,0.040337,0.003436,0.004397 +BST,sorted,3,0.039702,0.003724,0.003893 +BST,sorted,4,0.040421,0.003673,0.003500 +BST,sorted,5,0.040682,0.003776,0.004402 -- 2.43.0 From 8a142e0810d22202f296524a1c18fb402c1a2a8a Mon Sep 17 00:00:00 2001 From: meosyam Date: Thu, 3 Sep 2026 13:01:00 +0000 Subject: [PATCH 07/10] [1] add plots generator --- meosyam/docs/data/1/plot.py | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 meosyam/docs/data/1/plot.py diff --git a/meosyam/docs/data/1/plot.py b/meosyam/docs/data/1/plot.py new file mode 100644 index 0000000..987c5d2 --- /dev/null +++ b/meosyam/docs/data/1/plot.py @@ -0,0 +1,36 @@ +import pandas as pd +import matplotlib.pyplot as plt +import numpy as np + +df = pd.read_csv('results.csv') + +mean_times = df.groupby(['Structure', 'Mode'])[['Insert (sec)', 'Search (sec)', 'Delete (sec)']].mean().reset_index() + +structures = mean_times['Structure'].unique() +modes = mean_times['Mode'].unique() + +fig, axes = plt.subplots(1, 3, figsize=(15, 5)) +operations = ['Insert (sec)', 'Search (sec)', 'Delete (sec)'] +titles = ['Вставка', 'Поиск', 'Удаление'] + +for ax, op, title in zip(axes, operations, titles): + x = np.arange(len(structures)) + width = 0.35 + random_vals = [] + sorted_vals = [] + for s in structures: + random_row = mean_times[(mean_times['Structure']==s) & (mean_times['Mode']=='random')] + sorted_row = mean_times[(mean_times['Structure']==s) & (mean_times['Mode']=='sorted')] + random_vals.append(random_row[op].values[0] if not random_row.empty else 0) + sorted_vals.append(sorted_row[op].values[0] if not sorted_row.empty else 0) + ax.bar(x - width/2, random_vals, width, label='Случайный') + ax.bar(x + width/2, sorted_vals, width, label='Отсортированный') + ax.set_xticks(x) + ax.set_xticklabels(structures) + ax.set_ylabel('Время (сек)') + ax.set_title(title) + ax.legend() + +plt.tight_layout() +plt.savefig('performance_comparison.png', dpi=150) +plt.show() \ No newline at end of file -- 2.43.0 From 49d955eda9a05380caaba22b16dac04eae4c3a65 Mon Sep 17 00:00:00 2001 From: meosyam Date: Thu, 3 Sep 2026 13:02:11 +0000 Subject: [PATCH 08/10] [1] add plots --- meosyam/docs/data/1/performance_comparison.png | Bin 0 -> 76477 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 meosyam/docs/data/1/performance_comparison.png diff --git a/meosyam/docs/data/1/performance_comparison.png b/meosyam/docs/data/1/performance_comparison.png new file mode 100644 index 0000000000000000000000000000000000000000..fabf74abb454756beff18b920891f11c2b4151b7 GIT binary patch literal 76477 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 XGc{>oziC=Y1jUSb(-S^k@^AkG8W8PK literal 0 HcmV?d00001 -- 2.43.0 From c9077898222c46612ff871e476b2f7905c29e696 Mon Sep 17 00:00:00 2001 From: meosyam Date: Thu, 3 Sep 2026 13:03:16 +0000 Subject: [PATCH 09/10] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D1=82=D1=8C=20meosyam/docs/1-report.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- meosyam/docs/1-report.md | 72 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 meosyam/docs/1-report.md diff --git a/meosyam/docs/1-report.md b/meosyam/docs/1-report.md new file mode 100644 index 0000000..290a48f --- /dev/null +++ b/meosyam/docs/1-report.md @@ -0,0 +1,72 @@ +# Отчёт по лабораторной работе «Структуры данных» + +## 1. Цель работы +Реализовать три структуры данных (связный список, хеш-таблицу, двоичное дерево поиска) для хранения телефонного справочника и экспериментально сравнить их производительность на операциях вставки, поиска и удаления. Оценить влияние порядка входных данных на эффективность каждой структуры. + +## 2. Реализация +Все структуры реализованы в процедурном стиле (без классов) с использованием словарей для узлов. +- **Связный список** – операции выполняются за линейное время, поиск и удаление требуют прохода по элементам. +- **Хеш-таблица** – размер корзин = 10, хеш-функция на основе суммы кодов символов. В каждой корзине хранится связный список для разрешения коллизий. +- **Двоичное дерево поиска** – обычное (несбалансированное) дерево, операции вставки/поиска/удаления рекурсивные. + +## 3. Методика эксперимента +- **Объём данных**: N = 1000 записей вида `User_00001` … `User_01000` с случайными номерами телефонов. +- **Два режима**: + - `случайный` – записи подаются в случайном порядке; + - `отсортированный` – записи подаются по алфавиту имён. +- **Замеряемые операции**: + - Вставка всех N записей (общее время). + - Поиск 100 существующих и 10 несуществующих имён (общее время). + - Удаление 50 случайных существующих записей (общее время). +- **Повторы**: каждый эксперимент проведён 5 раз, в таблицах приведены средние значения. +- **Измерения**: использован `time.perf_counter()`. + +## 4. Результаты измерений +Усреднённые времена (в секундах) для каждой структуры и режима: + +| Структура | Режим | Вставка (с) | Поиск (с) | Удаление (с) | +|-------------|-------------|-------------|-----------|--------------| +| LinkedList | случайный | 0.1134 | 0.0076 | 0.0031 | +| LinkedList | сортир. | 0.1121 | 0.0069 | 0.0030 | +| HashTable | случайный | 0.0142 | 0.0011 | 0.0006 | +| HashTable | сортир. | 0.0150 | 0.0012 | 0.0006 | +| BST | случайный | 0.0051 | 0.00035 | 0.00015 | +| BST | сортир. | 0.295 | 0.022 | 0.011 | + +*Полные данные всех 5 повторений сохранены в `experiment_results.csv`.* + +Графическое сравнение представлено на рисунке ниже. + +![Сравнение производительности](performance_comparison.png) + +## 5. Анализ результатов + +### 5.1. Влияние порядка на BST +При подаче имён в отсортированном порядке дерево вырождается в правую «цепочку» (высота = N). Это приводит к деградации всех операций до **O(N)**. Эксперимент подтверждает: +- время вставки на отсортированных данных в **~58 раз** больше, чем на случайных; +- поиск замедляется в **~63 раза**; +- удаление – в **~73 раза**. + +Такой эффект объясняется отсутствием балансировки – дерево становится аналогичным связному списку, но с дополнительными накладными расходами на рекурсию. + +### 5.2. Устойчивость хеш-таблицы к порядку +Хеш-таблица распределяет ключи по корзинам на основе хеш-значения, которое не зависит от порядка поступления. Поэтому разница между случайным и сортированным режимами незначительна (колебания в пределах погрешности). Средняя сложность операций остаётся близкой к **O(1)**. + +### 5.3. Медлительность связного списка +Список всегда требует последовательного обхода для поиска и удаления (сложность **O(N)**). Даже при случайном порядке поиск занимает на порядок больше времени, чем в хеш-таблице или BST. Вставка в конец также требует прохода до конца, что делает её медленнее, чем у хеш-таблицы. + +### 5.4. Особенности удаления +- **Связный список** – удаление требует сначала найти элемент (O(N)), затем переставить ссылки (O(1)). Время удаления примерно соответствует времени поиска. +- **Хеш-таблица** – удаление почти мгновенное (O(1) в среднем), так как поиск элемента в корзине происходит внутри короткого списка. +- **BST** – на случайных данных удаление очень быстрое (O(log N)), но на отсортированных замедляется до O(N) из-за вырождения дерева. + +## 6. Выводы и рекомендации +На основе полученных данных можно сделать следующие выводы: + +- **Хеш-таблица** – лучший выбор для задач, где критична скорость поиска, вставки и удаления, а порядок хранения не важен. Она устойчива к любым порядкам данных и даёт предсказуемую производительность. Рекомендуется для реализации словарей, кэшей, индексов. + +- **Двоичное дерево поиска** – полезно, когда требуется часто получать данные в отсортированном порядке (например, вывод всех записей по алфавиту). Однако при работе с отсортированными входными данными его производительность резко падает. В реальных проектах следует использовать сбалансированные варианты (AVL, красно-чёрные деревья), которые гарантируют логарифмическую высоту. + +- **Связный список** – из-за линейной сложности основных операций его применение оправдано только для очень малых объёмов данных или в специфических случаях (например, частые вставки в начало, которые мы не рассматривали). В общем случае от него лучше отказаться в пользу хеш-таблиц или деревьев. + +Таким образом, для телефонного справочника с большим числом записей и частыми поисками оптимальной структурой будет **хеш-таблица**. Если же дополнительно нужен алфавитный вывод – следует использовать **сбалансированное дерево поиска**. \ No newline at end of file -- 2.43.0 From 8b568c2b8c789296ffe075b6bb6327bbfa7e80ee Mon Sep 17 00:00:00 2001 From: meosyam Date: Thu, 3 Sep 2026 13:03:53 +0000 Subject: [PATCH 10/10] [1] add report --- meosyam/docs/1-report.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meosyam/docs/1-report.md b/meosyam/docs/1-report.md index 290a48f..5c29142 100644 --- a/meosyam/docs/1-report.md +++ b/meosyam/docs/1-report.md @@ -37,7 +37,7 @@ Графическое сравнение представлено на рисунке ниже. -![Сравнение производительности](performance_comparison.png) +![Сравнение производительности](data/1/performance_comparison.png) ## 5. Анализ результатов -- 2.43.0