Разбор задачи: Обход двоичного дерева

Предложенный нами код решения:

def traversal(root):
    """
    Возвращает последовательный обход значений узлов двоичного дерева.
    :param root: list, корень двоичного дерева в виде вложенного списка [val, left, right]
    :return: list, значения узлов в порядке обхода in-order
    """
    if not root:
        return []
    
    # Рекурсивный обход
    left = traversal(root[1]) if len(root) > 1 and root[1] else []
    right = traversal(root[2]) if len(root) > 2 and root[2] else []
    return left + [root[0]] + right

Функция traversal выполняет обход двоичного дерева в порядке in-order (сначала левое поддерево, затем корень, потом правое поддерево). Дерево представлено вложенными списками.

1. Входные параметры

  • root: список, представляющий узел двоичного дерева в формате [val, left, right], где:
    • val — значение текущего узла.
    • left — левый потомок (также список или None).
    • right — правый потомок (также список или None).

Примеры представления дерева:

  • [1, None, [2, [3, None, None], None]] — узел 1 с правым потомком 2, у которого есть левый потомок 3.
  • [1] — одиночный узел с корнем 1.

2. Основная логика

  • Проверка на пустое дерево:

    if not root:
        return []
    

    Если дерево пустое (root == [] или None), функция сразу возвращает пустой список [].

  • Рекурсивный обход левого поддерева:

    left = traversal(root[1]) if len(root) > 1 and root[1] else []
    
    • Проверяется, есть ли левый потомок (len(root) > 1 и root[1] не None).
    • Если левый потомок существует, выполняется рекурсивный вызов traversal для этого поддерева.
    • Если левого поддерева нет, возвращается пустой список.
  • Рекурсивный обход правого поддерева:

    right = traversal(root[2]) if len(root) > 2 and root[2] else []
    
    • Проверяется, есть ли правый потомок (len(root) > 2 и root[2] не None).
    • Если правый потомок существует, выполняется рекурсивный вызов traversal для правого поддерева.
    • Если правого поддерева нет, возвращается пустой список.
  • Комбинация результатов:

    return left + [root[0]] + right
    
    • Результаты обхода объединяются в порядке левое поддерево → корень → правое поддерево.

3. Примеры работы

  1. Пример 1:

    root = [1, None, [2, [3, None, None], None]]
    traversal(root)  # Результат: [1, 3, 2]
    
    • Левое поддерево отсутствует: left = [].
    • Правое поддерево: [2, [3, None, None], None]. Рекурсия даёт: traversal([2, [3, None, None], None]) → [3, 2].
    • Итог: [] + [1] + [3, 2] → [1, 3, 2].
  2. Пример 2:

    root = [1, [2, [4, None, None], [5, [6, None, None], [7, None, None]]], [3, None, [8, [9, None, None], None]]]
    traversal(root)  # Результат: [4, 2, 6, 5, 7, 1, 3, 9, 8]
    
    • Левое поддерево: [2, [4, None, None], [5, [6, None, None], [7, None, None]]]. Рекурсия даёт: [4, 2, 6, 5, 7].
    • Правое поддерево: [3, None, [8, [9, None, None], None]]. Рекурсия даёт: [3, 9, 8].
    • Итог: [4, 2, 6, 5, 7] + [1] + [3, 9, 8] → [4, 2, 6, 5, 7, 1, 3, 9, 8].
  3. Пример 3:

    root = []
    traversal(root)  # Результат: []
    
  4. Пример 4:

    root = [1]
    traversal(root)  # Результат: [1]
    
    • Левое поддерево: [].
    • Правое поддерево: [].
    • Итог: [] + [1] + [] → [1].

 


0

Вы должны Войти или Зарегистрироваться чтобы оставлять комментарии