web-dev-qa-db-fra.com

Inorder Binary Tree Traversal (en utilisant Python)

J'essaie d'effectuer une traversée inordonnée d'un arbre. Le code lui-même semble correct, sauf qu'il ne fonctionne pas correctement. J'ai le sentiment que cela doit être lié à la condition if, à la façon dont append fonctionne en python, ou à quelque chose peut-être avec return. Cela fonctionne correctement si j'utilise print au lieu de return, je pense, mais je veux pouvoir utiliser return et toujours obtenir la bonne réponse. Par exemple, pour l'arborescence [1, None, 2,3], mon code renvoie [1] qui est clairement incorrect.

De plus, est-il possible de résoudre ce problème en utilisant la compréhension de liste? Si c'est le cas, tout exemple de code serait grandement apprécié.

Voici mon code:

    class Solution(object):
        def inorderTraversal(self, root):
            res = []
            if root:
                self.inorderTraversal(root.left)
                res.append(root.val)
                self.inorderTraversal(root.right)
            return res

De plus, avant de marquer cela comme un doublon, je sais que des traversées ont été demandées sur Stackoverflow (beaucoup de fois), mais aucune ne m'a aidé à comprendre pourquoi ma compréhension est fausse. Je serais tellement reconnaissant si quelqu'un m'aidait à apprendre comment corriger mon approche plutôt que de simplement publier un autre lien sans explication. Merci beaucoup!

8
Jane Sully

La raison pour laquelle cela ne fonctionne pas est que res n'a que la valeur du premier nœud que vous lui donnez en annexe; chaque fois que vous rappelez récursivement la fonction, elle crée simplement une nouvelle résolution. Il s'agit cependant d'une solution simple, comme suit:

class Solution(object):
    def inorderTraversal(self, root):
        res = []
        if root:
            res = self.inorderTraversal(root.left) 
            res.append(root.val)
            res = res + self.inorderTraversal(root.right)
        return res

En cela, il renvoie la branche gauche, la valeur, puis la droite. Cela peut être fait beaucoup plus brièvement comme suit:

class Solution(object):
    def inorderTraversal(self, root):
        return (self.inorderTraversal(root.left) + [root.val] + self.inorderTraversal(root.right)) if root else []
11

Utilisez ceci à la place, une simple récursivité ::

class Node:
    def __init__(self,key):
        self.left = None
        self.right = None
        self.val = key

def printInorder(root):
    if root:
        printInorder(root.left)
        print(root.val)
        printInorder(root.right)

def printPostorder(root):
    if root:
        printPostorder(root.left)
        printPostorder(root.right)
        print(root.val)

def printPreorder(root):
    if root:
        print(root.val)
        printPreorder(root.left)
        printPreorder(root.right)

# Driver code
root = Node(1)
root.left      = Node(2)
root.right     = Node(3)
root.left.left  = Node(4)
root.left.right  = Node(5)
print "Preorder traversal of binary tree is"
printPreorder(root)

print "\nInorder traversal of binary tree is"
printInorder(root)

print "\nPostorder traversal of binary tree is"
printPostorder(root)

Source :: ici

4
Akash Kandpal

La réponse de @Benedict Randall Shaw est déjà parfaite. Je veux juste y ajouter du plaisir d'une manière Pythonique. Bien que le doc ne suggère pas d'utiliser un objet mutable comme paramètre par défaut, cela simplifiera quelque peu le code en traitant le mutable par défaut list comme un membre de classe du python.

La différence n'est que le += est remplacé par =, puisque res est toujours le même objet list à l'intérieur de la fonction avant que l'objet fonction ne soit récupéré.

def inorderTraversal(root, res=[]):
    if root:
        res = inorderTraversal(root.left)
        res.append(root.val)
        res = inorderTraversal(root.right)
return res
0
Yossarian42