Basic question type records - binary tree inorder traversal

Due to my poor foundation, I made a record for some question types so as not to forget

1. Binary tree inorder traversal

This traversal method can be searched for a lot of explanations on the blog, here is mainly to record the code implementation, take the following binary tree as an example
insert image description here

The result should be
insert image description here

2. Iterative method

2.1 Traversal process

A temporary stack is borrowed here (first access post-processing) to store the corresponding root node and the node corresponding to the left subtree. The node is pushed onto the stack. When the left subtree node of the last root node visited is empty, the corresponding element is taken from the top of the stack, and then its right subtree node is accessed to determine whether it has left and right subtrees before operating.

  1. Starting from the root node (23), curr starts pointing to the original root node
    insert image description here

  2. The element pointing to the root node (23) is pushed onto the stack (the root node is often processed later, so we put it at the bottom of the stack first)
    insert image description here

  3. Find the left subtree node of the current node (34), curr=curr.left
    insert image description here

  4. If the currently moved curr (pointing to 34) is not empty, push it onto the stack
    insert image description here

  5. Continue to find the left child node of the current node (34) (the method is the same as the previous node, if it is not empty, push it into the stack)
    insert image description here
    insert image description here

  6. Until the left subtree node is empty (that is, the left subnode of the node corresponding to 77 shown in the figure is empty), take the corresponding top element
    at this time, indicating that the node has no left subtree, and traverse the order of left and right according to the inorder, left The subtree is empty, and the root node element should be read at this time (that is, the corresponding top element of the stack is taken out), where 77 is the first node we traverse in order
    insert image description here

  7. Visiting 77 corresponds to the right subtree node.
    If it is empty, it means that this node corresponds to no right subtree, so there is no need to visit its corresponding right node. So
    insert image description here
    far, the left subtree with 77 as the root node has been visited

  8. Visit the root node 99 with 77 as the left child node (take the corresponding root node from the stack, the top element of the stack is 99).
    After visiting the top element of the stack, you must immediately visit the right subtree
    insert image description here

  9. Visit the right subtree with 99 as the root node, if it is not empty, push it into the stack as the root node of the right subtree
    insert image description here

  10. Query whether the right subtree with 90 as the root node has a left child node.
    insert image description here
    If the right subtree with 90 as the root node has a left child node, then the method is the same as above.
    If there is no left child node, then take out the 90 in the stack root node
    insert image description here

  11. Query whether the subtree with 90 as the root node has a right subtree
    insert image description here
    At this time, the right subtree node of the subtree with 90 as the root node is empty, then further access the corresponding root node elements stored in the stack

  12. Continue to read the top element of the stack (corresponding to 34 at this time)
    insert image description here
    . At this time, we have finished processing the left subtree with 34 as the root node, and the root node 34 has also been read, and then process the right subtree corresponding to 34.

  13. Read the right subtree with 34 as the root node.
    The right subtree with 34 as the root node is empty, then the subtree with 34 as the root node has been traversed.
    insert image description here
    Continue to process the elements in the stack

  14. Continue to read the elements in the stack (23 at this time).
    insert image description here
    At this time, the left subtree of the entire binary tree has been traversed, and then the corresponding right subtree is traversed.

  15. Traverse the root node of the right subtree (root node 23 corresponds to the root node of the right subtree is not empty, you can continue to traverse, first traverse the first root node 21, and push it into the stack)
    insert image description here
    insert image description here

  16. Continue to traverse the left subtree with 21 as the root node first, if it is not empty, continue to push it into the stack (45)
    insert image description here

  17. Continue to move to the left until there is a left subtree
    pointing to empty (the left child node of 45), start processing the top element of the stack and read the top element of the stack
    insert image description here
    insert image description here

  18. Query whether the left subtree with 45 as the root node has a right child node.
    If so, push it onto the stack. Query whether there is a left child node next.
    If not, it means that the subtree with 45 as the root node has been visited, and continue processing top element
    insert image description here

  19. Observe the situation of the right subtree with 21 as the root node, if curr=curr.right
    insert image description here
    the root node of the right subtree is not empty (60), push it into the stack
    insert image description here

  20. Observe whether there are left and right nodes in the right subtree with 60 as the root node.
    If there is a left child node, continue traversing.
    If there is no left child node, take out the top element (60) and start traversing the right subtree.
    If the right child node is not empty, push it into the stack to continue traversing
    If the right child node is empty and the stack is empty, the entire in-order traversal ends
    insert image description here

