Binary tree traversal series summary

Posted by Mythic Fr0st on Sat, 15 Jan 2022 12:22:37 +0100

This paper mainly records four traversal modes of binary tree (pre order, middle order, post order and sequence).

Title reference force buckle 144.94.145.102

Tree traversal can be divided into two ways: depth first traversal (DFS) and breadth first traversal (BFS)
DFS: first order traversal, middle order traversal and second order traversal are often solved by recursion or stack
BFS: hierarchical traversal, using queues

Node definition of tree:

class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

First put the pre order, middle order and post order templates together.

I Recursive method
The implementation of recursion is: each recursive call will press the local variables, parameter values and return addresses of the function into the call stack, and then when the recursion returns, the parameters of the last recursion will pop up from the top of the stack. Therefore, this is why recursion can return to the upper layer. The recursive method is "top-down". The most important thing to use recursion is to find out what the base case and recursive case are. In the traversal of binary tree, base case is that the node of the tree is empty, that is, it has traversed to the leaf node.

The simplest and direct recursive version is as follows:
Recursive method I

class Solution:
    def Traversal(self, root: TreeNode) -> List[int]:
    	if not root: return []
    	# Preorder traversal
        return [root.val] + self.Traversal(root.left) + self.Traversal(root.right)
        # Medium order traversal
        return self.Traversal(root.left) + [root.val] + self.Traversal(root.right)
        # Postorder traversal
        return self.Traversal(root.left) + self.Traversal(root.right) + [root.val] 

Recursive method II

class Solution:
    def inorderTraversal(self, root: TreeNode) -> List[int]:
        def dfs(root):
            if not root:return []
            # Preorder traversal 
            res.append(root.val)
            dfs(root.left)
            dfs(root.right)
            # Medium order traversal
            dfs(root.left)
            res.append(root.val)
            dfs(root.right)
            # Postorder traversal
            dfs(root.left)
            dfs(root.right)
            res.append(root.val)
        res = []
        dfs(root)
        return res 

The time complexity of recursive method is O (n), n is the number of points of binary tree, and the space complexity is O (n). The space complexity depends on the stack depth of recursion.

Iterative method
The iterative method is a bottom-up method. The loop condition is that the auxiliary stack stack or root is not empty, because as long as there is one non empty, the node has not been traversed. For middle order traversal, the traversal order is left → root → right. The contents of the loop are:

  • First add the root node to the stack, and then traverse the left node until it is empty;
  • If it is empty, that is, root is an empty node, which means that the left node of the current subtree has been traversed. Start adding the left node value to res, pop up the recently traversed node from the stack, add the node value to res and let root = root right. The pre, middle and post order traversal is only different when res is added.
class Solution:
    def inorderTraversal(self, root: TreeNode) -> List[int]:
        # Using auxiliary stack to complete iterative method
        res, stack = [], []
        #Preorder traversal
        while stack or root:
            if root:
                stack.append(root)
                res.append(root.val)
                root = root.left
            else:
                root = stack.pop()
                root = root.right
        return res
        #Medium order traversal
        while stack or root:
            if root:
                stack.append(root) 
                root = root.left
            else:
                root = stack.pop()
                res.append(root.val)
                root = root.right
        return res
        #Postorder traversal
        while stack or root:
            if root:
                stack.append(root)
                res.append(root.val)
                root = root.right
            else:
                root = stack.pop()
                root = root.left
        return res[::-1] 

The post order traversal order is left → right → root, which is actually the reverse order of root → right → left. The traversal method is similar to the first left → right, so the last root can be written back in reverse order.
The time complexity is O (n), and the space complexity is O (n)

Last sequence traversal
The queue is used to save all nodes of each layer. Each time, the original node in the queue is dequeued, and then the non empty left and right child nodes of the dequeued element are queued.

Topics: Algorithm