2026-rff_mp/docs/data/bst_phonebook.py

136 lines
4.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import time
import csv
import random
import os
def create_node(name, phone):
"""Создает узел BST"""
return {'name': name, 'phone': phone, 'left': None, 'right': None}
def bst_insert(root, name, phone):
"""Вставляет запись в BST"""
if root is None:
return create_node(name, phone)
current = root
while True:
if name < current['name']:
if current['left'] is None:
current['left'] = create_node(name, phone)
break
current = current['left']
elif name > current['name']:
if current['right'] is None:
current['right'] = create_node(name, phone)
break
current = current['right']
else:
current['phone'] = phone
break
return root
def bst_find(root, name):
"""Ищет запись в BST"""
current = root
while current:
if name == current['name']:
return current['phone']
elif name < current['name']:
current = current['left']
else:
current = current['right']
return None
def bst_find_min(root):
"""Находит минимальный узел"""
if root is None:
return None
current = root
while current['left']:
current = current['left']
return current
def bst_delete(root, name):
"""Удаляет запись из BST"""
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']
elif root['right'] is None:
return root['left']
min_node = bst_find_min(root['right'])
root['name'] = min_node['name']
root['phone'] = min_node['phone']
root['right'] = bst_delete(root['right'], min_node['name'])
return root
def generate_test_data(n=300):
"""Генерирует тестовые данные"""
records = [(f"User_{i:05d}", f"123-456-{i%10000:04d}") for i in range(n)]
records_shuffled = records.copy()
random.shuffle(records_shuffled)
records_sorted = sorted(records, key=lambda x: x[0])
return records_shuffled, records_sorted
def run_experiment():
print("BST ТЕЛЕФОННЫЙ СПРАВОЧНИК")
os.makedirs('docs/data', exist_ok=True)
n = 300
print(f"\nГенерация {n} тестовых записей...")
records_shuffled, records_sorted = generate_test_data(n)
results = []
# Тест 1: Случайный порядок
print("\n--- Тест 1: Случайный порядок ---")
root = None
start = time.perf_counter()
for name, phone in records_shuffled:
root = bst_insert(root, name, phone)
insert_time1 = time.perf_counter() - start
print(f"Вставка: {insert_time1:.4f} сек")
names_to_find = [records_shuffled[i][0] for i in range(30)]
start = time.perf_counter()
for name in names_to_find:
bst_find(root, name)
find_time1 = time.perf_counter() - start
print(f"Поиск 30 записей: {find_time1:.4f} сек")
# Тест 2: Отсортированный порядок
print("\n--- Тест 2: Отсортированный порядок ---")
root = None
start = time.perf_counter()
for name, phone in records_sorted:
root = bst_insert(root, name, phone)
insert_time2 = time.perf_counter() - start
print(f"Вставка: {insert_time2:.4f} сек")
# Сохраняем результаты
results.append(['BST', 'случайный', insert_time1, find_time1, 0])
results.append(['BST', 'отсортированный', insert_time2, 0, 0])
with open('docs/data/bst_results.csv', 'w', newline='', encoding='utf-8') as f:
writer = csv.writer(f)
writer.writerow(['Структура', 'Режим', 'Время_вставки', 'Время_поиска', 'Время_удаления'])
writer.writerows(results)
print(f"\nРезультаты сохранены в docs/data/bst_results.csv")
print(f"\nСравнение:")
print(f"Случайный порядок вставки: {insert_time1:.4f} сек")
print(f"Отсортированный порядок вставки: {insert_time2:.4f} сек")
print(f"Разница: {insert_time2/insert_time1:.1f} раз")
if __name__ == "__main__":
run_experiment()