[Leetcode Series] [] [medium] algorithm of binary tree traversal sequence (recursion, stack, Morris morris)

table of Contents

 

topic:

Problem-solving ideas:

Method a: recursion (time O (N), the space O (N))

Method two: Stack (time O (N), the space O (N))

Method three: Morris traverse (time O (N), the space O (1))

Problem-solving ideas:

Method One: recursive

Method Two: Stack

Method three: Morris


topic:

Topic links:  https://leetcode-cn.com/problems/binary-tree-inorder-traversal/

 

Problem-solving ideas:

Method a: recursion (time O (N), the space O (N))

Each recursion, if the left subtree, then continue to use the left subtree recursively

If there is no left subtree, the current value will be added to the result set, returns to the recursion level

On a layer recursion, the first current value is added to the result set, determines whether to continue the right subtree

If a right subtree, the right subtree recursively continue, if not right subtree, return to the previous recursion continues, this logic is repeated

 

Method two: Stack (time O (N), the space O (N))

First push the root node, traversing

As long as the stack is not empty, you get the elements of the stack from the stack, and determine whether the left subtree

If you have left subtree of the left subtree stack, and then continue to traverse; get to the next traversing the top of the stack, the stack-oriented traversal left subtree

If you do not no left subtree, the current value is added to the result set, and the top of the stack sub-tree out of the stack

Continue to get subtree from the stack, the stack and the stack sub-tree, is added to the result set value, and then determines whether the right subtree

If you have the right subtree, then the right subtree pop, continue a cycle; if there is no right subtree, small cycles continue to get the top element

Illustrated as follows:

The root node stack

The left subtree stack 1 of 2

The left subtree stack 2 of 4

Since there is no left subtree 4, the stack 4, and 4 is added to the result set in res

4 because there is no right subtree, so continue to stack the top element 2, and added to the result set in res

Because there are 2 right subtree, so we do not continue to get elements from the top of the stack, and the right subtree stack 2 of 5

4 and 5 the same as the case of the stack 5, is added to the result set

From the top of the stack a stack, is added to the result set

Because 1 have the right subtree, the right subtree will push 1 3

3 because there is no left subtree, the stack will be the top element 3, is added to the result set

The right subtree of the stack 3

The stack 6, is added to the result set

There are no elements in the stack, stop the walk, return results

 

Method three: Morris traverse (time O (N), the space O (1))

Logic is as follows:

variable:

  1. root: root of the tree
  2. curr: The current traversed nodes, initialized to root
  3. prev: secondary node, initialized to empty

Process:

  1. If curr left subtree is empty, the curr value is added to the result set, and curr traversing right subtree
  2. If curr left subtree is not empty, the operation is carried out under the note:
    1. prev start traversing the right subtree curr left sub-tree, until there is no right subtree, or traverse to the node curr
    2. If prev right subtree is empty, then the right subtree pointing curr prev
    3. If prev right subtree is not empty, then curr.val added to the result set, update curr = curr.right right subtree, prev = None, continue to traverse

Icon:

Suppose the original structure of a tree as follows:

Black is always original root node node, this time pointing to the root node curr, curr node in the left subtree is 2, is not empty, then the prev points 2, starting from the right subtree 2 of 5 traversal:

When the search to 8, because there is no right subtree 8, the search is stopped, when three nodes as follows (curr, root in 1 position):

At this time, the right subtree pointing Curr prev, update curr = curr.left, node positions and is connected at this time are as follows (solid line represents the original tree structure, the dashed line is newly added connection):

Continue to cycle, this time prev = 2 left subtree is not empty, continue to point to curr prev left subtree, start the search:

4 no right subtree, so exit the search, will continue right subtree prev points to curr, update curr = curr.left, node locations, and links at this time is as follows (prev points after 4 because there is no right sub-tree traversal, so this time prev and curr in the same location):

To traverse this case, curr found no left subtree, so the result is added to the value of curr res set by the broken line, updating curr = curr.right, the next cycle begins. At this time curr = 2, so prev = curr.left left subtree 2 continues from 4 to start the search, right node 4 is 2, in line with the conditions curr = prev, the search is stopped, this time as follows:

When the search is stopped, prev = 4 right subtree is not empty, so in this case 2 will be added to the result set, update curr = curr.right, add more out of connection removed before that update prev.right = None, continue cycle:

After the logic above, the illustrated process is as follows:

 

Problem-solving ideas:

Method One: recursive

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

class Solution:
    def inorderTraversal(self, root: TreeNode) -> List[int]:
        def order_help(node, res):
            if node and node.left:
                order_help(node.left, res)
                
            if node:
                res.append(node.val)
            
            if node and node.right:
                order_help(node.right, res)
                
        res = []
        order_help(root, res)
        return res

 

Method Two: Stack

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

class Solution:
    def inorderTraversal(self, root: TreeNode) -> List[int]:
        if not root:
            return []
        
        node_stack = [root]
        res = []
        while 0 < len(node_stack):
            if node_stack[-1].left:
                node_stack.append(node_stack[-1].left)
                continue
                
            while 0 < len(node_stack):
                last_node = node_stack[-1]
                node_stack.pop()
                res.append(last_node.val)
                if last_node.right:
                    node_stack.append(last_node.right)
                    break

        return res

 

Method three: Morris

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

class Solution:
    def inorderTraversal(self, root: TreeNode) -> List[int]:
        curr = root
        prev = None
        res = []
        while curr:
            if not curr.left:
                res.append(curr.val)
                curr = curr.right
            else:
                prev = curr.left
                while prev.right and prev.right != curr:
                    prev = prev.right
                    
                if not prev.right:
                    prev.right = curr
                    curr = curr.left
                else:
                    res.append(curr.val)
                    prev.right = None
                    curr = curr.right
        
        return res
                

 

Published 100 original articles · won praise 4 · Views 1465

Guess you like

Origin blog.csdn.net/songyuwen0808/article/details/105373627