Advertisement
Hasli4

Untitled

Jun 13th, 2025
324
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.60 KB | None | 0 0
  1. import re
  2.  
  3. # Имя входного файла с данными
  4. INPUT_FILE = 'input.txt'
  5.  
  6. class Node:
  7.     """
  8.    Класс узла двоичного дерева, который умеет сам:
  9.      - создавать промежуточные узлы по коду пути,
  10.      - вставлять себя из файла или вручную,
  11.      - собирать список всех узлов,
  12.      - рисовать себя «горизонтально».
  13.    """
  14.  
  15.     def __init__(self, data=None):
  16.         # data=None  — узел пока пуст, data=int — узел заполнен числом
  17.         self.data = data
  18.         self.left = None
  19.         self.right = None
  20.  
  21.     def ensure_path(self, code):
  22.         """
  23.        По строке code из '0' и '1' спускаемся от self
  24.        (корня) на уровень целевого узла. Если на пути нет
  25.        промежуточного узла, сразу спрашиваем у пользователя,
  26.        какое там должно быть число, создаём узел и ставим его
  27.        на нужное место. Возвращает узел в конце пути.
  28.        """
  29.         node = self
  30.         for i, c in enumerate(code):
  31.             # решаем: 0→лево, 1→право
  32.             if c == '0':
  33.                 if node.left is None:
  34.                     # отсутствует узел → спрашиваем у человека
  35.                     while True:
  36.                         val = input(f"Введите число для узла с кодом '{code[:i+1]}' (левый от '{code[:i]}'): ")
  37.                         if val.isdigit():
  38.                             node.left = Node(int(val))
  39.                             break
  40.                         print("Неверно, введите целое неотрицательное число.")
  41.                 node = node.left
  42.             else:  # c == '1'
  43.                 if node.right is None:
  44.                     while True:
  45.                         val = input(f"Введите число для узла с кодом '{code[:i+1]}' (правый от '{code[:i]}'): ")
  46.                         if val.isdigit():
  47.                             node.right = Node(int(val))
  48.                             break
  49.                         print("Неверно, введите целое неотрицательное число.")
  50.                 node = node.right
  51.         return node
  52.  
  53.     def insert_from_file(self):
  54.         """
  55.        Читает файл INPUT_FILE, строки вида:
  56.            <число> <код_пути>
  57.        и последовательно вставляет пары в дерево, создавая
  58.        промежуточные узлы по необходимости.
  59.        """
  60.         try:
  61.             with open(INPUT_FILE, 'r', encoding='utf-8') as f:
  62.                 for lineno, line in enumerate(f, start=1):
  63.                     text = line.strip()
  64.                     if not text:
  65.                         continue
  66.                     parts = text.split()
  67.                     if len(parts) != 2 or not parts[0].isdigit() or any(ch not in '01' for ch in parts[1]):
  68.                         print(f"[Строка {lineno}] Пропущена (ожидалось: число и код из 0/1).")
  69.                         continue
  70.                     number, code = int(parts[0]), parts[1]
  71.                     node = self.ensure_path(code)
  72.                     if node.data is not None:
  73.                         print(f"[Строка {lineno}] Ошибка: узел '{code}' уже содержит {node.data}.")
  74.                     else:
  75.                         node.data = number
  76.         except FileNotFoundError:
  77.             print(f"Ошибка: файл '{INPUT_FILE}' не найден.")
  78.             exit(1)
  79.  
  80.     def insert_manually(self):
  81.         """
  82.        Позволяет пользователю вводить пары <число> <код_пути>
  83.        до тех пор, пока он не введёт 'q'.
  84.        """
  85.         print("Ввод вручную. Формат: <число> <код_пути>, либо 'q' для окончания.")
  86.         while True:
  87.             s = input("> ").strip()
  88.             if s.lower() == 'q':
  89.                 break
  90.             parts = s.split()
  91.             if len(parts) != 2 or not parts[0].isdigit() or any(ch not in '01' for ch in parts[1]):
  92.                 print("Неверный формат. Повторите.")
  93.                 continue
  94.             number, code = int(parts[0]), parts[1]
  95.             node = self.ensure_path(code)
  96.             if node.data is not None:
  97.                 print(f"Ошибка: узел '{code}' уже заполнен значением {node.data}.")
  98.             else:
  99.                 node.data = number
  100.  
  101.     def collect(self, path="", out=None):
  102.         """
  103.        Рекурсивно собирает все узлы в список out в формате
  104.        [(код_пути, значение), ...]
  105.        """
  106.         if out is None:
  107.             out = []
  108.         out.append((path, self.data))
  109.         if self.left:
  110.             self.left.collect(path + "0", out)
  111.         if self.right:
  112.             self.right.collect(path + "1", out)
  113.         return out
  114.  
  115.     def print_tree(self, level=0):
  116.         """
  117.        Рекурсивно выводит дерево «лежа»:
  118.        правые дети рисуются выше, левые — ниже.
  119.        Каждый уровень смещается на 4 пробела.
  120.        """
  121.         if self.right:
  122.             self.right.print_tree(level + 1)
  123.         print("    " * level + f"-> {self.data}")
  124.         if self.left:
  125.             self.left.print_tree(level + 1)
  126.  
  127.  
  128. # ==== Основная логика ====
  129.  
  130. print("Построение бинарного дерева по кодам путей.")
  131. mode = input("Выберите режим (1 — из файла, 2 — вручную): ").strip()
  132. root = Node(0)  # корень по условию содержит 0
  133.  
  134. if mode == '1':
  135.     root.insert_from_file()
  136. else:
  137.     root.insert_manually()
  138.  
  139. # Вывод всех узлов списком
  140. print("\nСписок узлов (код пути : значение):")
  141. for path, val in root.collect():
  142.     display_path = path or "root"
  143.     print(f"{display_path:>5} : {val}")
  144.  
  145. # Горизонтальная печать дерева
  146. print("\nГоризонтальное представление:")
  147. root.print_tree()
  148.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement