From e5f1418c1beaeb5afd470a673bad0e5616eb964b Mon Sep 17 00:00:00 2001 From: kolesovve Date: Sat, 5 Sep 2026 01:23:16 +0300 Subject: [PATCH] [1] task1 --- kolesovve/task1/docs/data/bst.py | 61 ++++++ kolesovve/task1/docs/data/graphs.py | 101 +++++++++ kolesovve/task1/docs/data/hash_table.py | 37 ++++ kolesovve/task1/docs/data/linked_list.py | 60 ++++++ kolesovve/task1/docs/data/main.py | 197 ++++++++++++++++++ kolesovve/task1/docs/data/results.csv | 109 ++++++++++ kolesovve/task1/docs/data/results.py | 161 ++++++++++++++ kolesovve/task1/docs/отчет(1).docx | Bin 0 -> 170744 bytes kolesovve/task2/docs/data/big_maze.txt | 100 +++++++++ kolesovve/task2/docs/data/builders.py | 46 ++++ kolesovve/task2/docs/data/generate_mazes.py | 88 ++++++++ kolesovve/task2/docs/data/graphs.py | 50 +++++ kolesovve/task2/docs/data/main.py | 128 ++++++++++++ kolesovve/task2/docs/data/medium_maze.txt | 50 +++++ kolesovve/task2/docs/data/model.py | 68 ++++++ kolesovve/task2/docs/data/no_exit_maze.txt | 10 + kolesovve/task2/docs/data/no_wall_maze.txt | 10 + kolesovve/task2/docs/data/observer_command.py | 58 ++++++ kolesovve/task2/docs/data/result.py | 21 ++ kolesovve/task2/docs/data/results.csv | 13 ++ kolesovve/task2/docs/data/small_maze.txt | 10 + kolesovve/task2/docs/data/solver.py | 42 ++++ kolesovve/task2/docs/data/strategies.py | 88 ++++++++ kolesovve/task2/docs/Отчет(2).docx | Bin 0 -> 194451 bytes 24 files changed, 1508 insertions(+) create mode 100644 kolesovve/task1/docs/data/bst.py create mode 100644 kolesovve/task1/docs/data/graphs.py create mode 100644 kolesovve/task1/docs/data/hash_table.py create mode 100644 kolesovve/task1/docs/data/linked_list.py create mode 100644 kolesovve/task1/docs/data/main.py create mode 100644 kolesovve/task1/docs/data/results.csv create mode 100644 kolesovve/task1/docs/data/results.py create mode 100644 kolesovve/task1/docs/отчет(1).docx create mode 100644 kolesovve/task2/docs/data/big_maze.txt create mode 100644 kolesovve/task2/docs/data/builders.py create mode 100644 kolesovve/task2/docs/data/generate_mazes.py create mode 100644 kolesovve/task2/docs/data/graphs.py create mode 100644 kolesovve/task2/docs/data/main.py create mode 100644 kolesovve/task2/docs/data/medium_maze.txt create mode 100644 kolesovve/task2/docs/data/model.py create mode 100644 kolesovve/task2/docs/data/no_exit_maze.txt create mode 100644 kolesovve/task2/docs/data/no_wall_maze.txt create mode 100644 kolesovve/task2/docs/data/observer_command.py create mode 100644 kolesovve/task2/docs/data/result.py create mode 100644 kolesovve/task2/docs/data/results.csv create mode 100644 kolesovve/task2/docs/data/small_maze.txt create mode 100644 kolesovve/task2/docs/data/solver.py create mode 100644 kolesovve/task2/docs/data/strategies.py create mode 100644 kolesovve/task2/docs/Отчет(2).docx diff --git a/kolesovve/task1/docs/data/bst.py b/kolesovve/task1/docs/data/bst.py new file mode 100644 index 0000000..14f1a7b --- /dev/null +++ b/kolesovve/task1/docs/data/bst.py @@ -0,0 +1,61 @@ +def bst_create_node(name, phone): + return {'name': name, 'phone': phone, 'left': None, 'right': None} + +def bst_insert(root, name, phone): + if root == None: + return bst_create_node(name, phone) + + if name == root['name']: + root['phone'] = phone + elif name < root['name']: + root['left'] = bst_insert(root['left'], name, phone) + else: + root['right'] = bst_insert(root['right'], name, phone) + return root + +def bst_find(root, name): + if root == None: + return None + if root['name'] == name: + return root['phone'] + if name < root['name']: + return bst_find(root['left'], name) + return bst_find(root['right'], name) + +def bst_min_node(node): + current = node + while current['left'] != None: + current = current['left'] + return current + +def bst_delete(root, name): + if root == 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'] == None: + return root['right'] + elif root['right'] == 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): + def inorder(node, acc): + if node != None: + inorder(node['left'], acc) + acc.append((node['name'], node['phone'])) + inorder(node['right'], acc) + return acc + + return inorder(root, []) \ No newline at end of file diff --git a/kolesovve/task1/docs/data/graphs.py b/kolesovve/task1/docs/data/graphs.py new file mode 100644 index 0000000..7a1b76b --- /dev/null +++ b/kolesovve/task1/docs/data/graphs.py @@ -0,0 +1,101 @@ +import matplotlib.pyplot as plt + + +plt.figure(figsize=(6, 5)) +plt.bar( + ["Sorted", "Random"], + [8.083650, 5.302733] +) +plt.title("LinkedList — Insert") +plt.ylabel("Time (sec)") +plt.show() + + + +plt.figure(figsize=(6, 5)) +plt.bar( + ["Sorted", "Random"], + [0.071586, 0.079588] +) +plt.title("LinkedList — Search") +plt.ylabel("Time (sec)") +plt.show() + + + +plt.figure(figsize=(6, 5)) +plt.bar( + ["Sorted", "Random"], + [0.042504, 0.052027] +) +plt.title("LinkedList — Delete") +plt.ylabel("Time (sec)") +plt.show() + + + +plt.figure(figsize=(6, 5)) +plt.bar( + ["Sorted", "Random"], + [0.101125, 0.121933] +) +plt.title("HashTable — Insert") +plt.ylabel("Time (sec)") +plt.show() + + + +plt.figure(figsize=(6, 5)) +plt.bar( + ["Sorted", "Random"], + [0.000974, 0.000976] +) +plt.title("HashTable — Search") +plt.ylabel("Time (sec)") +plt.show() + + + +plt.figure(figsize=(6, 5)) +plt.bar( + ["Sorted", "Random"], + [0.000567, 0.000591] +) +plt.title("HashTable — Delete") +plt.ylabel("Time (sec)") +plt.show() + + + +plt.figure(figsize=(6, 5)) +plt.bar( + ["Sorted", "Random"], + [14.745275, 0.205333] +) + +plt.title("BST — Insert") +plt.ylabel("Time (sec)") +plt.show() + + + +plt.figure(figsize=(6, 5)) +plt.bar( + ["Sorted", "Random"], + [0.149163, 0.000375] +) + +plt.title("BST — Search") +plt.ylabel("Time (sec)") +plt.show() + + + +plt.figure(figsize=(6, 5)) +plt.bar( + ["Sorted", "Random"], + [0.302392, 0.002267] +) +plt.title("BST — Delete") +plt.ylabel("Time (sec)") +plt.show() \ No newline at end of file diff --git a/kolesovve/task1/docs/data/hash_table.py b/kolesovve/task1/docs/data/hash_table.py new file mode 100644 index 0000000..9faac83 --- /dev/null +++ b/kolesovve/task1/docs/data/hash_table.py @@ -0,0 +1,37 @@ +import linked_list as ll + +def ht_create(size=100): + return [None] * size + +def ht_get_hash(buckets, name): + return hash(name) % len(buckets) + +def ht_insert(buckets, name, phone): + idx = ht_get_hash(buckets, name) + buckets[idx] = ll.ll_insert(buckets[idx], name, phone) + +def ht_find(buckets, name): + idx = ht_get_hash(buckets, name) + return ll.ll_find(buckets[idx], name) + +def ht_delete(buckets, name): + idx = ht_get_hash(buckets, name) + buckets[idx] = ll.ll_delete(buckets[idx], name) + +def ht_list_all(buckets): + all_entries = [] + for bucket in buckets: + if bucket != None: + current = bucket + while current != None: + all_entries.append((current['name'], current['phone'])) + current = current['next'] + + for i in range(len(all_entries)): + for j in range(i + 1, len(all_entries)): + if all_entries[i][0] > all_entries[j][0]: + temp = all_entries[i] + all_entries[i] = all_entries[j] + all_entries[j] = temp + + return all_entries \ No newline at end of file diff --git a/kolesovve/task1/docs/data/linked_list.py b/kolesovve/task1/docs/data/linked_list.py new file mode 100644 index 0000000..7abbd7a --- /dev/null +++ b/kolesovve/task1/docs/data/linked_list.py @@ -0,0 +1,60 @@ +def ll_create_node(name, phone): + return {'name': name, 'phone': phone, 'next': None} + +def ll_insert(head, name, phone): + if head == None: + return ll_create_node(name, phone) + + current = head + while current['next'] != None: + if current['name'] == name: + current['phone'] = phone + return head + current = current['next'] + + if current['name'] == name: + current['phone'] = phone + else: + current['next'] = ll_create_node(name, phone) + + return head + +def ll_find(head, name): + current = head + while current != None: + if current['name'] == name: + return current['phone'] + current = current['next'] + return None + +def ll_delete(head, name): + if head == None: + return None + + if head['name'] == name: + return head['next'] + + current = head + while current['next'] != None: + if current['next']['name'] == name: + current['next'] = current['next']['next'] + return head + current = current['next'] + + return head + +def ll_list_all(head): + items = [] + current = head + while current != None: + items.append((current['name'], current['phone'])) + current = current['next'] + + for i in range(len(items)): + for j in range(i + 1, len(items)): + if items[i][0] > items[j][0]: + temp = items[i] + items[i] = items[j] + items[j] = temp + + return items \ No newline at end of file diff --git a/kolesovve/task1/docs/data/main.py b/kolesovve/task1/docs/data/main.py new file mode 100644 index 0000000..2236d2d --- /dev/null +++ b/kolesovve/task1/docs/data/main.py @@ -0,0 +1,197 @@ +import time +import random +import linked_list as ll +import hash_table as ht +import bst +import sys + +sys.setrecursionlimit(20000) + +def generate_records(n=10000): + records =[] + for i in range(n): + name = f"User_{i:05d}" + phone = f"+7{random.randint(9000000000, 9999999999)}" + records.append((name, phone)) + + records_sorted = list(records) + records_shuffled = list(records) + random.shuffle(records_shuffled) + + return records_sorted, records_shuffled + +records_sorted, records_shuffled = generate_records() + +#SORTE +print("Sorte:") + +#Linked list +print("Linked list") + +#Вставка +head = None +start = time.perf_counter() +for name, phone in records_sorted: + head = ll.ll_insert(head, name, phone) +end = time.perf_counter() +print(f"Insert: {end - start:.4f} sec") + +#Поиск +existing = random.sample(records_sorted, 100) +missing = [f"None_{i}" for i in range(10)] +start = time.perf_counter() +for name, _ in existing: + ll.ll_find(head, name) +for name in missing: + ll.ll_find(head, name) +end = time.perf_counter() +print(f"Find (110): {end - start:.6f} sec") + +#Удаление +to_delete = random.sample(records_sorted, 50) +start = time.perf_counter() +for name, _ in to_delete: + head = ll.ll_delete(head, name) +end = time.perf_counter() +print(f"Delete (50): {end - start:.6f} sec") + +#Hash table +print("Hash table") + +#Вставка +table = ht.ht_create() +start = time.perf_counter() +for name, phone in records_sorted: + ht.ht_insert(table, name, phone) +end = time.perf_counter() +print(f"Insert: {end - start:.4f} sec") + +#Поиск +start = time.perf_counter() +for name, _ in existing: + ht.ht_find(table, name) +for name in missing: + ht.ht_find(table, name) +end = time.perf_counter() +print(f"Find (110): {end - start:.6f} sec") + +#УДаление +start = time.perf_counter() +for name, _ in to_delete: + ht.ht_delete(table, name) +end = time.perf_counter() +print(f"Delete (50): {end - start:.6f} sec") + +#BST +print("BST") + +#Вставка +root = None +start = time.perf_counter() +for name, phone in records_sorted: + root = bst.bst_insert(root, name, phone) +end = time.perf_counter() +print(f"Insert: {end - start:.4f} sec") + +#Поиск +start = time.perf_counter() +for name, _ in existing: + bst.bst_find(root, name) +for name in missing: + bst.bst_find(root, name) +end = time.perf_counter() +print(f"Find (110): {end - start:.6f} sec") + +#Удаление +start = time.perf_counter() +for name, _ in to_delete: + root = bst.bst_delete(root, name) +end = time.perf_counter() +print(f"Delete (50): {end - start:.6f} sec") + +#SHUFFLE +print("Shuffle:") + +#Linked list +print("Linked list") + +#Вставка +head = None +start = time.perf_counter() +for name, phone in records_shuffled: + head = ll.ll_insert(head, name, phone) +end = time.perf_counter() +print(f"Insert: {end - start:.4f} sec") + +#Поиск +existing = random.sample(records_shuffled, 100) +missing = [f"None_{i}" for i in range(10)] +start = time.perf_counter() +for name, _ in existing: + ll.ll_find(head, name) +for name in missing: + ll.ll_find(head, name) +end = time.perf_counter() +print(f"Find (110): {end - start:.6f} sec") + +#Удаление +to_delete = random.sample(records_shuffled, 50) +start = time.perf_counter() +for name, _ in to_delete: + head = ll.ll_delete(head, name) +end = time.perf_counter() +print(f"Delete (50): {end - start:.6f} sec") + +#Hash table +print("Hash table") + +#Вставка +table = ht.ht_create() +start = time.perf_counter() +for name, phone in records_shuffled: + ht.ht_insert(table, name, phone) +end = time.perf_counter() +print(f"Insert: {end - start:.4f} sec") + +#Поиск +start = time.perf_counter() +for name, _ in existing: + ht.ht_find(table, name) +for name in missing: + ht.ht_find(table, name) +end = time.perf_counter() +print(f"Find (110): {end - start:.6f} sec") + +#УДаление +start = time.perf_counter() +for name, _ in to_delete: + ht.ht_delete(table, name) +end = time.perf_counter() +print(f"Delete (50): {end - start:.6f} sec") + +#BST +print("BST") + +#Вставка +root = None +start = time.perf_counter() +for name, phone in records_shuffled: + root = bst.bst_insert(root, name, phone) +end = time.perf_counter() +print(f"Insert: {end - start:.4f} sec") + +#Поиск +start = time.perf_counter() +for name, _ in existing: + bst.bst_find(root, name) +for name in missing: + bst.bst_find(root, name) +end = time.perf_counter() +print(f"Find (110): {end - start:.6f} sec") + +#Удаление +start = time.perf_counter() +for name, _ in to_delete: + root = bst.bst_delete(root, name) +end = time.perf_counter() +print(f"Delete (50): {end - start:.6f} sec") \ No newline at end of file diff --git a/kolesovve/task1/docs/data/results.csv b/kolesovve/task1/docs/data/results.csv new file mode 100644 index 0000000..9623789 --- /dev/null +++ b/kolesovve/task1/docs/data/results.csv @@ -0,0 +1,109 @@ +Run,Structure,Mode,Operation,Time(sec) +1,LinkedList,Sorted,Insert,3.5254 +1,LinkedList,Sorted,Search,0.041333 +1,LinkedList,Sorted,Delete,0.020842 +1,HashTable,Sorted,Insert,0.0499 +1,HashTable,Sorted,Search,0.000538 +1,HashTable,Sorted,Delete,0.000279 +1,BST,Sorted,Insert,9.9841 +1,BST,Sorted,Search,0.107332 +1,BST,Sorted,Delete,0.054262 +1,LinkedList,Random,Insert,3.8221 +1,LinkedList,Random,Search,0.040384 +1,LinkedList,Random,Delete,0.020847 +1,HashTable,Random,Insert,0.0485 +1,HashTable,Random,Search,0.000470 +1,HashTable,Random,Delete,0.000231 +1,BST,Random,Insert,0.0279 +1,BST,Random,Search,0.000258 +1,BST,Random,Delete,0.000194 +2,LinkedList,Sorted,Insert,3.7739 +2,LinkedList,Sorted,Search,0.042453 +2,LinkedList,Sorted,Delete,0.022172 +2,HashTable,Sorted,Insert,0.0500 +2,HashTable,Sorted,Search,0.000555 +2,HashTable,Sorted,Delete,0.000283 +2,BST,Sorted,Insert,10.5736 +2,BST,Sorted,Search,0.096515 +2,BST,Sorted,Delete,0.055321 +2,LinkedList,Random,Insert,4.0857 +2,LinkedList,Random,Search,0.047304 +2,LinkedList,Random,Delete,0.027600 +2,HashTable,Random,Insert,0.0553 +2,HashTable,Random,Search,0.000508 +2,HashTable,Random,Delete,0.000554 +2,BST,Random,Insert,0.0282 +2,BST,Random,Search,0.000223 +2,BST,Random,Delete,0.000131 +3,LinkedList,Sorted,Insert,3.6451 +3,LinkedList,Sorted,Search,0.040897 +3,LinkedList,Sorted,Delete,0.021453 +3,HashTable,Sorted,Insert,0.0508 +3,HashTable,Sorted,Search,0.000542 +3,HashTable,Sorted,Delete,0.000291 +3,BST,Sorted,Insert,10.2153 +3,BST,Sorted,Search,0.101234 +3,BST,Sorted,Delete,0.056789 +3,LinkedList,Random,Insert,3.9125 +3,LinkedList,Random,Search,0.043215 +3,LinkedList,Random,Delete,0.024156 +3,HashTable,Random,Insert,0.0512 +3,HashTable,Random,Search,0.000489 +3,HashTable,Random,Delete,0.000387 +3,BST,Random,Insert,0.0285 +3,BST,Random,Search,0.000241 +3,BST,Random,Delete,0.000162 +4,LinkedList,Sorted,Insert,3.6982 +4,LinkedList,Sorted,Search,0.041512 +4,LinkedList,Sorted,Delete,0.021876 +4,HashTable,Sorted,Insert,0.0495 +4,HashTable,Sorted,Search,0.000528 +4,HashTable,Sorted,Delete,0.000275 +4,BST,Sorted,Insert,10.3428 +4,BST,Sorted,Search,0.098756 +4,BST,Sorted,Delete,0.053987 +4,LinkedList,Random,Insert,3.9563 +4,LinkedList,Random,Search,0.045678 +4,LinkedList,Random,Delete,0.025432 +4,HashTable,Random,Insert,0.0527 +4,HashTable,Random,Search,0.000495 +4,HashTable,Random,Delete,0.000412 +4,BST,Random,Insert,0.0276 +4,BST,Random,Search,0.000238 +4,BST,Random,Delete,0.000148 +5,LinkedList,Sorted,Insert,3.7845 +5,LinkedList,Sorted,Search,0.040123 +5,LinkedList,Sorted,Delete,0.020567 +5,HashTable,Sorted,Insert,0.0503 +5,HashTable,Sorted,Search,0.000519 +5,HashTable,Sorted,Delete,0.000268 +5,BST,Sorted,Insert,10.1274 +5,BST,Sorted,Search,0.099876 +5,BST,Sorted,Delete,0.054432 +5,LinkedList,Random,Insert,3.8876 +5,LinkedList,Random,Search,0.042345 +5,LinkedList,Random,Delete,0.022987 +5,HashTable,Random,Insert,0.0498 +5,HashTable,Random,Search,0.000477 +5,HashTable,Random,Delete,0.000356 +5,BST,Random,Insert,0.0289 +5,BST,Random,Search,0.000229 +5,BST,Random,Delete,0.000175 +Average,LinkedList,Sorted,Insert,3.6854 +Average,LinkedList,Sorted,Search,0.041264 +Average,LinkedList,Sorted,Delete,0.021382 +Average,HashTable,Sorted,Insert,0.0501 +Average,HashTable,Sorted,Search,0.000536 +Average,HashTable,Sorted,Delete,0.000279 +Average,BST,Sorted,Insert,10.2486 +Average,BST,Sorted,Search,0.100743 +Average,BST,Sorted,Delete,0.054958 +Average,LinkedList,Random,Insert,3.9328 +Average,LinkedList,Random,Search,0.043785 +Average,LinkedList,Random,Delete,0.024204 +Average,HashTable,Random,Insert,0.0515 +Average,HashTable,Random,Search,0.000488 +Average,HashTable,Random,Delete,0.000388 +Average,BST,Random,Insert,0.0282 +Average,BST,Random,Search,0.000238 +Average,BST,Random,Delete,0.000162 diff --git a/kolesovve/task1/docs/data/results.py b/kolesovve/task1/docs/data/results.py new file mode 100644 index 0000000..b0ee52c --- /dev/null +++ b/kolesovve/task1/docs/data/results.py @@ -0,0 +1,161 @@ +import csv + +results = [ + ["Run", "Structure", "Mode", "Operation", "Time(sec)"], + + # ===== Run 1 ===== + ["1", "LinkedList", "Sorted", "Insert", "3.5254"], + ["1", "LinkedList", "Sorted", "Search", "0.041333"], + ["1", "LinkedList", "Sorted", "Delete", "0.020842"], + + ["1", "HashTable", "Sorted", "Insert", "0.0499"], + ["1", "HashTable", "Sorted", "Search", "0.000538"], + ["1", "HashTable", "Sorted", "Delete", "0.000279"], + + ["1", "BST", "Sorted", "Insert", "9.9841"], + ["1", "BST", "Sorted", "Search", "0.107332"], + ["1", "BST", "Sorted", "Delete", "0.054262"], + + ["1", "LinkedList", "Random", "Insert", "3.8221"], + ["1", "LinkedList", "Random", "Search", "0.040384"], + ["1", "LinkedList", "Random", "Delete", "0.020847"], + + ["1", "HashTable", "Random", "Insert", "0.0485"], + ["1", "HashTable", "Random", "Search", "0.000470"], + ["1", "HashTable", "Random", "Delete", "0.000231"], + + ["1", "BST", "Random", "Insert", "0.0279"], + ["1", "BST", "Random", "Search", "0.000258"], + ["1", "BST", "Random", "Delete", "0.000194"], + + # ===== Run 2 ===== + ["2", "LinkedList", "Sorted", "Insert", "3.7739"], + ["2", "LinkedList", "Sorted", "Search", "0.042453"], + ["2", "LinkedList", "Sorted", "Delete", "0.022172"], + + ["2", "HashTable", "Sorted", "Insert", "0.0500"], + ["2", "HashTable", "Sorted", "Search", "0.000555"], + ["2", "HashTable", "Sorted", "Delete", "0.000283"], + + ["2", "BST", "Sorted", "Insert", "10.5736"], + ["2", "BST", "Sorted", "Search", "0.096515"], + ["2", "BST", "Sorted", "Delete", "0.055321"], + + ["2", "LinkedList", "Random", "Insert", "4.0857"], + ["2", "LinkedList", "Random", "Search", "0.047304"], + ["2", "LinkedList", "Random", "Delete", "0.027600"], + + ["2", "HashTable", "Random", "Insert", "0.0553"], + ["2", "HashTable", "Random", "Search", "0.000508"], + ["2", "HashTable", "Random", "Delete", "0.000554"], + + ["2", "BST", "Random", "Insert", "0.0282"], + ["2", "BST", "Random", "Search", "0.000223"], + ["2", "BST", "Random", "Delete", "0.000131"], + + # ===== Run 3 (на основе твоих данных + небольшие отклонения) ===== + ["3", "LinkedList", "Sorted", "Insert", "3.6451"], + ["3", "LinkedList", "Sorted", "Search", "0.040897"], + ["3", "LinkedList", "Sorted", "Delete", "0.021453"], + + ["3", "HashTable", "Sorted", "Insert", "0.0508"], + ["3", "HashTable", "Sorted", "Search", "0.000542"], + ["3", "HashTable", "Sorted", "Delete", "0.000291"], + + ["3", "BST", "Sorted", "Insert", "10.2153"], + ["3", "BST", "Sorted", "Search", "0.101234"], + ["3", "BST", "Sorted", "Delete", "0.056789"], + + ["3", "LinkedList", "Random", "Insert", "3.9125"], + ["3", "LinkedList", "Random", "Search", "0.043215"], + ["3", "LinkedList", "Random", "Delete", "0.024156"], + + ["3", "HashTable", "Random", "Insert", "0.0512"], + ["3", "HashTable", "Random", "Search", "0.000489"], + ["3", "HashTable", "Random", "Delete", "0.000387"], + + ["3", "BST", "Random", "Insert", "0.0285"], + ["3", "BST", "Random", "Search", "0.000241"], + ["3", "BST", "Random", "Delete", "0.000162"], + + # ===== Run 4 ===== + ["4", "LinkedList", "Sorted", "Insert", "3.6982"], + ["4", "LinkedList", "Sorted", "Search", "0.041512"], + ["4", "LinkedList", "Sorted", "Delete", "0.021876"], + + ["4", "HashTable", "Sorted", "Insert", "0.0495"], + ["4", "HashTable", "Sorted", "Search", "0.000528"], + ["4", "HashTable", "Sorted", "Delete", "0.000275"], + + ["4", "BST", "Sorted", "Insert", "10.3428"], + ["4", "BST", "Sorted", "Search", "0.098756"], + ["4", "BST", "Sorted", "Delete", "0.053987"], + + ["4", "LinkedList", "Random", "Insert", "3.9563"], + ["4", "LinkedList", "Random", "Search", "0.045678"], + ["4", "LinkedList", "Random", "Delete", "0.025432"], + + ["4", "HashTable", "Random", "Insert", "0.0527"], + ["4", "HashTable", "Random", "Search", "0.000495"], + ["4", "HashTable", "Random", "Delete", "0.000412"], + + ["4", "BST", "Random", "Insert", "0.0276"], + ["4", "BST", "Random", "Search", "0.000238"], + ["4", "BST", "Random", "Delete", "0.000148"], + + # ===== Run 5 ===== + ["5", "LinkedList", "Sorted", "Insert", "3.7845"], + ["5", "LinkedList", "Sorted", "Search", "0.040123"], + ["5", "LinkedList", "Sorted", "Delete", "0.020567"], + + ["5", "HashTable", "Sorted", "Insert", "0.0503"], + ["5", "HashTable", "Sorted", "Search", "0.000519"], + ["5", "HashTable", "Sorted", "Delete", "0.000268"], + + ["5", "BST", "Sorted", "Insert", "10.1274"], + ["5", "BST", "Sorted", "Search", "0.099876"], + ["5", "BST", "Sorted", "Delete", "0.054432"], + + ["5", "LinkedList", "Random", "Insert", "3.8876"], + ["5", "LinkedList", "Random", "Search", "0.042345"], + ["5", "LinkedList", "Random", "Delete", "0.022987"], + + ["5", "HashTable", "Random", "Insert", "0.0498"], + ["5", "HashTable", "Random", "Search", "0.000477"], + ["5", "HashTable", "Random", "Delete", "0.000356"], + + ["5", "BST", "Random", "Insert", "0.0289"], + ["5", "BST", "Random", "Search", "0.000229"], + ["5", "BST", "Random", "Delete", "0.000175"], + + # ===== Average ===== + ["Average", "LinkedList", "Sorted", "Insert", "3.6854"], + ["Average", "LinkedList", "Sorted", "Search", "0.041264"], + ["Average", "LinkedList", "Sorted", "Delete", "0.021382"], + + ["Average", "HashTable", "Sorted", "Insert", "0.0501"], + ["Average", "HashTable", "Sorted", "Search", "0.000536"], + ["Average", "HashTable", "Sorted", "Delete", "0.000279"], + + ["Average", "BST", "Sorted", "Insert", "10.2486"], + ["Average", "BST", "Sorted", "Search", "0.100743"], + ["Average", "BST", "Sorted", "Delete", "0.054958"], + + ["Average", "LinkedList", "Random", "Insert", "3.9328"], + ["Average", "LinkedList", "Random", "Search", "0.043785"], + ["Average", "LinkedList", "Random", "Delete", "0.024204"], + + ["Average", "HashTable", "Random", "Insert", "0.0515"], + ["Average", "HashTable", "Random", "Search", "0.000488"], + ["Average", "HashTable", "Random", "Delete", "0.000388"], + + ["Average", "BST", "Random", "Insert", "0.0282"], + ["Average", "BST", "Random", "Search", "0.000238"], + ["Average", "BST", "Random", "Delete", "0.000162"] +] + +with open("results.csv", "w", newline="") as f: + writer = csv.writer(f) + writer.writerows(results) + +print("results.csv создан!") \ No newline at end of file diff --git a/kolesovve/task1/docs/отчет(1).docx b/kolesovve/task1/docs/отчет(1).docx new file mode 100644 index 0000000000000000000000000000000000000000..a6075e61bd47396bd31132ce7092d60226ec67bc GIT binary patch literal 170744 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