Classmate, I have summarized various traversal methods of binary tree for you, with a diagram of queue stack (consolidate the foundation and strongly recommend Collection)

Time:2021-11-27

Hello, ladies and gentlemen, I am the official account.Jack, come onToday, I’d like to share an article about binary tree (recommended collection, easy to consolidate the foundation).

  • After reading this article, leetcode solves at least eight questions
  • Master the pre order, middle order and post order traversal of binary tree and two different implementation methods: recursive and non recursive
  • During non recursive traversal and hierarchical traversal, there are detailed diagrams to show how the elements in the queue / stack move, which is helpful to understand the operation of the code

Introduction to binary tree

Binary treeIt refers to an ordered tree in which the degree of nodes in the tree is no more than 2. It is the simplest and most important tree.

The recursive definition of binary tree is:A binary tree is an empty tree, or a non empty tree composed of a root node and two disjoint left and right subtrees called roots respectively; The left subtree and the right subtree are also binary trees

  • Logically, a binary tree hasFive basic forms, as shown in the figure

    1. Empty binary tree
    2. Binary tree with only one root node
    3. Only left subtree
    4. Complete binary tree
    5. Only right subtree

Classmate, I have summarized various traversal methods of binary tree for you, with a diagram of queue stack (consolidate the foundation and strongly recommend Collection)

Explanation of binary tree related attributes:

  • node: contains a data element and several information pointing to the branches of the subtree.
  • Degree of node: the number of subtrees a node has is called the degree of the node.
  • leaf node : also known as terminal node, node without subtree or node with zero degree.
  • Branch node: it is also called non terminal node, and the node whose degree is not zero is called non terminal node.
  • Degree of tree: the maximum degree of all nodes in the tree.
  • Hierarchy of nodes: starting from the root node, it is assumed that the root node is layer 1, and the child nodes of the root node are layer 2, and so on. If a node is located in layer L, its child nodes are located in layer L + 1.
  • Depth of tree: also known as the height of the tree. The maximum hierarchical value of all nodes in the tree is called the depth of the tree.
  • Ordered tree: if the order of each tree in the tree is in order, the tree is called ordered tree.
  • Disordered tree: if the order of each sub tree in the tree has no order, the tree is called an unordered tree.

Binary tree traversal mode

  • There are three traversal methods of binary tree

    • Preorder traversal (around the root): access the root node, then the left subtree, and then the right subtree.
    • Middle order traversal (left root right): first access the left subtree, then the root node, and then the right subtree.
    • Subsequent traversal (left and right roots): first access the left subtree, then the right subtree, and then the root node.

For example, a binary tree like this is traversed by three traversal methods, and the output results are

Classmate, I have summarized various traversal methods of binary tree for you, with a diagram of queue stack (consolidate the foundation and strongly recommend Collection)

  • Preorder traversal: abdecfg
  • Middle order traversal: dbeafcg
  • Subsequent traversal: debfgca

Let’s implement these three traversals in code

  • Note: abovePre order, middle order and post orderEach traversal method hasrecursionandnon-recursive Two implementation methods
  • PreambleTraversal isDepth first traversal(DFS)
  • arrangementTraversal isbreadth-first search (BFS)

Recursive traversal of binary tree

*Preorder traversal (leetcode 144)

class Solution {
    //Declaration list
    ArrayList<Integer> list = new ArrayList<>();
    public List<Integer> preorderTraversal(TreeNode root) {
        //If the root node is empty, the empty list is returned directly
        if (root == null){
            return  new ArrayList<>();
        }
        //The node is not empty. Add the value of the node to the list    
        list.add(root.val);
        //Judge whether the left node of this node is empty. If not, the left subtree will be traversed recursively
        if (root.left != null){
            preorderTraversal(root.left);
        }
        //Judge whether the right node of this node is empty. If not, the right subtree will be traversed recursively
        if (root.right != null){
            preorderTraversal(root.right);
        }
        //Finally, return to the list
        return list;
    }
}
class Solution {
    //Declaration list
    ArrayList<Integer> list = new ArrayList<>();
    public List<Integer> inorderTraversal(TreeNode root) {
        //If the root node is empty, the empty list is returned directly
        if (root == null){
            return  new ArrayList<>();
        }
        //Judge whether the left node of this node is empty. If not, it will recursively traverse the left subtree of this node
        if (root.left != null){
            inorderTraversal(root.left);
        }
        //The node is not empty. Add the value of the node to the list
        list.add(root.val);
        //Judge whether the right node of this node is empty. If it is not empty, the right subtree of this node will be traversed recursively
        if (root.right != null){
            inorderTraversal(root.right);
        }
        //Finally, return to the list
        return list;
    }
}
class Solution {
    //Declaration list
    ArrayList<Integer> list = new ArrayList<>();
    public List<Integer> postorderTraversal(TreeNode root) {
        //If the root node is empty, the empty list is returned directly
        if (root == null){
            return  new ArrayList<>();
        }
        //Judge whether the left node of this node is empty. If not, it will recursively traverse the left subtree of this node
        if (root.left != null){
            postorderTraversal(root.left);
        }
        //Judge whether the right node of this node is empty. If it is not empty, the right subtree of this node will be traversed recursively
        if (root.right != null){
            postorderTraversal(root.right);
        }
        //The node is not empty. Add the value of the node to the list
        list.add(root.val);
        //Finally, return to the list
        return list;
    }
}