2.2 Code implementation

The description in front of the code directly copies the content of Likou. The main idea of ​​the function is to
traverse the binary tree from the root node. If the root node is empty, it will directly return an empty list.
Next is the normal process (the whole process is the same as the above traversal process)

  1. Create two new lists, one as a stack to store the top element of the stack, and one to store the final traversal result
  2. curr starts to point to the root node
  3. The end condition of the traversal is that the current pointer is empty and there are no elements in the stack (the while loop condition here)
  4. Push the root node onto the stack, and move the node pointer to the left
  5. When the left-shifted node pointer is empty, it means that the subtree with this node as the root node has no left child nodes, and the traversal order is left root right, then the left is empty, and the in-order traversal directly reads the top element of the stack ( The value of the root node), the pointer also points to the root node, and jumps out of the second while loop.
  6. Query the right child node whose root node is the subtree in the previous step, move the pointer, and continue to repeat the above traversal (enter the first while loop)
  7. End the in-order traversal until the pointer points to empty and there are no elements in the stack

2.2.1 python

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def inorderTraversal(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
    
        if not root:
            return []
        res, stack = list(), list()
        curr = root
        while curr or len(stack): # 指针为空且栈中元素为空时结束循环
            while curr: # 当前指针不为空,推入根节点
                stack.append(curr)
                curr = curr.left
            # 左子节点为空,则读取栈顶元素对应的根节点
            node = stack.pop()
            res.append(node.val)
            # 读取右子树
            curr = node.right
        return res

The use case given here is
Input: [1,null,2,3]
Output: [1,3,2]
Here I print the initial root node:
(TreeNode{val: 1, left: None, right: TreeNode{val: 2, left: TreeNode{val: 3, left: None, right: None}, right: None}}, 'root')
insert image description here

2.2.2 JavaScript

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
    
    
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {
    
    TreeNode} root
 * @return {
    
    number[]}
 */
var inorderTraversal = function(root) {
    
    
    if (!root) return []
    const stack = [], res = []
    let curr = root
    let node
    while (!(!stack.length && !curr)) {
    
     // 指针为空且栈中无元素时,结束循环
    // while (stack.length || curr) {
    
    
        while (curr) {
    
     // 指针不为空
            stack.push(curr)
            curr = curr.left
        }
        node = stack.pop()
        res.push(node.val)
        curr = node.right
    }
    return res
};

3. Recursive method

3.1 Traversal process

  1. The main idea of ​​splitting a binary tree
    insert image description here
    is to divide a complete binary tree into a left subtree, a root node, and a right subtree, and
    insert image description here
    continue to split further.
    insert image description here
    When the leftmost left subtree has an empty left child node, the recursion ends.

  2. Further visit sequentially from the smallest subtree
    insert image description here

  3. In -
    insert image description here
    order traversal = in-order traversal of the left subtree + root node + in-order traversal of the right subtree

3.2 Code implementation

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
    
    
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {
    
    TreeNode} root
 * @return {
    
    number[]}
 */
var inorderTraversal = function(root) {
    
    
    if (!root) return []
    
    const inorder = (node, res) => {
    
    
        if (!node) return
        inorder(node.left, res)
        res.push(node.val)
        inorder(node.right, res)
    }

    const res = []
    inorder(root, res)
    return res
};

reference link

Lekko explanation

Guess you like

Origin blog.csdn.net/m0_47146037/article/details/127259636
Recommended