2026-rff_mp/docs/data/bst_phonebook.py

136 lines
4.6 KiB
Python
Raw Normal View History

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()