Through observation, we find that the code is so similar. Yes, it is very similar. The only difference between them islist.add(root.val);The position of the code is different. This line of code represents theTraversal (access)
The following figure shows the preorder traversal(root(left and right)

Classmate, I have summarized various traversal methods of binary tree for you, with a diagram of queue stack (consolidate the foundation and strongly recommend Collection)
The following figure shows the middle order traversal (left)root(right)

Classmate, I have summarized various traversal methods of binary tree for you, with a diagram of queue stack (consolidate the foundation and strongly recommend Collection)

The following figure shows the post order traversal (left and right)root

Classmate, I have summarized various traversal methods of binary tree for you, with a diagram of queue stack (consolidate the foundation and strongly recommend Collection)

Non recursive traversal of binary tree

  • Use stack (Filo first in and last out feature)
  • After each piece of code, there is a specific process of the relationship between the stack and its elements. It is recommended to calm down and look at it slowly to help understand how the code runs
  • Preorder traversal
class Solution {
    List list =   new ArrayList();
    public List<Integer> preorderTraversal(TreeNode root) {
        //If the root node is empty, the empty list is returned directly
        if(root==null){
            return  new ArrayList();
        }
        //Declare a stack
        Stack<TreeNode> stack = new Stack<>();
        //Stack nodes
        stack.push(root);
        //If the stack is not empty
        while (!stack.empty()){
            //Pop this node from the stack
            TreeNode node = stack.pop();
            //Add to list
            list.add(node.val);
            //If the right child node of this node is not empty
            if (node.right!=null){
                //Put it into the stack. Because the stack is first in and then out, press the right child node of the stack first and then out
                stack.push(node.right);
            }
            //If the left child node of this node is not empty
            if (node.left!=null){
                //Put it into the stack. Because the stack is first in and last out, the left child node of the last stack is first out
            }
        }
        //Return to list
        return list;
    }
}

Classmate, I have summarized various traversal methods of binary tree for you, with a diagram of queue stack (consolidate the foundation and strongly recommend Collection)

Classmate, I have summarized various traversal methods of binary tree for you, with a diagram of queue stack (consolidate the foundation and strongly recommend Collection)

  • Medium order traversal
class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
        //Judge whether the node is empty. If it is empty, the empty list will be returned directly
        if (root == null){
            return new ArrayList();
        }
        //The declaration list stores the results
        List<Integer> list =  new ArrayList();
        //Declare a stack
        Stack<TreeNode> stack = new Stack<>();
        //When the node is not empty or the stack is not empty
        while (root != null || !stack.empty()){
            //When the node is not empty
            while (root != null){
                //Stack nodes
                stack.push(root);
                //Point the node to its left child node
                root = root.left;
            }
            //If the stack is not empty
            if (!stack.empty()){
                //Pop up the elements in the stack
                TreeNode node = stack.pop();
                //Add to list
                list.add(node.val);
                //Point the node to its right child node
                root = node.right;
            }
        }
        return list;
    }
}

Classmate, I have summarized various traversal methods of binary tree for you, with a diagram of queue stack (consolidate the foundation and strongly recommend Collection)

Classmate, I have summarized various traversal methods of binary tree for you, with a diagram of queue stack (consolidate the foundation and strongly recommend Collection)

  • Postorder traversal
class Solution {
    public List<Integer> postorderTraversal(TreeNode root) {
        //If the root node is empty, the empty list is returned directly
        if (root == null){
            return  new ArrayList<>();
        }
        //Declaration list
        ArrayList<Integer> list = new ArrayList<>();
        //Declaration stack a
        Stack<TreeNode> stackA = new Stack<TreeNode>();
        //Declaration stack B
        Stack<TreeNode> stackB = new Stack<TreeNode>();
        //Push secondary element into stack a
        stackA.push(root);
        //When stack a is not empty
        while (!stackA.empty()){
            //Take out the pressed elements
            TreeNode node = stackA.pop();
            //Push into stack B
            stackB.push(node);
            //When the left child node of this node is not empty
            if (node.left != null){
                //Push into stack a
                stackA.push(node.left);
            }
            //When the right child node of this node is not empty
            if (node.right != null){
                //Push into stack a
                stackA.push(node.right);
            }
        }
        //When stack B is not empty
        while (!stackB.empty()){
            //Take out its elements and add them to the list
            TreeNode node = stackB.pop();
            list.add(node.val);
        }
        //Finally, return to the list
        return list;
    }
}

Classmate, I have summarized various traversal methods of binary tree for you, with a diagram of queue stack (consolidate the foundation and strongly recommend Collection)

Classmate, I have summarized various traversal methods of binary tree for you, with a diagram of queue stack (consolidate the foundation and strongly recommend Collection)

