diff --git a/VolkovVA/cod.py b/VolkovVA/cod.py new file mode 100644 index 0000000..af9ea4a --- /dev/null +++ b/VolkovVA/cod.py @@ -0,0 +1,369 @@ +import random as rnd +import time +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 is not None: + if current['name'] == name: + current['phone'] = phone + return head + if current['next'] is None: + break + current = current['next'] + + current['next'] = new_node + 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): + + if head is None: + return None + if head['name'] == name: + return head['next'] + + current = head + while current['next'] is not None: + if current['next']['name'] == name: + current['next'] = current['next']['next'] + return head + current = current['next'] + return head + +def sort_records(lst): + + n = len(lst) + for i in range(n): + for j in range(0, n-i-1): + if lst[j][0] > lst[j + 1][0]: + lst[j], lst[j + 1] = lst[j + 1], lst[j] + return lst + +def ll_list_all(head): + record = [] + current = head + while current is not None: + record += [(current['name'], current['phone'])] + current = current['next'] + res = sort_records(record) + return res + + +# ХЕШ-ТАБЛИЦА + + +def def_hash(name, size): + + hash_value = 0 + for char in name: + hash_value += ord(char) + final_idx = hash_value % size + return final_idx + +def ht_insert(buckets, name, phone): + size = len(buckets) + idx = def_hash(name, size) + buckets[idx] = ll_insert(buckets[idx], name, phone) + return buckets + +def ht_find(buckets, name): + size = len(buckets) + idx = def_hash(name, size) + return ll_find(buckets[idx], name) + +def ht_delete(buckets, name): + size = len(buckets) + idx = def_hash(name, size) + buckets[idx] = ll_delete(buckets[idx], name) + return buckets + +def ht_list_all(buckets): + res = [] + for head in buckets: + current = head + while current is not None: + res += [(current['name'], current['phone'])] + current = current['next'] + return sort_records(res) + + +# ДВОИЧНОЕ ДЕРЕВО ПОИСКА + + +def bst_insert(root, name, phone): + new_node = {'name': name, 'phone': phone, 'left': None, 'right': None} + + if root is None: + return new_node + + current = root + while True: + if name == current['name']: + current['phone'] = phone + break + elif name < current['name']: + if current['left'] is None: + current['left'] = new_node + break + current = current['left'] + else: + if current['right'] is None: + current['right'] = new_node + break + current = current['right'] + + return root + +def bst_find(root, name): + current = root + while current is not None: + if name == current['name']: + return current['phone'] + elif name < current['name']: + current = current['left'] + else: + current = current['right'] + return None + +def bst_delete(root, name): + if root is None: + return None + + p_node = None + current = root + + while current is not None and current['name'] != name: + p_node = current + if name < current['name']: + current = current['left'] + else: + current = current['right'] + + if current is None: + return root + + if current['left'] is None and current['right'] is None: + if p_node is None: + return None + if p_node['left'] is current: + p_node['left'] = None + else: + p_node['right'] = None + return root + + if current['left'] is None: + c_node = current['right'] + elif current['right'] is None: + c_node = current['left'] + else: + succ_parent = current + succ = current['right'] + while succ['left']: + succ_parent = succ + succ = succ['left'] + + current['name'], current['phone'] = succ['name'], succ['phone'] + + if succ_parent['left'] is succ: + succ_parent['left'] = succ['right'] + else: + succ_parent['right'] = succ['right'] + return root + + if p_node is None: + return c_node + if p_node['left'] is current: + p_node['left'] = c_node + else: + p_node['right'] = c_node + return root + +def bst_list_all(root): + record = [] + + def helper(node): + if node is not None: + helper(node['left']) + nonlocal record + record += [(node['name'], node['phone'])] + helper(node['right']) + + helper(root) + return record + + +# ЭКСПЕРИМЕНТАЛЬНАЯ ЧАСТЬ + + +if __name__ == '__main__': + N = 10000 + + + records = [] + for i in range(N): + name = f"User_{i:05d}" + phone = f"+7-{rnd.randint(100, 999)}-{rnd.randint(100, 999)}-{rnd.randint(1000, 9999)}" + records.append((name, phone)) + + + records_shuffled = records[:] + rnd.shuffle(records_shuffled) + records_sorted = sorted(records, key=lambda x: x[0]) + + + s_names = [] + for i in range(100): + s_names.append(records_shuffled[i][0]) + for i in range(10): + s_names.append(f"None_{i}") + + d_names = [] + sampled = rnd.sample(records_shuffled, 50) + for item in sampled: + d_names.append(item[0]) + + print("Начало замеров...") + + results = [["Структура", "Режим", "Операция", "Время (сек)"]] + + + # ПРОВЕДЕНИЕ ЗАМЕРОВ + + # СВЯЗНЫЙ СПИСОК + for mode_name, data in [("случайный", records_shuffled), ("отсортированный", records_sorted)]: + s_ins = 0 + s_fnd=0 + s_del=0 + for _ in range(5): + ll = None + + + t1 = time.perf_counter() + for name, phone in data: + ll = ll_insert(ll, name, phone) + time_ins = time.perf_counter() - t1 + s_ins += time_ins + results.append(["LinkedList", mode_name, "вставка", time_ins]) + + + t1 = time.perf_counter() + for name in s_names: + ll_find(ll, name) + time_fnd = time.perf_counter() - t1 + s_fnd += time_fnd + results.append(["LinkedList", mode_name, "поиск", time_fnd]) + + + t1 = time.perf_counter() + for name in d_names: + ll = ll_delete(ll, name) + time_del = time.perf_counter() - t1 + s_del += time_del + results.append(["LinkedList", mode_name, "удаление", time_del]) + + print(f" Связный список ({mode_name}) | Среднее за 5 замеров ") + print(f"Вставка: {s_ins/5:.5f} сек.") + print(f"Поиск: {s_fnd/5:.5f} сек.") + print(f"Удаление: {s_del/5:.5f} сек.") + print("-" * 40) + + + + + # ХЕШ-ТАБЛИЦА + for mode_name, data in [("случайный", records_shuffled), ("отсортированный", records_sorted)]: + s_ins = 0 + s_fnd=0 + s_del =0 + for _ in range(5): + ht = [None] * 2000 + + + t1 = time.perf_counter() + for name, phone in data: + ht = ht_insert(ht, name, phone) + time_ins = time.perf_counter() - t1 + s_ins += time_ins + results.append(["HashTable", mode_name, "вставка", time_ins]) + + + t1 = time.perf_counter() + for name in s_names: + ht_find(ht, name) + time_fnd = time.perf_counter() - t1 + s_fnd += time_fnd + results.append(["HashTable", mode_name, "поиск", time_fnd]) + + + t1 = time.perf_counter() + for name in d_names: + ht = ht_delete(ht, name) + time_del = time.perf_counter() - t1 + s_del += time_del + results.append(["HashTable", mode_name, "удаление", time_del]) + + print(f" Хеш-таблица ({mode_name}) | Среднее за 5 замеров ") + print(f"Вставка: {s_ins/5:.5f} сек.") + print(f"Поиск: {s_fnd/5:.5f} сек.") + print(f"Удаление: {s_del/5:.5f} сек.") + print("-" * 40) + + # ДЕРЕВО + + for mode_name, data in [("случайный", records_shuffled), ("отсортированный", records_sorted)]: + s_ins = 0 + s_fnd = 0 + s_del = 0 + for _ in range(5): + bst = None + + + t1 = time.perf_counter() + for name, phone in data: + bst = bst_insert(bst, name, phone) + time_ins = time.perf_counter() - t1 + s_ins += time_ins + results.append(["BST", mode_name, "вставка", time_ins]) + + + t1 = time.perf_counter() + for name in s_names: + bst_find(bst, name) + time_fnd = time.perf_counter() - t1 + s_fnd += time_fnd + results.append(["BST", mode_name, "поиск", time_fnd]) + + + t1 = time.perf_counter() + for name in d_names: + bst = bst_delete(bst, name) + time_del = time.perf_counter() - t1 + s_del += time_del + results.append(["BST", mode_name, "удаление", time_del]) + + print(f"Двоичное дерево ({mode_name}) | Среднее за 5 замеров ") + print(f"Вставка: {s_ins/5:.5f} сек.") + print(f"Поиск: {s_fnd/5:.5f} сек.") + print(f"Удаление: {s_del/5:.5f} сек.") + print("-" * 40) + # Сохранение результатов + with open("docs/data/results.csv", "w", newline="", encoding="utf-8") as f: + writer = csv.writer(f) + writer.writerows(results) \ No newline at end of file diff --git a/VolkovVA/docs/.gitkeep b/VolkovVA/docs/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/VolkovVA/docs/data/.gitkeep b/VolkovVA/docs/data/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/VolkovVA/docs/data/grafic.py b/VolkovVA/docs/data/grafic.py new file mode 100644 index 0000000..ae5e74d --- /dev/null +++ b/VolkovVA/docs/data/grafic.py @@ -0,0 +1,61 @@ +import csv +import matplotlib.pyplot as plt +from collections import defaultdict + +pth = r"C:\Users\vva26\2026-rff_mp\VolkovVA\docs\data\results.csv" +grf = r"C:\Users\vva26\2026-rff_mp\VolkovVA\docs\performance_chart.png" + +dct = defaultdict(lambda: defaultdict(list)) + +with open(pth, "r", encoding="utf-8") as f: + rdr = csv.reader(f) + nxt = next(rdr) + + for row in rdr: + if not row: + continue + str, mod, ope, tim = row + key = f"{str}\n({ope})" + dct[key][mod].append(float(tim)) + +lbl = [] +rnd = [] +srt = [] + +for key, mds in dct.items(): + lbl.append(key) + avg_rnd = sum(mds["случайный"]) / len(mds["случайный"]) if mds["случайный"] else 0 + avg_srt = sum(mds["отсортированный"]) / len(mds["отсортированный"]) if mds["отсортированный"] else 0 + rnd.append(avg_rnd) + srt.append(avg_srt) + +idx = range(len(lbl)) +wth = 0.35 + +x_rnd = [] +for i in idx: + x_rnd.append(i - wth/2) + +x_srt = [] +for i in idx: + x_srt.append(i + wth/2) + +fig, axs = plt.subplots(figsize=(11, 6)) + +bar1 = axs.bar(x_rnd, rnd, wth, label='Случайные данные', color='#3498db') +bar2 = axs.bar(x_srt, srt, wth, label='Отсортированные данные', color='#e74c3c') + +axs.set_title('Сравнение скорости операций в различных структурах данных', fontsize=13, fontweight='bold', pad=15) +axs.set_xticks(idx) +axs.set_xticklabels(lbl, rotation=15, ha='right', fontsize=10) +axs.legend(fontsize=10) +axs.grid(axis='y', linestyle='--', alpha=0.5) + +axs.set_yscale('log') +axs.set_ylabel('Время выполнения в сек (Логарифмическая шкала)', fontsize=11) + +plt.tight_layout() + +plt.savefig(grf, dpi=300) +print(f"\n[OK] График сохранен в: {grf}") +plt.show() \ No newline at end of file diff --git a/VolkovVA/docs/data/performance_chart.png b/VolkovVA/docs/data/performance_chart.png new file mode 100644 index 0000000..8162b0c Binary files /dev/null and b/VolkovVA/docs/data/performance_chart.png differ diff --git a/VolkovVA/docs/data/results.csv b/VolkovVA/docs/data/results.csv new file mode 100644 index 0000000..5fe986d --- /dev/null +++ b/VolkovVA/docs/data/results.csv @@ -0,0 +1,91 @@ +Структура,Режим,Операция,Время (сек) +LinkedList,случайный,вставка,4.291091899998719 +LinkedList,случайный,поиск,0.005068599999503931 +LinkedList,случайный,удаление,0.019771399998717243 +LinkedList,случайный,вставка,4.525691400001961 +LinkedList,случайный,поиск,0.005420200002845377 +LinkedList,случайный,удаление,0.020462399999814807 +LinkedList,случайный,вставка,4.353839700001117 +LinkedList,случайный,поиск,0.00541249999878346 +LinkedList,случайный,удаление,0.023757300001307158 +LinkedList,случайный,вставка,4.502167200000258 +LinkedList,случайный,поиск,0.010723499999585329 +LinkedList,случайный,удаление,0.03311329999996815 +LinkedList,случайный,вставка,5.201365899996745 +LinkedList,случайный,поиск,0.010636599999997998 +LinkedList,случайный,удаление,0.039027299997542286 +LinkedList,отсортированный,вставка,4.315812599998026 +LinkedList,отсортированный,поиск,0.04411020000043209 +LinkedList,отсортированный,удаление,0.030419400001846952 +LinkedList,отсортированный,вставка,8.593622799999139 +LinkedList,отсортированный,поиск,0.08360049999828334 +LinkedList,отсортированный,удаление,0.05115080000177841 +LinkedList,отсортированный,вставка,8.543958199999906 +LinkedList,отсортированный,поиск,0.09370399999897927 +LinkedList,отсортированный,удаление,0.056215399999928195 +LinkedList,отсортированный,вставка,7.622753499999817 +LinkedList,отсортированный,поиск,0.10020520000034594 +LinkedList,отсортированный,удаление,0.06128549999993993 +LinkedList,отсортированный,вставка,8.650270099999034 +LinkedList,отсортированный,поиск,0.07040950000009616 +LinkedList,отсортированный,удаление,0.040762199998425785 +HashTable,случайный,вставка,0.47725569999965956 +HashTable,случайный,поиск,0.0002153999994334299 +HashTable,случайный,удаление,0.0027007999997294974 +HashTable,случайный,вставка,0.5317499999982829 +HashTable,случайный,поиск,0.0003974999999627471 +HashTable,случайный,удаление,0.005713599999580765 +HashTable,случайный,вставка,0.6429859999989276 +HashTable,случайный,поиск,0.00022510000053443946 +HashTable,случайный,удаление,0.0043073999986518174 +HashTable,случайный,вставка,0.6996447000019543 +HashTable,случайный,поиск,0.000267400002485374 +HashTable,случайный,удаление,0.00396790000013425 +HashTable,случайный,вставка,0.6941239000007045 +HashTable,случайный,поиск,0.0002880000029108487 +HashTable,случайный,удаление,0.003416699997615069 +HashTable,отсортированный,вставка,0.6140038000012282 +HashTable,отсортированный,поиск,0.0050384999995003454 +HashTable,отсортированный,удаление,0.002920400002039969 +HashTable,отсортированный,вставка,0.546170899997378 +HashTable,отсортированный,поиск,0.005110499998409068 +HashTable,отсортированный,удаление,0.002819400000589667 +HashTable,отсортированный,вставка,0.49733259999993606 +HashTable,отсортированный,поиск,0.003421200002776459 +HashTable,отсортированный,удаление,0.0022764000023016706 +HashTable,отсортированный,вставка,0.4543197999992117 +HashTable,отсортированный,поиск,0.00394619999860879 +HashTable,отсортированный,удаление,0.0024693000013940036 +HashTable,отсортированный,вставка,0.4290051999996649 +HashTable,отсортированный,поиск,0.003611500000261003 +HashTable,отсортированный,удаление,0.002442600001813844 +BST,случайный,вставка,0.045431899998220615 +BST,случайный,поиск,0.00016899999900488183 +BST,случайный,удаление,0.0002190000013797544 +BST,случайный,вставка,0.04518879999886849 +BST,случайный,поиск,0.0001917000008688774 +BST,случайный,удаление,0.00022659999740426429 +BST,случайный,вставка,0.04384279999794671 +BST,случайный,поиск,0.00015949999942677096 +BST,случайный,удаление,0.00020090000180061907 +BST,случайный,вставка,0.047621300000173505 +BST,случайный,поиск,0.00017160000061267056 +BST,случайный,удаление,0.00021569999807979912 +BST,случайный,вставка,0.04882440000073984 +BST,случайный,поиск,0.00017870000010589138 +BST,случайный,удаление,0.00022280000121099874 +BST,отсортированный,вставка,14.469153600002755 +BST,отсортированный,поиск,0.13092999999935273 +BST,отсортированный,удаление,0.06794660000014119 +BST,отсортированный,вставка,13.552134699999442 +BST,отсортированный,поиск,0.09381570000186912 +BST,отсортированный,удаление,0.048802499997691484 +BST,отсортированный,вставка,13.858903200001805 +BST,отсортированный,поиск,0.12883069999952568 +BST,отсортированный,удаление,0.06201040000087232 +BST,отсортированный,вставка,14.243588299999828 +BST,отсортированный,поиск,0.10868889999983367 +BST,отсортированный,удаление,0.05314870000074734 +BST,отсортированный,вставка,12.31363550000242 +BST,отсортированный,поиск,0.11658590000297409 +BST,отсортированный,удаление,0.053270799999154406 diff --git a/VolkovVA/docs/~$Отчёт.odt b/VolkovVA/docs/~$Отчёт.odt new file mode 100644 index 0000000..620d15a Binary files /dev/null and b/VolkovVA/docs/~$Отчёт.odt differ diff --git a/VolkovVA/docs/Отчёт.odt b/VolkovVA/docs/Отчёт.odt new file mode 100644 index 0000000..00957fe Binary files /dev/null and b/VolkovVA/docs/Отчёт.odt differ