# Preface

The related concepts of binary trees are also not introduced here. After all, the basic data structure has been discussed a lot, so it is not repeated here.For some balanced binary trees, complete binary trees, red-black trees, B+trees and other related structures, this has been introduced by many blogs, here is just some basic operations of binary trees.

# Definition

This should have been seen many times

```/**
* autor:liman
* createtime:2020/2/6
* comment:Implementation of Binary Tree Node
*/
public class TreeNode {

public String value;
public TreeNode left;
public TreeNode right;

public TreeNode(String value) {
this.value = value;
}
}
```

# Traversed non-recursive implementation

Recursive implementations are very simple, and many people are expected to do so. Here's a description of non-recursive traversal implementations

The basic traversal operation is as follows:The output shown here represents the traversal operation

```/**
* Do traversal.
*
* @param node
*/
public static void doTraverse(TreeNode node) {
System.out.print(node.value + " ");
}
```

## Preorder traversal

```/**
* Priority traversal of non-recursive implementations, where stack operations are used
*
* @param root
*/
public static void preOrderTraverse(TreeNode root) {
if (root != null) {//If the root node is not empty
Stack<TreeNode> stack = new Stack<>();//Non-recursive to use stack
stack.push(root);
while (!stack.isEmpty()) {
TreeNode node = stack.pop();
doTraverse(node);
//Judge the right subtree before the left subtree
if (node.right != null) {//Judges the right subtree, if it is not empty, stacks
stack.push(node.right);
}
if (node.left != null) {//Judge left subtree, if left subtree is not empty then stack
stack.push(node.left);
}
}
}
}
```

## Intermediate traversal

```/**
* Ordered traversal in a non-recursive implementation
*
* @param root
*/
public static void innerOrderTraverse(TreeNode root) {
if (root != null) {
Stack<TreeNode> stack = new Stack<>();
//Continuously stack the left subtree to find the leftmost node in the whole tree (the first node traversed in middle order)
while (!stack.isEmpty() || root != null) {
if (root != null) {
stack.push(root);
root = root.left;
} else {//If the left subtree of the node is empty, it pops up, traverses, and points to the right subtree.
root = stack.pop();
doTraverse(root);
root = root.right;
}
}

}
}
```

## Subsequent traversal

```/**
* Non-recursive implementation of post-traversal, one stack is cumbersome, two stacks are relatively simple
*
* @param root
*/
public static void postOrderTraverse(TreeNode root) {
if (root != null) {
Stack<TreeNode> stack1 = new Stack<>();
Stack<TreeNode> stack2 = new Stack<>();//Store elements to traverse
stack1.push(root);
while (!stack1.isEmpty()) {
TreeNode pop = stack1.pop();
stack2.push(pop);
if (pop.left != null) {
stack1.push(pop.left);
}
if (pop.right != null) {
stack1.push(pop.right);
}
}
while (!stack2.isEmpty()) {
doTraverse(stack2.pop());
}
}
}
```

## level traversal

```/**
* Hierarchical traversal, non-recursive implementation
* @param root
*/
public static void levelOrderTraverse(TreeNode root) {
if (root != null) {
Queue<TreeNode> queue = new ArrayDeque<>();
queue.offer(root);//root Queued
while (!queue.isEmpty()) {
//Get the number of nodes at the current level
int levelNum = queue.size();
for (int i = 0; i < levelNum; i++) {
TreeNode node = queue.poll();
doTraverse(node);
if (node.left != null) {//Queued Left Subtree
queue.offer(node.left);
}

if (node.right != null) {//Queue Right Subtree
queue.offer(node.right);
}
}
}
}
}
```

# Calculating the Depth of a Binary Tree (Maximum Depth and Minimum Depth)

## Maximum Depth

### Recursive implementation

Recursive maximum depth, code is simplest

```/**
* Recursive calculation of maximum depth
*
* @param root
* @return
*/
public int maxDepth(TreeNode root) {
if (root == null) {
return 0;
}
int left = maxDepth(root.left);
int right = maxDepth(root.right);
return Math.max(left, right) + 1;//After all, the root node is one level high.
}
```

### Non-recursive implementation