Binary tree sequence traversal (BFS)

  • Sequence traversal of leetcode 102 binary tree
  • After using the queue (FIFO first in first out feature) code, there is a specific process of the relationship between the queue and its elements. It is recommended to calm down and take a slow look to help understand how the code runs
class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        if (root == null) {
            return new ArrayList<List<Integer>>();
        }
        //Declare a list to store data for each row
        List<List<Integer>> result = new ArrayList<>();
        //Declare a queue
        LinkedList<TreeNode> queue = new LinkedList<>();
        //If the root node is not empty, queue it
        queue.offer(root);
        //When the queue is not empty, it means that there is data in the queue
        while (!queue.isEmpty()) {
            //Store the data line of each row
            List<Integer> line = new ArrayList<Integer>();
            //Save the number of existing data in the queue. These are the values to be added to each row list
            int size = queue.size();
            for (int i=0;i<size;i++){
            //Take out the node of the queue (FIFO first in first out)
            TreeNode node = queue.poll();
            line.add(node.val);
              if (node.left != null) {
                  queue.offer(node.left);
              }
              if (node.right != null) {
                  queue.offer(node.right);
              }
            }
            result.add(line);
        }
        return result;
    }
}

Classmate, I have summarized various traversal methods of binary tree for you, with a diagram of queue stack (consolidate the foundation and strongly recommend Collection)

Leetcode binary tree related exercises

  • As we have seen here, we have a certain understanding of the pre order (DFS), middle order, post order, recursive / non recursive and hierarchical traversal (BFS) of binary trees(If the above pictures are digested

Then let’s strike while the iron is hot and try a few leetcode questions! (the overall code is only slightly changed from the above, because the general idea is the same. It’s easy to digest all the above contents)

class Solution {
    public List<String> binaryTreePaths(TreeNode root) {
        if (root == null){
            return new ArrayList<>();
        }
        ArrayList<String> list = new ArrayList<>();
        Stack<TreeNode> stack = new Stack<TreeNode>();
        //This stack storage path operates the same as the stack of the previous storage node
        Stack<String> path = new Stack<String>();
        stack.push(root);
        path.push(root.val+"");
        while (!stack.empty()){
            TreeNode node = stack.pop();
            String p = path.pop();
            //When it is a leaf node, the path in the stack is a complete path, which can be added to the result
            if (node.right == null && node.left == null ){
                list.add(p);
            }
            //If the right child node is not empty
            if (node.right != null){
                stack.push(node.right);
                //Continue pressing the temporary path
                path.push(p+"->"+node.right.val);
            }
            //If the left child node is not empty
            if (node.left != null){
                stack.push(node.left);
                //Continue pressing the temporary path
                path.push(p+"->"+node.left.val);
            }
        }
        return list;
    }
}
class Solution {
    public int maxDepth(TreeNode root) {
       if (root == null){
           return 0;
       }
        LinkedList<TreeNode> queue = new LinkedList<>();
        int result = 0;
        queue.offer(root);
        while (!queue.isEmpty()){
            //Number of layers + 1
            result++;
            //This is the number of nodes in the current layer
            int size = queue.size();
            for (int i=0;i<size;i++){
                //Only after all of them are out of the team can they be counted again
                TreeNode node = queue.poll();
                if (node.left != null){
                    //If the outgoing node has left child nodes, join the queue
                    queue.offer(node.left);
                }
                if (node.right != null){
                    //If the outgoing node has a right child node, join the queue
                    queue.offer(node.right);
                }
            }
        }
        //Returns the number of layers
        return result;

    }
}
class Solution {
    public List<List<Integer>> levelOrderBottom(TreeNode root) {
        if (root == null){
            return new ArrayList<List<Integer>>() ;
        }
        List<List<Integer>> result = new ArrayList<List<Integer>>() ;
        LinkedList<TreeNode> queue = new LinkedList<>();
        //Declare a stack to store the nodes of each layer
        Stack<ArrayList<Integer> > stack = new Stack<>();
        queue.offer(root);
        while (!queue.isEmpty()){
            int size = queue.size();
            ArrayList<Integer> list = new ArrayList<>();
            for (int i=0;i<size;i++){
                TreeNode node = queue.poll();
                list.add(node.val);
                if (node.left != null){
                    queue.offer(node.left);
                }
                if (node.right != null){
                    queue.offer(node.right);
                }
            }
            //Push the nodes of this layer into the stack
            stack.push(list);
        }
        //When the stack is not empty, the result will pop up, so as to traverse the binary tree from bottom to top
        while (!stack.isEmpty()){
            ArrayList<Integer> list = stack.pop();
            result.add(list);
        }
        return result;
    }
}

summary

Through this article, we can at least solve the following problems on leetcode

Previous highlights

hum about

If you think this article is a little helpful to you,Welcome to official account No. Java Gon Freecss.

If the article is wrong, you are welcome to point it out, pretty boys and girls, see you in the next article,Sweep, pay attention to me and start our story

Classmate, I have summarized various traversal methods of binary tree for you, with a diagram of queue stack (consolidate the foundation and strongly recommend Collection)