Понимание рекурсии при обходе дерева

Я пытаюсь понять, как работает рекурсия и как работает обход двоичного дерева.

Итак, насколько я знаю, рекурсия вызывает функцию внутри себя. Что-то вроде зацикливания.

Теперь мне дали код, как выполнить обход postOrder в двоичном дереве.

(Обратите внимание, что это не мой код, я просто пытаюсь понять, как работает рекурсия в этом коде)

 # Definition for a  binary tree node
 # class TreeNode:
 #     def __init__(self, x):
 #         self.val = x
 #         self.left = None
 #         self.right = None

 class Solution:
     # @param root, a tree node
     # @return a list of integers

 def postorderTraversal(self, root):
    solution = []
    self.postorderTraversalRec(root, solution)
    return solution

 def postorderTraversalRec(self, root, solution):
    if root == None:
        return
    self.postorderTraversalRec(root.left, solution)
    self.postorderTraversalRec(root.right, solution)
    solution.append(root.val)

Теперь, насколько я понимаю, обход PostOrder идет справа-налево-посередине, поэтому сначала дочерний, а затем родительский.

Вот 2 строки, где, как мне кажется, происходит рекурсия.

    self.postorderTraversalRec(root.left, solution)
    self.postorderTraversalRec(root.right, solution)

Насколько я понимаю, первая строка говорит программе рекурсивно пройти через все левые узлы, пока не достигнет конца. Затем он говорит программе пройти через все левые узлы, пока не достигнет конца.

Но проблема, с которой я столкнулся, заключается в том, что я не могу понять, как это делает обход PostOrder. Для меня это выглядит как обход PreOrder.


person Andre    schedule 26.10.2014    source источник


Ответы (1)


Обход после заказа выглядит следующим образом:

  1. Обходим левое поддерево.
  2. Обходим правое поддерево.
  3. Посетите корень.

Что именно здесь и происходит. Для любого данного узла (root) сначала вы посещаете левое поддерево (root.left), затем правое поддерево (root.right), а затем сам узел (root.val).

Часть «до» или «после» типа обхода относится к тому, когда значение текущего узла посещается, либо перед посещением дочерних узлов (до), после (после), или даже между посещением каждого дочернего узла. (обход по порядку). В вашем примере кода значение текущего узла посещается после обхода дочерних элементов. Итак, обход по порядку.

person dano    schedule 26.10.2014
comment
Я в замешательстве... когда мы вызываем рекурсивную функцию: self.postorderTraversalRec(root.left, solution)... она продолжает рекурсивно проходить через все левые узлы... и как только все левые узлы заканчиваются... она проходит через правые ручные узлы... Это мое мнение. - person Andre; 26.10.2014
comment
@Ali Да, это именно то, что он делает. Вы все еще описываете обход после заказа. - person dano; 26.10.2014
comment
но чем это отличается от предзаказа? - person Andre; 26.10.2014
comment
@Ali для предварительного заказа, мы начинаем сначала с обхода корня. Перейдите по этой ссылке, чтобы визуально понять алгоритмы обхода дерева. algomation.com/algorithm/ - person user3378649; 26.10.2014
comment
В предварительном порядке мы добавили бы root.val перед рекурсией, а не после. - person Karl Knechtel; 26.10.2014
comment
@Ali: Ваша функция будет выглядеть так: В случае рекурсии предварительного заказа: def preorderTraversalRec(self, root, solution): если root == None: return solution.append(root.val) self.preorderTraversalRec(root.left, решение) self.preorderTraversalRec(root.right, решение) - person user3378649; 26.10.2014
comment
да спасибо сэр! Я понимаю, чем отличаются эти два обхода до и после. - person Andre; 26.10.2014