Issue 35: Learn Binary Tree from DFS! (Suitable for Xiaobai)

I have prepared 1,000 e-books and 100 high-definition mind maps in various fields of computer, and I will reply to [Resources] after paying attention to get it! You can even reply [introduction] to join the BAT introduction group!

Issue 35: Learn Binary Tree from DFS!  (Suitable for Xiaobai)

In computer science, a binary tree is a tree structure with at most two subtrees per node . Usually subtrees are called "left subtree" and "right subtree". Binary trees are often used to implement binary search trees and binary heaps. Trees are slightly more complicated than linked lists because linked lists are linear data structures, and trees are not. Many tree problems can be solved by breadth first search or depth first search .

In this series, we will learn about the classic operations of binary trees through some examples!

01, topic analysis


Question 104: The maximum depth of a binary tree


Given a binary tree, find its maximum depth. The depth of the binary tree is the number of nodes on the longest path from the root node to the farthest leaf node


Explanation: A leaf node refers to a node without child nodes.

Example:

给定二叉树 [3,9,20,null,null,15,7],
    3   
   / \  
  9  20    
    /  \  
   15   7

02, recursive solution


We know that the depth of each node is related to the depth of its left and right subtrees, and is equal to the maximum depth value of its left and right subtrees plus 1. which is:

maxDepth(root) = max(maxDepth(root.left),
maxDepth(root.right)) + 1

Take [3,4,20,null,null,15,7] as an example:

<1> If we want to solve the maximum depth of the root node, we must solve the depth of its left and right subtrees

Issue 35: Learn Binary Tree from DFS!  (Suitable for Xiaobai)

<2>We see. The subtree with 4 as the root node has no left and right nodes, and its depth is 1. The depth of the subtree with 20 as the root node also depends on the depth of its left and right subtrees.
Issue 35: Learn Binary Tree from DFS!  (Suitable for Xiaobai)

<3> For the subtrees of 15 and 7, we can see that the depth is 1 at a glance.
Issue 35: Learn Binary Tree from DFS!  (Suitable for Xiaobai)

<4>From this we can get the maximum depth of the root node as:

maxDepth(root-3)
=max(**maxDepth**(sub-4),**maxDepth**(sub-20))+1
=max(1,max(**maxDepth**(sub-15),**maxDepth**(sub-7))+1)+1
=max(1,max(1,1)+1)+1
=max(1,2)+1
=3

According to the analysis, we solve the code through recursion as follows:

func maxDepth(root *TreeNode) int {
    if root == nil {
        return 0
    }
    return max(maxDepth(root.Left), maxDepth(root.Right)) + 1
}

func max(a int, b int) int {
    if a > b {
        return a
    }
    return b
}

03、DFS


In fact, the recursive method we used above essentially uses the idea of ​​DFS. Let me first introduce DFS: Depth First Search. For binary trees, it traverses the nodes of the tree along the depth of the tree and searches the branches of the tree as deep as possible . This process continues until the source has been found Up to all nodes reachable by the node.

Issue 35: Learn Binary Tree from DFS!  (Suitable for Xiaobai)
As shown in the figure above, the access sequence of the binary tree is:

A-B-D-E-C-F-G

A-B-D-E-C-F-G

Here, we think about a question? Although we used a recursive way to successfully complete the topic based on the idea of ​​DFS. But the shortcomings of this approach are obvious. Because in recursion, if the hierarchy is too deep, we are likely to save too many temporary variables, causing stack overflow . This is why we generally don't use recursion in background code. If you don’t understand, let’s explain in detail below:

In fact, the parameters of the function call are passed through the stack space, and the stack resources of the thread will be occupied during the call . For recursive calls, functions can only exit after reaching the final end point. Before reaching the final end point, the occupied stack space has not been released. If there are too many recursive calls, the occupied stack resources may exceed the thread. The maximum value of, which causes the stack to overflow and cause the program to exit abnormally.

So, we bring up the following topic: how to convert recursive code into a non-recursive form. Please keep in mind here that 99% of recursive to non-recursive can be achieved through the stack.

Non-recursive DFS, the code is as follows:

private List<TreeNode> traversal(TreeNode root) {     
    List<TreeNode> res = new ArrayList<>(); 
    Stack<TreeNode> stack = new Stack<>(); 
    stack.add(root); 
    while (!stack.empty()) { 
        TreeNode node = stack.peek(); 
        res.add(node);         
        stack.pop();                         
        if (node.right != null) {
           stack.push(node.right);
           }
        if (node.left != null) {
           stack.push(node.left);
           }
     }
     return res;
}

In the above code, the only thing that needs to be emphasized is, why do we need to push data in right and then left? It is because we need to first access the data and then push it onto the stack (please consider the characteristics of the stack).

If you don’t understand the code, please see the picture below:
Issue 35: Learn Binary Tree from DFS!  (Suitable for Xiaobai)

1: First push a onto the stack

2: a pops the stack and pushes c and b into the stack (note the order)

3: b pops the stack, pushes e and d into the stack

4: d, e, c pop the stack, push g, f into the stack

5: f, g bomb stack

At this point, the explanation of non-recursive DFS is complete.

Guess you like

Origin blog.51cto.com/15076236/2608548