package DataStrcuture;
import java.util.*;
/**
* @Author: JackYe
* @CreateDate: 2019/6/3 15:37
* @Description: java类作用描述
* @UpdateUser: 更新者
* @UpdateDate: 2019/6/3 15:37
* @UpdateRemark: 更新说明
* @Version: 1.0
*/
class TreeNode {
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode(int val) {
this.val = val;
this.left = null;
this.right = null;
}
}
public class BinaryTree {
public TreeNode root;
public void insert(int val) {
TreeNode node = new TreeNode(val);
if (root == null) {
root = node;
} else {
TreeNode newHead = root;
TreeNode parent;
while (true) {
parent = newHead;
if (node.val < newHead.val) {
newHead = newHead.left;
if (newHead == null) {
parent.left = node;
return;
}
} else {
newHead = newHead.right;
if (newHead == null) {
parent.right = node;
return;
}
}
}
}
}
public void buildTree(int[] data) {
for (int i = 0; i < data.length; i++) {
insert(data[i]);
}
}
//前序遍历 中左右 (深度遍历)
public void PreOrder(TreeNode root) {
if (root == null) {
return;
}
System.out.print(root.val + " ");
PreOrder(root.left);
PreOrder(root.right);
}
//前序遍历(非递归) 中左右 (深度遍历)
public void PreOrder2(TreeNode root, int N) {
if (root == null) {
return;
}
TreeNode[] tree = new TreeNode[N];
TreeNode newHead = root;
int index = 0;
while (newHead != null || index > 0) {
while (newHead != null) {
System.out.print(newHead.val + " ");
tree[index++] = newHead;
newHead = newHead.left;
}
newHead = tree[--index];
newHead = newHead.right;
}
}
//中序遍历 左中右
public void inOrder(TreeNode root) {
if (root == null) {
return;
}
inOrder(root.left);
System.out.print(root.val + " ");
inOrder(root.right);
}
/*中序遍历 非递归算法*/
public void inOrder2(TreeNode root, int N) {
if (root == null) {
return;
}
TreeNode[] tree = new TreeNode[N];
TreeNode newHead = root;
int index = 0;
while (newHead != null || index > 0) {
while (newHead != null) {
tree[index++] = newHead;
newHead = newHead.left;
}
newHead = tree[--index];
System.out.print(newHead.val + " ");
newHead = newHead.right;
}
}
//后续遍历 左右中
public void postOrder(TreeNode root) {
if (root == null) {
return;
}
postOrder(root.left);
postOrder(root.right);
System.out.print(root.val + " ");
}
/*难度较大 后续遍历 非递归*/
public void postOrder2(TreeNode root, int N) {
if (root == null) {
return;
}
TreeNode[] tree = new TreeNode[N];
TreeNode newHead = root;
int index = 0;
TreeNode lastNode = null;
while (newHead != null || index > 0) {
while (newHead != null) {
tree[index++] = newHead;
newHead = newHead.left;
}
newHead = tree[index - 1];
if (newHead.right == null || newHead.right == lastNode) {
System.out.print(newHead.val + " ");
lastNode = newHead;
index--;
newHead = null;
} else {
newHead = newHead.right;
}
}
}
/*后续遍历 非递归*/
public void postOrder2(TreeNode root) {
Stack stack1 = new Stack();
Stack stack2 = new Stack();
stack1.push(root);
while (!stack1.isEmpty()) {
root = stack1.pop();
stack2.push(root);
if (root.left != null) {
stack1.push(root.left);
}
if (root.right != null) {
stack1.push(root.right);
}
}
while (!stack2.isEmpty()) {
System.out.print(stack2.pop().val + " ");
}
}
//层序遍历 从左至右 (广度遍历)
public ArrayList> levelOrder(TreeNode root) {
ArrayList> result = new ArrayList<>();
if (root == null) {
return result;
}
Queue queue01 = new LinkedList<>();
Queue queue02 = new LinkedList<>();
TreeNode node;
ArrayList data;
queue01.offer(root);
while (!queue01.isEmpty() || !queue02.isEmpty()) {
if (!queue01.isEmpty()) {
data = new ArrayList<>();
while (!queue01.isEmpty()) {
node = queue01.poll();
data.add(node.val);
if (node.left != null) {
queue02.offer(node.left);
}
if (node.right != null) {
queue02.offer(node.right);
}
}
result.add(data);
}
if (!queue02.isEmpty()) {
data = new ArrayList<>();
while (!queue02.isEmpty()) {
node = queue02.poll();
data.add(node.val);
if (node.left != null) {
queue01.offer(node.left);
}
if (node.right != null) {
queue01.offer(node.right);
}
}
result.add(data);
}
}
return result;
}
//如果已知先序遍历和中序遍历,如何求后续遍历
public TreeNode reconstructTree(int[] preOrder, int[] inOrder) {
int pi = 0;
int pj = preOrder.length - 1;
int ni = 0;
int nj = inOrder.length;
HashMap hashMap = new HashMap<>();
for (int i = 0; i < inOrder.length; i++) {
hashMap.put(inOrder[i], i);
}
return reconstructCore(preOrder, pi, pj, inOrder, ni, nj, hashMap);
}
public TreeNode reconstructCore(int[] preOrder, int pi, int pj, int[] inOrder, int ni, int nj, HashMap map) {
if (pi > pj) {
return null;
}
TreeNode root = new TreeNode(preOrder[pi]);
int index = (int) map.get(preOrder[pi]);
root.left = reconstructCore(preOrder, pi + 1, pi + index - ni, inOrder, ni, index - 1, map);
root.right = reconstructCore(preOrder, pi + index - ni + 1, pj, inOrder, index + 1, nj, map);
return root;
}
//判断是否是二叉树的子结构
public boolean isSubTree(TreeNode root, TreeNode subRoot) {
boolean flag = false;
if (subRoot == null || root == null) {
return false;
}
if (root.val == subRoot.val) {
flag = isSubTreeCore(root, subRoot);
} else {
flag = isSubTree(root.left, subRoot);
if (flag == false) {
flag = isSubTree(root.right, subRoot);
}
}
return flag;
}
public boolean isSubTreeCore(TreeNode root, TreeNode subRoot) {
if (root == null && subRoot != null) {
return false;
}
if (root == null && subRoot == null) {
return true;
}
if (root != null && subRoot == null) {
return true;
}
if (root.val == subRoot.val) {
return isSubTreeCore(root.left, subRoot.left) && isSubTreeCore(root.right, subRoot.right);
} else {
return false;
}
}
//给出根节点和一个整数,返回路径,路径上节点的和为target
int count = 0;
ArrayList arrayList = new ArrayList<>();
ArrayList> finalList = new ArrayList<>();
public ArrayList> FindPath(TreeNode root, int target) {
if (root == null || target <= 0) {
return finalList;
}
FindPathCore(root, target);
Collections.sort(finalList, new Comparator>() {
@Override
public int compare(ArrayList o1, ArrayList o2) {
return o1.size() - o2.size();
}
});
return finalList;
}
private void FindPathCore(TreeNode root, int target) {
if (root == null) {
return;
}
count += root.val;
arrayList.add(root.val);
FindPathCore(root.left, target);
FindPathCore(root.right, target);
if (count == target) {
finalList.add(new ArrayList<>(arrayList));
}
count = count - root.val;
arrayList.remove(arrayList.size() - 1);
}
//给出一颗树求取树的深度(即深度的值为根节点到叶子节点最长的路径)
public int getDepth(TreeNode root) {
Queue queue = new LinkedList<>();
if (root != null) {
queue.offer(root);
}
int lastCount = 1;
int count = 0;
int deepth = 0;
while (!queue.isEmpty()) {
TreeNode newHead = queue.poll();
count++;
if (newHead.left != null) {
queue.offer(newHead.left);
}
if (newHead.right != null) {
queue.offer(newHead.right);
}
if (count == lastCount) {
deepth++;
count = 0;
lastCount = queue.size();
}
}
return deepth;
}
//判断树的结构是否为对称的二叉树
public boolean isSymmetrical(TreeNode root) {
if (root == null) {
return false;
}
return isSymmetrical(root.left, root.right);
}
private boolean isSymmetrical(TreeNode right, TreeNode left) {
if (right == null && left == null) {
return true;
}
if (right != null && left != null && right.val == left.val) {
return isSymmetrical(left.left, right.right) && isSymmetrical(left.right.right.right);
}
return false;
}
//判断该树是否为平衡二叉树
public boolean isBalanced(TreeNode root) {
if (root == null) {
return false;
}
int gap = 0;
int leftDepth = height(root.left);
int rightDepth = height(root.right);
if (Math.abs(leftDepth - rightDepth) > 1) {
return false;
} else {
return isBalanced(root.left) && isBalanced(root.right);
}
}
private int height(TreeNode root) {
if (root == null) {
return 0;
}
int leftDepth = height(root.left);
int rightDepth = height(root.right);
if (Math.abs(leftDepth - rightDepth) > 1) {
return -1;
}
return Math.max(leftDepth, rightDepth) + 1;
}
public static void main(String[] args) {
BinaryTree binaryTree = new BinaryTree();
int[] data = {2, 8, 7, 4, 9, 3, 1, 6, 7, 5};
int pre[] = new int[]{1, 2, 4, 7, 3, 5, 6, 8};
int in[] = new int[]{4, 7, 2, 1, 5, 3, 8, 6};
binaryTree.buildTree(data);
System.out.println("二叉树的前序遍历");
binaryTree.PreOrder(binaryTree.root);
System.out.println("\n二叉树的前序遍历(非递归)");
binaryTree.PreOrder2(binaryTree.root, data.length);
System.out.println("\n二叉树的中序遍历");
binaryTree.inOrder(binaryTree.root);
System.out.println("\n二叉树的中序遍历(非递归)");
binaryTree.inOrder2(binaryTree.root, data.length);
System.out.println("\n二叉树的后序遍历");
binaryTree.postOrder(binaryTree.root);
System.out.println("\n二叉树的后序遍历(非递归1)");
binaryTree.postOrder2(binaryTree.root);
System.out.println("\n二叉树的后序遍历(非递归2)");
binaryTree.postOrder2(binaryTree.root, data.length);
System.out.println("\n二叉树的层序遍历");
binaryTree.levelOrder(binaryTree.root);
System.out.println("\n二叉树重建");
TreeNode root = binaryTree.reconstructTree(pre, in);
System.out.println("是否是树的子结构");
TreeNode a = new TreeNode(10);
TreeNode b = new TreeNode(5);
TreeNode c = new TreeNode(12);
TreeNode d = new TreeNode(4);
TreeNode e = new TreeNode(7);
a.left = b;
a.right = c;
b.left = d;
b.right = e;
System.out.println(binaryTree.isSubTree(b, a));
System.out.println("二叉树中的路径满足22");
System.out.println(binaryTree.FindPath(a, 22));
System.out.println("二叉树的深度" + binaryTree.getDepth(a));
System.out.println("二叉树是否对称" + binaryTree.isSymmetrical(a));
}
}