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
The result should be
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.
-
Starting from the root node (23), curr starts pointing to the original root node
-
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)
-
Find the left subtree node of the current node (34), curr=curr.left
-
If the currently moved curr (pointing to 34) is not empty, push it onto the stack
-
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)
-
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
-
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
far, the left subtree with 77 as the root node has been visited -
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
-
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
-
Query whether the right subtree with 90 as the root node has a left child node.
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
-
Query whether the subtree with 90 as the root node has a right subtree
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 -
Continue to read the top element of the stack (corresponding to 34 at this time)
. 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. -
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.
Continue to process the elements in the stack -
Continue to read the elements in the stack (23 at this time).
At this time, the left subtree of the entire binary tree has been traversed, and then the corresponding right subtree is traversed. -
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)
-
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)
-
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
-
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
-
Observe the situation of the right subtree with 21 as the root node, if curr=curr.right
the root node of the right subtree is not empty (60), push it into the stack
-
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
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)
- Create two new lists, one as a stack to store the top element of the stack, and one to store the final traversal result
- curr starts to point to the root node
- 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)
- Push the root node onto the stack, and move the node pointer to the left
- 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.
- 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)
- 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')
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
-
The main idea of splitting a binary tree
is to divide a complete binary tree into a left subtree, a root node, and a right subtree, and
continue to split further.
When the leftmost left subtree has an empty left child node, the recursion ends. -
Further visit sequentially from the smallest subtree
-
In -
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
};