# 征战二叉树-第二站

### 1. 前序遍历（迭代）

``````/**
* 前序遍历的迭代算法
* 要点：使用栈来进行装载节点
* @param root
* @return
*/
public List<T> preOrderWithIteration(TreeNode<T> root){

if (root == null) {
return null;
}

List<T> list = new ArrayList<T>();
Stack<TreeNode<T>> stack = new Stack<TreeNode<T>>();
stack.push(root);
while(!stack.isEmpty()){
TreeNode<T> currentNode = stack.pop();

if (currentNode.right != null) {
stack.push(currentNode.right);
}

if (currentNode.left != null) {
stack.push(currentNode.left);
}
}
return list;
}
``````

### 2. 中序遍历（迭代）

``````/**
* 中序遍历的迭代算法
* @param root
* @return
*/
public List<T> inOrderWithIteration(TreeNode<T> root){

if(root == null){
return null;
}
List<T> list = new ArrayList<T>();
Stack<TreeNode<T>> stack = new Stack<TreeNode<T>>();

while(root != null || !stack.isEmpty()){

while(root != null){
stack.push(root);
root = root.left;
}
if (!stack.isEmpty()) {

TreeNode<T> currentNode = stack.pop();
root = currentNode.right;
}
}
return list;
}
``````

### 3. 后序遍历（迭代）

``````/**
* 后序遍历，非递归算法
* @param root
* @return
*/
public List<T> postOrderWithIteration(TreeNode<T> root){

if(root == null){
return null;
}

List<T> list = new ArrayList<T>();
Stack<TreeNode<T>> stack = new Stack<TreeNode<T>>();
TreeNode<T> curNode;
TreeNode<T> preNode = null;
stack.push(root);

while(!stack.isEmpty()){

curNode = stack.peek();
if ((curNode.left == null && curNode.right == null) || (preNode != null
&& (preNode == curNode.left || preNode == curNode.right))) {

preNode = curNode;
stack.pop();
}
else {
if (curNode.right != null) {
stack.push(curNode.right);
}
if(curNode.left != null){
stack.push(curNode.left);
}
}
}
return list;
}

``````

### 4. 判断两个二叉树是否镜像

``````/**
* 判断两个二叉树是否镜像
* @param root1
* @param root2
* @return
*/
public boolean isMirror(TreeNode<T> root1,TreeNode<T> root2){

if (root1 == null && root2 == null) {
return true;
}
else if (root1 != null || root2 != null) {
return false;
}
else if(root1.getData() != root2.getData()){
return false;
}

return isMirror(root1.left, root2.right) && isMirror(root1.right, root2.left);

}

``````

### 5. 求镜像二叉树，或者是翻转二叉树

``````/**
* 求镜像二叉树，或者是翻转二叉树
* @param root
* @return
*/
public TreeNode<T> mirrorTreeNode(TreeNode<T> root){
if (root == null) {
return null;
}
TreeNode<T> left = mirrorTreeNode(root.left);
TreeNode<T> right = mirrorTreeNode(root.right);

root.left = right;
root.right = left;

return root;
}
``````

### 6. 寻找连个节点的最小祖先节点

``````/**
* 寻找连个节点的最小祖先节点
* @param root
* @param nodeA
* @param nodeB
* @return
*/
public TreeNode<T> getLowestAncestor(TreeNode<T> root,TreeNode<T> nodeA,TreeNode<T> nodeB){
if (findNode(root.left,nodeA)) {
if (findNode(root.right, nodeB)) {
return root;
}
else {
return getLowestAncestor(root.left, nodeA, nodeB);
}

}
else {
if (findNode(root.left, nodeB)) {
return root;
}
else {
return getLowestAncestor(root.right, nodeA, nodeB);
}
}

}

private boolean findNode(TreeNode<T> root, TreeNode<T> node) {

if (root == null || node == null) {
return false;
}
if (root == node) {
return true;
}
boolean isFound = findNode(root.left, node);
if (!isFound) {
isFound = findNode(root.right, node);
}
return isFound;
}
``````

### 7. 获取二叉树两个节点之间最大距离

1.左子树的最大深度+右子树的最大深度为二叉树的最长距离

2.左子树中的最长距离即为二叉树的最长距离

3.右子树种的最长距离即为二叉树的最长距离

``````    /**
* 获取二叉树两个节点之间的最大距离
* @param root
* @return
*/
public int getMaxDistance(TreeNode<T> root){

return getMaxDistanceHolder(root).maxDistance;
}

private DistanceHolder getMaxDistanceHolder(TreeNode<T> root){

if (root == null) {
return new DistanceHolder(-1,0);
}
DistanceHolder leftHolder = getMaxDistanceHolder(root.left);
DistanceHolder rightHolder = getMaxDistanceHolder(root.right);

DistanceHolder result = new DistanceHolder();
result.maxDepth = Math.max(leftHolder.maxDepth, rightHolder.maxDepth) + 1;
result.maxDistance = Math.max(leftHolder.maxDepth + rightHolder.maxDepth,
Math.max(leftHolder.maxDistance, rightHolder.maxDistance));

return result;
}

/**
* 用来持有距离的最大深度的类
*
*/
private static class DistanceHolder{

public int maxDistance;
public int maxDepth;

public DistanceHolder(){}
public DistanceHolder(int maxDistance, int maxDepth) {
this.maxDistance = maxDistance;
this.maxDepth = maxDepth;
}

}
``````

### 8. 输入一个二叉树和一个整数，打印出二叉树中节点值的和等于输入整数所有的路径

``````/**
*
* @param root
* @param k
* @return
*/
public List<Integer> findAllPath(TreeNode<Integer> root,int k){
List<Integer> list = new ArrayList<Integer>();
if (root == null) {
return list;
}
int sum = 0;
Stack<TreeNode<Integer>> stack = new Stack<TreeNode<Integer>>();
findAllPath(root, k,list,stack,sum);
return list;
}

private void findAllPath(TreeNode<Integer> root, int k, List<Integer> list,
Stack<TreeNode<Integer>> stack, int sum) {

sum += root.getData();
stack.push(root);
if (root.left == null && root.right == null && sum == k) {

for(TreeNode<Integer> node : stack){
}
}

if (root.left != null) {
findAllPath(root.left, k, list, stack, sum);
}
if (root.right != null) {
findAllPath(root.right, k, list, stack, sum);
}

stack.pop();//这里每次要弹出栈，因为到这里已经不满足条件了，需要将本次检索的元素清除掉
}

``````

### 推荐阅读更多精彩内容

• 树的概述 树是一种非常常用的数据结构，树与前面介绍的线性表，栈，队列等线性结构不同，树是一种非线性结构 1.树的定...
Jack921阅读 3,060评论 1 31
• 数据结构和算法--二叉树的实现 几种二叉树 1、二叉树 和普通的树相比，二叉树有如下特点： 每个结点最多只有两棵子...
sunhaiyu阅读 3,158评论 0 13
• 1 序 2016年6月25日夜，帝都，天下着大雨，拖着行李箱和同学在校门口照了最后一张合照，搬离寝室打车去了提前租...
StarryThrone阅读 2,706评论 0 9
• 基于树实现的数据结构，具有两个核心特征： 逻辑结构：数据元素之间具有层次关系； 数据运算：操作方法具有Log级的平...
yhthu阅读 1,648评论 1 5
• 去年二叉树算法的事情闹的沸沸扬扬，起因是Homebrew 的作者 @Max Howell 在 twitter 上发...
Masazumi柒阅读 562评论 0 8