Binary tree recursive routine: judge whether it is a full binary tree and the number of nodes of the largest sub search binary tree

Posted by elementaluk on Tue, 25 Jan 2022 04:46:06 +0100

Today, continue the recursive routine of binary tree.

1, Determine whether it is a full binary tree

Full binary tree definition: for a binary tree with height h, the number of nodes is (2^h - 1)

1. Recursive routine idea

According to the definition of full binary tree, we only need to obtain the height and the number of nodes each time.

That is, we need the data of height and number of nodes from the left subtree and right subtree every time. Finally, we judge whether it is a full binary tree according to the relationship between height and number of nodes. Therefore, the following Info classes can be defined

/**
 * @author Java And algorithm learning: Monday
 */
public static class Info {
    public int height;
    public int nodes;

    public Info(int height, int nodes) {
        this.height = height;
        this.nodes = nodes;
    }
}

2. Recursive routine code

(1) First, judge whether it is good to set when the node is empty. When the node is empty, new Info(0, 0), that is, it is considered that the height of the empty node is 0 and the number of nodes is 0.

(2) Then write the code of the recursive routine according to all the possibilities listed. Because the whole recursion is to be formed, the Info class must be returned at each step. (no brain gets the Info of the left and right subtrees, pieces together his own Info, and returns his own Info)

/**
 * @author Java And algorithm learning: Monday
 */
public static Info process(Node x) {
    if (x == null) {
        return new Info(0, 0);
    }

    //Get the information of left and right subtrees
    Info leftInfo = process(x.left);
    Info rightInfo = process(x.right);

    //Piece together your own information
    int height = Math.max(leftInfo.height, rightInfo.height) + 1;
    int nodes = leftInfo.nodes + rightInfo.nodes + 1;

    return new Info(height, nodes);
}

(3) The main function calls the recursive method to get the result

/**
 * @author Java And algorithm learning: Monday
 */
public static boolean isFull(Node head) {
    if (head == null) {
        return true;
    }
    Info process = process(head);
    return (1 << process.height) - 1 == process.nodes;
}

All code addresses: https://github.com/monday-pro/algorithm-study/blob/master/src/basic/binarytree/IsFullBinaryTree.java

2, Find the node number of the largest sub search binary tree in the binary tree

Given a binary tree, the whole may or may not be a search binary tree, but some of its subtrees are search binary trees. To find the number of nodes of the sub search binary tree with the largest number of nodes.

1. Recursive routine idea

The maximum sub search binary tree is divided into two possibilities, including the binary tree head node and not including the binary tree head node.

(1) Excluding header nodes: it is necessary to find the maximum number of nodes of the left tree and the maximum number of nodes of the right tree

(2) Including header nodes: it is necessary to determine whether the left tree is a binary tree, whether the right tree is a binary tree, whether the maximum value of the left tree is less than the header node, and whether the minimum value of the right tree is greater than the header node. At the same time, it is also necessary to determine the number of nodes of the left tree and the right tree.

That is, each time from the left tree and the right tree, we need to maximize the number of nodes of the search binary tree, whether to search the binary tree, max, min and the number of nodes, but it can also be simplified. If the number of nodes of the maximum search binary tree is equal to the number of nodes, it means that the whole subtree is a search binary tree, so it can be simplified to the maximum number of nodes, max, min and the number of nodes of the search binary tree. Although we only return the number of nodes in the end, we need to search binary tree, max and min to help solve the number of nodes. Finally, you can define the following Info classes

/**
 * @author Java And algorithm learning: Monday
 */
public static class Info {
    //The maximum size of subtree satisfying the search condition of binary tree
    public int maxSubSize;

    public int max;

    public int min;

    //Number of nodes in the whole subtree
    public int allSize;

    public Info(int maxSubSize, int max, int min, int allSize) {
        this.maxSubSize = maxSubSize;
        this.max = max;
        this.min = min;
        this.allSize = allSize;
    }
} 