```/**
* Non-recursive maximum depth, using hierarchical traversal
*
* @param root
* @return
*/
public int maxDepthLevel(TreeNode root) {
if (root == null) {
return 0;
}

Queue<TreeNode> queue = new ArrayDeque<>();
queue.offer(root);
int level = 0;
while (!queue.isEmpty()) {
level++; //Here the statistical level is high
int levelNum = queue.size();
for (int i = 0; i < levelNum; i++) {
TreeNode node = queue.poll();
if (node.left != null) {
queue.offer(node.left);
}

if (node.right != null) {
queue.offer(node.right);
}
}
}
return level;
}
```

## Minimum Depth

The minimum depth is more than the maximum depth, returning 0 directly if the tree is empty, 1 directly if there is only one root node, and the minimum depth of the right subtree if the left subtree is empty and the right subtree is not empty.If the right subtree is empty and the left subtree is not empty, the minimum depth of the left subtree needs to be calculated.

### Recursive implementation

```/**
* Recursively find the minimum depth of a tree, there are more conditions to consider here
*
* @param root
* @return
*/
public int mixDepth(TreeNode root) {
if (root == null) {//Tree is empty
return 0;
}
if (root.left == null && root.right == null) {//Only one root node
return 1;
}
if (root.left == null && root.right != null) {//Left subtree is empty, right subtree is not empty
return mixDepth(root.right) + 1;
}
if (root.right == null && root.left != null) {//Right subtree is empty, left subtree is not empty
return mixDepth(root.left) + 1;
}

//This is when neither the left subtree nor the right subtree is empty
int left = mixDepth(root.left);
int right = mixDepth(root.right);
return Math.min(left,right)+1;
}
```

### Non-recursive implementation

When traversing through a hierarchy, the height of the first node that encounters an empty left and right subtree must be the minimum depth

```public int mixDepthLevel(TreeNode root){
if (root == null) {
return 0;
}

Queue<TreeNode> queue = new ArrayDeque<>();
queue.offer(root);
int level = 0;
while (!queue.isEmpty()) {
level++;
int levelNum = queue.size();
for (int i = 0; i < levelNum; i++) {
TreeNode node = queue.poll();
//The height of the first node with empty left and right subtrees must be the minimum depth
if(node.left== null && node.right == null){
return level;
}
if (node.left != null) {
queue.offer(node.left);
}

if (node.right != null) {
queue.offer(node.right);
}
}
}
return 0;
}
```

# Compute the nearest ancestor of two nodes

```/**
* Recursively implements the closest ancestor of two nodes
* @param root
* @param node01
* @param node02
* @return
*/
public TreeNode lowestCommoAncestor(TreeNode root, TreeNode node01, TreeNode node02) {

//The closest common ancestor is the root node
if (root == null || root == node01 || root == node02) {
return root;
}

TreeNode left = lowestCommoAncestor(root.left, node01, node02);
TreeNode right = lowestCommoAncestor(root.right, node01, node02);

if (left != null && right != null) {//If left and right are not empty, both sides can find node01 and node02, then the public node can only root
return root;
}

//If only one is empty, then that common ancestor is this node.
return left != null ? left : right;
}
```

# Constructing Binary Trees from Median and Priority Sequences

In fact, this data structure has been exposed to related problems, that is, to find the root node from the sequence of sequential traversal, and then this root node is the left subtree of the node to the left of the sequence, and the nodes to the right of the sequence are all the right subtrees of the node.

```public TreeNode buildTree(int[] preOrder,int[] inOrder){
if(preOrder == null || inOrder == null){
return null;
}
HashMap<Integer,Integer> map = new HashMap<>();
for(int i=0;i<inOrder.length;i++){
map.put(inOrder[i],i);
}
return buildTree(preOrder,0,preOrder.length-1,inOrder,0,inOrder.length-1,map);
}

/**
*  Construct a binary tree from an array traversed in middle and first order
* @param preOrder Priority Sequence Array
* @param pStart	Starting position of the sequence
* @param pEnd		End position of sequence
* @param inOrder	Median sequence array
* @param iStart	The starting position of an intermediate sequence
* @param iEnd		End position of intermediate sequence
* @param map		map of ordered sequence elements and index locations, just for ease of search
* @return
*/
public TreeNode buildTree(int[] preOrder,int pStart,int pEnd,
int[] inOrder,int iStart,int iEnd,
HashMap<Integer,Integer> map){
if(pStart>pEnd || iStart>iEnd){
return null;
}

int index = map.get(preOrder[pStart]);//Locate the root node in the middle traversal