diff --git a/SolovevDS/docs/data/data_for_task1/data_structures.py b/SolovevDS/docs/data/data_for_task1/data_structures.py
new file mode 100644
index 0000000..0f5879a
--- /dev/null
+++ b/SolovevDS/docs/data/data_for_task1/data_structures.py
@@ -0,0 +1,203 @@
+#--------------------------------------Связный список--------------------------
+def ll_insert(head, name, phone):
+ # 1. если список пуст → новый элемент становится head
+ if head is None:
+ return {'name': name, 'phone': phone,'next': None}
+
+ current = head
+ # 2. сначала проверим — может имя уже есть → тогда просто обновим
+ while current is not None:
+ if current['name'] == name:
+ current['phone'] = phone
+ return head
+ current = current['next']
+ # 3. идём до конца списка
+ current = head
+ while current['next'] is not None:
+ current = current['next']
+ # 4. добавляем новый узел в конец
+ current['next'] = {'name': name,'phone': phone,'next': None}
+
+ return head
+
+
+def ll_find(head, name):
+ current = head
+
+ while current is not None:
+ if current['name'] == name:
+ return current['phone']
+
+ current = current['next']
+
+ return None
+
+def ll_delete(head, name):
+ current = head
+ previous = None
+
+ while current is not None:
+ if current['name'] == name:
+
+ # 1. удаляем голову списка
+ if previous is None:
+ return current['next']
+
+ # 2. удаляем середину или конец
+ previous['next'] = current['next']
+ return head
+
+ previous = current
+ current = current['next']
+
+ return head # если не нашли
+
+def ll_list_all(head):
+ result = []
+ current = head
+ # 1. проходим по списку
+ while current is not None:
+ result.append((current['name'], current['phone']))
+ current = current['next']
+ # 2. сортируем по имени
+ result.sort(key=lambda x: x[0])
+
+ return result
+
+
+#----------------------------------HASH-таблица--------------------------------
+def my_hash(s, M):
+ B = 31
+ n = len(s)
+ h = 0
+ for i in range(n):
+ h += ord(s[i]) * (B ** (n - 1 - i))
+ return h % M
+
+def ht_insert(buckets, name, phone):
+ index = my_hash(name, len(buckets))
+ buckets[index] = ll_insert(buckets[index], name, phone)
+ return buckets
+
+
+def ht_find(buckets, name):
+ index = my_hash(name, len(buckets))
+ return ll_find(buckets[index], name)
+
+def ht_delete(buckets, name):
+ index = my_hash(name, len(buckets))
+ buckets[index] = ll_delete(buckets[index], name)
+ return buckets
+
+def ht_list_all(buckets):
+ result = []
+ for i in range(len(buckets)):
+ result += ll_list_all(buckets[i])
+ result.sort(key=lambda x: x[0])
+ return result
+
+#---------------------------Двоичное дерево поиска-----------------------------
+def bst_insert(root, name, phone):
+ if root is None:
+ return {'name': name, 'phone': phone,'left': None, 'right': None}
+
+ current = root
+ while True:
+ # если такое имя уже есть — меняем телефон
+ if name == current['name']:
+ current['phone'] = phone
+ return root
+
+ # если новое имя меньше — идём влево
+ if name < current['name']:
+ if current['left'] is None:
+ current['left'] = {'name': name, 'phone': phone,'left': None, 'right': None}
+ return root
+ current = current['left']
+
+ # если новое имя больше — идём вправо
+ else:
+ if current['right'] is None:
+ current['right'] = {'name': name, 'phone': phone,'left': None, 'right': None}
+ return root
+ current = current['right']
+
+def bst_find(root, name):
+ current = root
+
+ while current is not None:
+ if name == current['name']:
+ return current['phone']
+
+ if name < current['name']:
+ current = current['left']
+ else:
+ current = current['right']
+
+ return None
+
+def bst_delete(root, name):
+ current = root
+ previous = None
+
+ while current is not None and current['name'] != name:
+ previous = current
+
+ if name < current['name']:
+ current = current['left']
+ else:
+ current = current['right']
+
+ # если не нашли
+ if current is None:
+ return root
+
+ # 2. Если у узла два потомка
+ if current['left'] is not None and current['right'] is not None:
+ successor_parent = current
+ successor = current['right']
+
+ # ищем минимальный узел в правом поддереве
+ while successor['left'] is not None:
+ successor_parent = successor
+ successor = successor['left']
+
+ # копируем данные successor в current
+ current['name'] = successor['name']
+ current['phone'] = successor['phone']
+
+ # теперь удаляем successor
+ current = successor
+ previous = successor_parent
+ #3
+ if current['left'] is not None:
+ child = current['left']
+ else:
+ child = current['right']
+
+ # 4. Если удаляем корень
+ if previous is None:
+ return child
+
+ # 5. Переподключаем родителя
+ if previous['left'] is current:
+ previous['left'] = child
+ else:
+ previous['right'] = child
+
+ return root
+
+def bst_list_all(root):
+ result = []
+
+ def inorder(node):
+ if node is None:
+ return
+
+ inorder(node['left'])
+ result.append((node['name'], node['phone']))
+ inorder(node['right'])
+
+ inorder(root)
+ return result
+
diff --git a/SolovevDS/docs/data/data_for_task1/delete_chart.svg b/SolovevDS/docs/data/data_for_task1/delete_chart.svg
new file mode 100644
index 0000000..a76383b
--- /dev/null
+++ b/SolovevDS/docs/data/data_for_task1/delete_chart.svg
@@ -0,0 +1,1298 @@
+
+
+
diff --git a/SolovevDS/docs/data/data_for_task1/diagramm.py b/SolovevDS/docs/data/data_for_task1/diagramm.py
new file mode 100644
index 0000000..222ff2d
--- /dev/null
+++ b/SolovevDS/docs/data/data_for_task1/diagramm.py
@@ -0,0 +1,62 @@
+# -*- coding: utf-8 -*-
+"""
+Created on Fri May 1 11:42:31 2026
+
+@author: ddima
+"""
+
+import matplotlib.pyplot as plt
+import numpy as np
+
+data = {
+ ("LinkedList", "shuffled", "insert"): 3.46348492,
+ ("HashTable", "shuffled", "insert"): 0.01967166,
+ ("BST", "shuffled", "insert"): 0.01715242,
+
+ ("LinkedList", "shuffled", "find"): 0.0301834,
+ ("HashTable", "shuffled", "find"): 0.0002298400002,
+ ("BST", "shuffled", "find"): 0.0002346200003,
+
+ ("LinkedList", "shuffled", "delete"): 0.01254974,
+ ("HashTable", "shuffled", "delete"): 0.0001220800004,
+ ("BST", "shuffled", "delete"): 0.0001421199995,
+
+ ("LinkedList", "sorted", "insert"): 3.2739972,
+ ("HashTable", "sorted", "insert"): 0.01923022,
+ ("BST", "sorted", "insert"): 4.01406982,
+
+ ("LinkedList", "sorted", "find"): 0.0252881,
+ ("HashTable", "sorted", "find"): 0.0002579799999,
+ ("BST", "sorted", "find"): 0.0369953,
+
+ ("LinkedList", "sorted", "delete"): 0.01326564,
+ ("HashTable", "sorted", "delete"): 0.0001182399996,
+ ("BST", "sorted", "delete"): 0.02074794,
+}
+
+structures = ["BST", "LinkedList", "HashTable"]
+structure_labels = ["Бинарное дерево", "Связный список", "Хэш-таблица"]
+
+operations = [("insert", "Вставка"), ("find", "Поиск"), ("delete", "Удаление"),]
+
+for op_key, op_title in operations:
+ shuffled_values = [data[(s, "shuffled", op_key)] for s in structures]
+ sorted_values = [data[(s, "sorted", op_key)] for s in structures]
+
+ x = np.arange(len(structures))
+ width = 0.35
+
+ plt.figure(figsize=(8, 5))
+
+ plt.bar(x - width / 2, shuffled_values, width, label="Случайный")
+ plt.bar(x + width / 2, sorted_values, width, label="Отсортированный")
+
+ plt.title(op_title)
+ plt.ylabel("Время (сек)")
+ plt.xticks(x, structure_labels)
+ plt.legend()
+ plt.grid(axis="y", alpha=0.3)
+ plt.tight_layout()
+
+ plt.savefig(f"{op_key}_chart.svg", format="svg")
+ plt.show()
\ No newline at end of file
diff --git a/SolovevDS/docs/data/data_for_task1/experements_with_structures.py b/SolovevDS/docs/data/data_for_task1/experements_with_structures.py
new file mode 100644
index 0000000..3aaf000
--- /dev/null
+++ b/SolovevDS/docs/data/data_for_task1/experements_with_structures.py
@@ -0,0 +1,240 @@
+import data_structures as st
+import time
+import random
+import csv
+
+
+def generate_records(N):
+ records = []
+
+ for i in range(N):
+ name = f"User_{i:05d}"
+ phone = f"+7{random.randint(10**9, 10**10 - 1)}"
+ records.append((name, phone))
+
+ records_shuffled = records[:]
+ random.shuffle(records_shuffled)
+
+ records_sorted = sorted(records, key=lambda x: x[0])
+
+ return records_shuffled, records_sorted
+
+def linked_list_build_structure(records):
+ head = None
+
+ for name, phone in records:
+ head = st.ll_insert(head, name, phone)
+
+ return head
+
+def hash_table_build_structure(records):
+ buckets = [None] * 10007
+
+ for name, phone in records:
+ buckets = st.ht_insert(buckets, name, phone)
+
+ return buckets
+
+def bst_build_structure(records):
+ root = None
+
+ for name, phone in records:
+ root = st.bst_insert(root, name, phone)
+
+ return root
+
+def measure_time(func, *args):
+ start = time.perf_counter()
+ result = func(*args)
+ end = time.perf_counter()
+
+ return result, end - start
+
+def prepare_find_names(records):
+ existing_names = [name for name, phone in records]
+
+ find_existing = random.sample(existing_names, 100)
+
+ find_missing = []
+ for i in range(10):
+ find_missing.append(f"None_{i}")
+ find_names = find_existing + find_missing
+ return find_names
+
+
+def linked_list_find(head, find_names):
+ results = []
+ for name in find_names:
+ phone = st.ll_find(head, name)
+ results.append(phone)
+ return results
+
+def hash_table_find(buckets, find_names):
+ results = []
+ for name in find_names:
+ phone = st.ht_find(buckets, name)
+ results.append(phone)
+ return results
+
+def bst_find(root, find_names):
+ results = []
+ for name in find_names:
+ phone = st.bst_find(root, name)
+ results.append(phone)
+ return results
+
+def prepare_delete_names(records):
+ existing_names = [name for name, phone in records]
+ delete_names = random.sample(existing_names, 50)
+ return delete_names
+
+
+def linked_list_delete(head, delete_names):
+ for name in delete_names:
+ head = st.ll_delete(head, name)
+ return head
+
+def hash_table_delete(buckets, delete_names):
+ for name in delete_names:
+ buckets = st.ht_delete(buckets, name)
+ return buckets
+
+def bst_delete(root, delete_names):
+ for name in delete_names:
+ root = st.bst_delete(root, name)
+ return root
+
+
+def run_one_experiment(records_shuffled, records_sorted, find_names, delete_names):
+ one_run_results = []
+ #------------------------ создание структур + замер времени заполнения -------------------------
+ # ------------------- shuffled -------------------
+ head_shuffled, ll_insert_time_shuffled = measure_time(linked_list_build_structure,records_shuffled)
+
+ buckets_shuffled, ht_insert_time_shuffled = measure_time(hash_table_build_structure,records_shuffled)
+
+ root_shuffled, bst_insert_time_shuffled = measure_time(bst_build_structure,records_shuffled)
+
+
+ # ------------------- sorted -------------------
+
+ head_sorted, ll_insert_time_sorted = measure_time(linked_list_build_structure,records_sorted)
+
+ buckets_sorted, ht_insert_time_sorted = measure_time(hash_table_build_structure,records_sorted)
+
+ root_sorted, bst_insert_time_sorted = measure_time(bst_build_structure,records_sorted)
+
+
+
+ # ------------------- поиск в shuffled -------------------
+
+ ll_find_results_shuffled, ll_find_time_shuffled = measure_time(linked_list_find,head_shuffled,find_names)
+
+ ht_find_results_shuffled, ht_find_time_shuffled = measure_time(hash_table_find,buckets_shuffled,find_names)
+
+ bst_find_results_shuffled, bst_find_time_shuffled = measure_time(bst_find,root_shuffled,find_names)
+
+
+ # ------------------- поиск в sorted -------------------
+
+ ll_find_results_sorted, ll_find_time_sorted = measure_time(linked_list_find,head_sorted,find_names)
+
+ ht_find_results_sorted, ht_find_time_sorted = measure_time(hash_table_find,buckets_sorted,find_names)
+
+ bst_find_results_sorted, bst_find_time_sorted = measure_time(bst_find,root_sorted,find_names)
+
+
+
+ # ------------------- удаление в shuffled -------------------
+
+ head_shuffled, ll_delete_time_shuffled = measure_time(linked_list_delete,head_shuffled,delete_names)
+
+ buckets_shuffled, ht_delete_time_shuffled = measure_time(hash_table_delete,buckets_shuffled,delete_names)
+
+ root_shuffled, bst_delete_time_shuffled = measure_time(bst_delete,root_shuffled,delete_names)
+
+ # ------------------- удаление в sorted -------------------
+
+ head_sorted, ll_delete_time_sorted = measure_time(linked_list_delete,head_sorted,delete_names)
+
+ buckets_sorted, ht_delete_time_sorted = measure_time(hash_table_delete,buckets_sorted,delete_names)
+
+ root_sorted, bst_delete_time_sorted = measure_time(bst_delete,root_sorted,delete_names)
+
+ one_run_results.append(["LinkedList", "shuffled", "insert", ll_insert_time_shuffled])
+ one_run_results.append(["HashTable", "shuffled", "insert", ht_insert_time_shuffled])
+ one_run_results.append(["BST", "shuffled", "insert", bst_insert_time_shuffled])
+
+ one_run_results.append(["LinkedList", "shuffled", "find", ll_find_time_shuffled])
+ one_run_results.append(["HashTable", "shuffled", "find", ht_find_time_shuffled])
+ one_run_results.append(["BST", "shuffled", "find", bst_find_time_shuffled])
+
+ one_run_results.append(["LinkedList", "shuffled", "delete", ll_delete_time_shuffled])
+ one_run_results.append(["HashTable", "shuffled", "delete", ht_delete_time_shuffled])
+ one_run_results.append(["BST", "shuffled", "delete", bst_delete_time_shuffled])
+
+ one_run_results.append(["LinkedList", "sorted", "insert", ll_insert_time_sorted])
+ one_run_results.append(["HashTable", "sorted", "insert", ht_insert_time_sorted])
+ one_run_results.append(["BST", "sorted", "insert", bst_insert_time_sorted])
+
+ one_run_results.append(["LinkedList", "sorted", "find", ll_find_time_sorted])
+ one_run_results.append(["HashTable", "sorted", "find", ht_find_time_sorted])
+ one_run_results.append(["BST", "sorted", "find", bst_find_time_sorted])
+
+ one_run_results.append(["LinkedList", "sorted", "delete", ll_delete_time_sorted])
+ one_run_results.append(["HashTable", "sorted", "delete", ht_delete_time_sorted])
+ one_run_results.append(["BST", "sorted", "delete", bst_delete_time_sorted])
+
+ return one_run_results
+
+
+N = 10000
+REPEATS = 5
+records_shuffled, records_sorted = generate_records(N)
+find_names = prepare_find_names(records_sorted)
+delete_names = prepare_delete_names(records_sorted)
+
+results = [["Запуск", "Структура", "Режим", "Операция", "Время (сек)"]]
+
+for run in range(1, REPEATS + 1):
+ print("Запуск эксперимента:", run)
+
+ one_run_results = run_one_experiment(records_shuffled,records_sorted,find_names,delete_names)
+
+ for row in one_run_results:
+ structure = row[0]
+ mode = row[1]
+ operation = row[2]
+ elapsed = row[3]
+
+ results.append([run, structure, mode, operation, elapsed])
+
+groups = {}
+
+for row in results[1:]:
+ structure = row[1]
+ mode = row[2]
+ operation = row[3]
+ elapsed = row[4]
+
+ key = (structure, mode, operation)
+
+ if key not in groups:
+ groups[key] = []
+
+ groups[key].append(elapsed)
+
+
+for key, times in groups.items():
+ structure, mode, operation = key
+ avg_time = sum(times) / len(times)
+
+ results.append(["average", structure, mode, operation, avg_time])
+
+
+with open("results.csv", "w", newline="", encoding="utf-8") as f:
+ writer = csv.writer(f)
+ writer.writerows(results)
+
+print("Результаты сохранены в results.csv")
+
diff --git a/SolovevDS/docs/data/data_for_task1/find_chart.svg b/SolovevDS/docs/data/data_for_task1/find_chart.svg
new file mode 100644
index 0000000..24d75bf
--- /dev/null
+++ b/SolovevDS/docs/data/data_for_task1/find_chart.svg
@@ -0,0 +1,1282 @@
+
+
+
diff --git a/SolovevDS/docs/data/data_for_task1/insert_chart.svg b/SolovevDS/docs/data/data_for_task1/insert_chart.svg
new file mode 100644
index 0000000..dc6bc2b
--- /dev/null
+++ b/SolovevDS/docs/data/data_for_task1/insert_chart.svg
@@ -0,0 +1,1296 @@
+
+
+
diff --git a/SolovevDS/docs/data/data_for_task1/results.csv b/SolovevDS/docs/data/data_for_task1/results.csv
new file mode 100644
index 0000000..9e8a000
--- /dev/null
+++ b/SolovevDS/docs/data/data_for_task1/results.csv
@@ -0,0 +1,109 @@
+Запуск,Структура,Режим,Операция,Время (сек)
+1,LinkedList,shuffled,insert,3.4127272000005178
+1,HashTable,shuffled,insert,0.019356400000106078
+1,BST,shuffled,insert,0.01772239999991143
+1,LinkedList,shuffled,find,0.029260500003147172
+1,HashTable,shuffled,find,0.00023599999985890463
+1,BST,shuffled,find,0.00022670000180369243
+1,LinkedList,shuffled,delete,0.011755700001231162
+1,HashTable,shuffled,delete,0.00011840000297524966
+1,BST,shuffled,delete,0.00014689999807160348
+1,LinkedList,sorted,insert,3.2256927999987965
+1,HashTable,sorted,insert,0.019139899999572663
+1,BST,sorted,insert,4.1095220999995945
+1,LinkedList,sorted,find,0.024785800000245217
+1,HashTable,sorted,find,0.00022289999833446927
+1,BST,sorted,find,0.03631210000094143
+1,LinkedList,sorted,delete,0.012450800000806339
+1,HashTable,sorted,delete,0.00011539999832166359
+1,BST,sorted,delete,0.0211152999982005
+2,LinkedList,shuffled,insert,3.3890004999993835
+2,HashTable,shuffled,insert,0.019052899999223882
+2,BST,shuffled,insert,0.01668930000232649
+2,LinkedList,shuffled,find,0.028735200001392514
+2,HashTable,shuffled,find,0.00022629999875789508
+2,BST,shuffled,find,0.00024219999977503903
+2,LinkedList,shuffled,delete,0.01258820000293781
+2,HashTable,shuffled,delete,0.00011489999815239571
+2,BST,shuffled,delete,0.00014340000052470714
+2,LinkedList,sorted,insert,3.256336700000247
+2,HashTable,sorted,insert,0.018892399999458576
+2,BST,sorted,insert,3.978548999999475
+2,LinkedList,sorted,find,0.02532219999920926
+2,HashTable,sorted,find,0.00022780000290367752
+2,BST,sorted,find,0.036961199999495875
+2,LinkedList,sorted,delete,0.013499500000762055
+2,HashTable,sorted,delete,0.00011860000086016953
+2,BST,sorted,delete,0.02029960000072606
+3,LinkedList,shuffled,insert,3.4580803999997443
+3,HashTable,shuffled,insert,0.019483100000798004
+3,BST,shuffled,insert,0.017162699998152675
+3,LinkedList,shuffled,find,0.029887100001360523
+3,HashTable,shuffled,find,0.00023090000104275532
+3,BST,shuffled,find,0.00023660000078962184
+3,LinkedList,shuffled,delete,0.01279649999924004
+3,HashTable,shuffled,delete,0.00014880000162520446
+3,BST,shuffled,delete,0.0001424999973096419
+3,LinkedList,sorted,insert,3.3060915999994904
+3,HashTable,sorted,insert,0.020634799999243114
+3,BST,sorted,insert,3.999759400001494
+3,LinkedList,sorted,find,0.025299299999460345
+3,HashTable,sorted,find,0.00022419999731937423
+3,BST,sorted,find,0.03626530000110506
+3,LinkedList,sorted,delete,0.012905700001283549
+3,HashTable,sorted,delete,0.00012069999866071157
+3,BST,sorted,delete,0.020299800002248958
+4,LinkedList,shuffled,insert,3.490586699997948
+4,HashTable,shuffled,insert,0.020179600000119535
+4,BST,shuffled,insert,0.017119400003139162
+4,LinkedList,shuffled,find,0.030576699999073753
+4,HashTable,shuffled,find,0.00022309999985736795
+4,BST,shuffled,find,0.00023399999918183312
+4,LinkedList,shuffled,delete,0.012583200001245132
+4,HashTable,shuffled,delete,0.00011319999975967221
+4,BST,shuffled,delete,0.00013839999883202836
+4,LinkedList,sorted,insert,3.2922638000018196
+4,HashTable,sorted,insert,0.018590499999845633
+4,BST,sorted,insert,4.008463900001516
+4,LinkedList,sorted,find,0.025681600000098115
+4,HashTable,sorted,find,0.0002204000011261087
+4,BST,sorted,find,0.0370997999998508
+4,LinkedList,sorted,delete,0.013347899999644142
+4,HashTable,sorted,delete,0.00011789999916800298
+4,BST,sorted,delete,0.021108500000991626
+5,LinkedList,shuffled,insert,3.567029800000455
+5,HashTable,shuffled,insert,0.020286300001316704
+5,BST,shuffled,insert,0.017068300003302284
+5,LinkedList,shuffled,find,0.0324575000013283
+5,HashTable,shuffled,find,0.00023290000171982683
+5,BST,shuffled,find,0.00023359999977401458
+5,LinkedList,shuffled,delete,0.013025099997321377
+5,HashTable,shuffled,delete,0.00011509999967529438
+5,BST,shuffled,delete,0.00013940000280854292
+5,LinkedList,sorted,insert,3.289601099997526
+5,HashTable,sorted,insert,0.01889350000055856
+5,BST,sorted,insert,3.9740547000001243
+5,LinkedList,sorted,find,0.02535160000115866
+5,HashTable,sorted,find,0.00039459999970858917
+5,BST,sorted,find,0.038338099999236874
+5,LinkedList,sorted,delete,0.014124299999821233
+5,HashTable,sorted,delete,0.00011860000086016953
+5,BST,sorted,delete,0.0209164999978384
+average,LinkedList,shuffled,insert,3.4634849199996096
+average,HashTable,shuffled,insert,0.01967166000031284
+average,BST,shuffled,insert,0.01715242000136641
+average,LinkedList,shuffled,find,0.030183400001260453
+average,HashTable,shuffled,find,0.00022984000024734997
+average,BST,shuffled,find,0.0002346200002648402
+average,LinkedList,shuffled,delete,0.012549740000395104
+average,HashTable,shuffled,delete,0.00012208000043756329
+average,BST,shuffled,delete,0.00014211999950930476
+average,LinkedList,sorted,insert,3.273997199999576
+average,HashTable,sorted,insert,0.01923021999973571
+average,BST,sorted,insert,4.014069820000441
+average,LinkedList,sorted,find,0.02528810000003432
+average,HashTable,sorted,find,0.0002579799998784438
+average,BST,sorted,find,0.036995300000126005
+average,LinkedList,sorted,delete,0.013265640000463463
+average,HashTable,sorted,delete,0.00011823999957414344
+average,BST,sorted,delete,0.02074794000000111
diff --git a/SolovevDS/docs/laba_1_report.pdf b/SolovevDS/docs/laba_1_report.pdf
new file mode 100644
index 0000000..f0f277d
Binary files /dev/null and b/SolovevDS/docs/laba_1_report.pdf differ