SHARE
    TWEET
    Hasli4

    Untitled

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

    AltStyle によって変換されたページ (->オリジナル) /