Hasli4

Untitled

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