[selected sword fingers] two solutions of “the next node of order traversal in binary tree” are explained in detail

Time:2021-12-30

Title Description

This is from niuke.com“Next node of JZ 57 binary tree”, difficulty is“Medium”

Tag: “sword finger offer”, “binary tree”, “middle order traversal”

Given a node in a binary tree, please find the next node in the middle order traversal order and return.

Note that the nodes in the tree contain not only the left and right child nodes, but also the next pointer to the parent node.

The following figure shows a binary tree with one node. The pointer from the parent node to the child node in the tree is represented by a solid line, and the pointer from the child node to the parent node is represented by a dotted line.

[selected sword fingers] two solutions of

Example:

Input: {8,6,10,5,7,9,11}, 8

Return: 9

Analysis: the root node of the subtree passed in from this assembly is actually the whole tree. It traverses {5,6,7,8,9,10,11} in the middle order. The next node of root node 8 is 9, which should return {9,10,11}. Only the next node of the subtree will be printed in the background, so only 9 will be printed. As shown in the figure below, in fact, there are pointers to the left and right children and to the parent node. The figure below is not drawn.

[selected sword fingers] two solutions of

Input Description: the input is divided into two segments. The first segment is the overall binary tree, and the second segment is the value of a given binary tree node. The background will assemble these two parameters into a binary tree, and the local subtree will be passed into the function GetNext. The user’s input has only one subtree root node.

Return value Description: returns the next node of the root node of the incoming subtree. This node will be printed out in the background.

Example 1

Input: {8,6,10,5,7,9,11}, 8

Return value: 9

Example 2

Input: {8,6,10,5,7,9,11}, 6

Return value: 7

Example 3

Input: {1,2, #, #, 3, #, 4}, 4

Return value: 1

Example 4

Input: {5}, 5

Return value: "null"

Description: does not exist, spooling "null"

requirement:

  • Time: 1 s
  • Space: 64 m

Naive solution

A simple way to do this is according to the topicTreeLinkNodeDefinition, usenextProperty stores the “parent node of the current node”.

From input parameter nodepNodeStart, keep usingnextProperty up until the head node of the whole tree is found, so that the head node isroot

Then, the “middle order traversal” of the binary tree is realized, and the nodes accessed in the traversal process are stored in the listlistYes, thenlistTraverse and findpNodeLocationidx, you can determinepNodeWhether there is a “next node” and which “next node” is.

[selected sword fingers] two solutions of

code:

import java.util.*;
public class Solution {
    List<TreeLinkNode> list = new ArrayList<>();
    public TreeLinkNode GetNext(TreeLinkNode pNode) {
        //According to the "next" pointer of the incoming node, keep looking up until the root node "root" is found
        TreeLinkNode root = pNode;
        while (root.next != null) root = root.next;

        //Perform a "middle order traversal" on the tree and save the results to the "list"
        dfs(root);

        //Find the location of the incoming node # pnode # from # list # idx
        int n = list.size(), idx = -1;
        for (int i = 0; i < n; i++) {
            if (list.get(i).equals(pNode)) {
                idx = i;
                break;
            }
        }
        
        //If {IDX} is not the last element of "middle order traversal", it indicates that there is a next node. Find it from {list} and return it
        //The judgment of {IDX = = - 1} here belongs to defensive programming
        return idx == -1 || idx == n - 1 ? null : list.get(idx + 1);
    }
    void dfs(TreeLinkNode root) {
        if (root == null) return;
        dfs(root.left);
        list.add(root);
        dfs(root.right);
    }
}
  • Time complexity: finding noderootThe maximum number of visited nodes will not exceed the tree height; The complexity of middle order traversal is; Found from the middle order traversal resultspNodeThe complexity of the next node of is. The overall complexity is
  • Space complexity: ignore the additional space consumption caused by recursion. Complexity is

Advanced Techniques

Another “advanced” approach is to make full use of “middle order traversal of binary tree”.

We know that the traversal order of “middle order traversal” of binary tree is“Left root right”

Can be based on incoming nodespNodeWhether there is a “right son” and the incoming nodepNodeWhether to discuss for the “left son” of its “parent node”:

  • Incoming nodepNodeThere is a “right son”: according to the “middle order traversal”, the traversal order is“Left root right”, it can be determined that the “next node” must be the “leftmost node” in the “right subtree” of the current node;
  • Incoming nodepNodeThere is no “right son”. In this case, we need to discuss the situation according to whether the current node is the “left son” of its “parent node”:
  • If the incoming nodepNodeIf it is the “left son” of its “parent node”, the traversal order according to the “middle order traversal” is“Left root right”It can be seen that the next node is the parent node. Just return to the node directly;
  • If the incoming nodepNodeIf it is the “right son” of its “parent node”, the traversal order according to the “middle order traversal” is“Left root right”It can be seen that its parent node has been traversed, and we need to recursively find the matching nodenode.equals(node.next.left)If not, it means that the current node is the rightmost node of the whole binary tree. At this time, it returnsnullJust.

code:

public class Solution {
    public TreeLinkNode GetNext(TreeLinkNode pNode) {
        if (pNode.right != null) {
            //If the current node has a right child, the next node is the "leftmost node in the right subtree" of the current node
            pNode = pNode.right;
            while (pNode.left != null) pNode = pNode.left;
            return pNode;
        } else {
            //If the current node does not have a right son, then "find the parent node up" until a parent node satisfying the requirement that "its left son is the current node" appears
            while (pNode.next != null) {
                if (pNode.equals(pNode.next.left)) return pNode.next;
                pNode = pNode.next;
            }
        }
        return null;
    }
}
  • Time complexity:
  • Spatial complexity: (see Top Comment) it’s o (1), not

last

This is the third article in our “selected sword fingers” seriesNo.57The series began on July 1, 2021.

This series will talk about all the classic and timeless topics in the “sword finger offer” of niuke.com.

While providing the pursuit of “proof” & “ideas”, it also provides the most concise code.

Welcome to pay attention and make a friend ω ・´)

[selected sword fingers] two solutions of