2. Recursive routine code

(1) First, judge whether it is good to set when the node is empty. At this time, it is not good to set. When the node is empty, max and min are not easy to specify. Therefore, when the node is empty, it will directly return null, and then deal with this null during recursion.

(2) Then write the code of the recursive routine according to all the possibilities listed. Because the whole recursion is to be formed, the Info class must be returned at each step. (no brain gets the Info of the left and right subtrees, pieces together his own Info, and returns his own Info)

/**
 * @author Java And algorithm learning: Monday
 */
public static Info process(Node x) {
    if (x == null) {
        return null;
    }

    //Get left and right subtree information
    Info leftInfo = process(x.left);
    Info rightInfo = process(x.right);

    //Piece together your own information
    int max = x.value;
    int min = x.value;
    int allSize = 1;
    if (leftInfo != null) {
        max = Math.max(leftInfo.max, max);
        min = Math.min(leftInfo.min, min);
        allSize += leftInfo.allSize;
    }
    if ((rightInfo != null)) {
        max = Math.max(rightInfo.max, max);
        min = Math.min(rightInfo.min, min);
        allSize += rightInfo.allSize;
    }

    //Left tree # maximum search binary tree size
    int p1 = -1;
    if (leftInfo != null) {
        p1 = leftInfo.maxSubSize;
    }

    //Right tree # maximum search binary tree size
    int p2 = -1;
    if (rightInfo != null) {
        p2 = rightInfo.maxSubSize;
    }

    //The largest subtree contains header nodes
    int p3 = -1;
    //Is the left tree a search binary tree
    boolean leftSearch = leftInfo == null || leftInfo.maxSubSize == leftInfo.allSize;
    //Is the right tree a search binary tree
    boolean rightSearch = rightInfo == null || rightInfo.maxSubSize == rightInfo.allSize;
    if (leftSearch && rightSearch) {
        //Whether the maximum value of the left tree is smaller than the current node value (null also means smaller than the current node)
        boolean lessMaxLessX = leftInfo == null || leftInfo.max < x.value;
        //Whether the minimum value of the right tree is greater than the current node value (null also means greater than the current node)
        boolean rightMinMoreX = rightInfo == null || rightInfo.min > x.value;

        //The value of p3 can be modified only after all conditions are met
        if (lessMaxLessX && rightMinMoreX) {
            int leftSize = leftInfo == null ? 0 : leftInfo.allSize;
            int rightSize = rightInfo == null ? 0 : rightInfo.allSize;
            p3 = leftSize + rightSize + 1;
        }
    }

    //Finally, modify the maximum search Binary subtree size of the current subtree
    int maxSubSize = Math.max(p1, Math.max(p2, p3));

    return new Info(maxSubSize, max, min, allSize);
}

(3) The main function calls the recursive method to get the result

/**
 * @author Java And algorithm learning: Monday
 */
public static int maxSubSearchBinaryTreeSize(Node head) {
    if (head == null) {
        return 0;
    }
    return process(head).maxSubSize;
}

All code addresses: https://github.com/monday-pro/algorithm-study/blob/master/src/basic/binarytree/MaxSubSearchBinaryTreeSize.java

3, Binary tree recursive routine summary

Do you feel a little bit about the recursive routine of binary tree? It's time to summarize the recursive routine of binary tree.

1. Assuming that the X node is the head, it is assumed that any information can be requested from the X left tree and the X right tree

2. Under the assumption of the previous step, discuss the tree with X as the head node, and list the possibility of getting the answer (the most important)

3. After listing all the possibilities, determine what information you need from the left tree and the right tree

4. Seeking the complete set of left tree information and right tree information is the information Info that any subtree needs to return

5. Recursive functions return Info, which is required for each subtree

6. Write code and consider how to integrate the information of the left tree and the information of the right tree into the information of the whole tree

After reading the previous binary tree recursion routine, and then look at this summary, is it handy.

Topics: Algorithm data structure Binary tree recursion