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
 Empty binary tree
 Binary tree with only one root node
 Only left subtree
 Complete binary tree
 Only right subtree
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
 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 hasrecursionandnonrecursive Two implementation methods
 PreambleTraversal isDepth first traversal（DFS）
 arrangementTraversal isbreadthfirst 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)
The following figure shows the middle order traversal (left)root(right)
The following figure shows the post order traversal (left and right)root）
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;
}
}
 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;
}
}
 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;
}
}
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;
}
}
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
 Preorder traversal (leetcode 144)
 Medium order traversal (leetcode 94)
 Leetcode257 all paths of binary tree
 Maximum depth of leetcode104 binary treeAndSword finger offer 55iidentical
 Sequence traversal of leetcode107 binary tree 2
Previous highlights
 Jingdong interviewer asked me, “talk about MySQL affairs, mvcc? (good article, recommended Collection)”
 Hello, my name is AQS (Series 1: locking)
 Can you answer Jingdong’s interview question?
 ？ Why can thread pools be reused? I’m masked…
 Learned volatile, you changed your mind, I saw it
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