package tree;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) {
val = x;
}
}
public class Solution {
public static void main(String[] args) {
Solution solution = new Solution();
int[][] nums = {{1, 2, 3, 4, 5}, {4, 5, 3, 2, 1}};
TreeNode root = solution.buildTree(new int[]{1, 2, 3, 4, 5, 6, 7});
solution.prePrint(root);
System.out.println();
solution.preIterator(root);
System.out.println();
solution.inPrint(root);
System.out.println();
solution.inIterator(root);
System.out.println();
solution.postPrintTree(root);
System.out.println();
solution.postIterator(root);
System.out.println();
}
public ArrayList<Integer> PrintFromTopToBottom(TreeNode root) {
ArrayList<Integer> al = new ArrayList<>();
if (root == null) return al;
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()) {
Queue<TreeNode> temp = new LinkedList<>();
while (!queue.isEmpty()) {
TreeNode cur = queue.poll();
al.add(cur.val);
if (cur.left != null) temp.offer(cur.left);
if (cur.right != null) temp.offer(cur.right);
}
queue = temp;
}
return al;
}
public boolean HasSubtree(TreeNode root1, TreeNode root2) {
if (root1 == null || root2 == null) return false;
if (root1.val == root2.val) {
if (isSubTree(root1, root2)) return true;
}
return HasSubtree(root1.left, root2) || HasSubtree(root1.right, root2);
}
private boolean isSubTree(TreeNode root1, TreeNode root2) {
if (root2 == null) return true;
else if (root1 == null) return false;
if (root1.val != root2.val) return false;
return isSubTree(root1.left, root2.left) && isSubTree(root1.right, root2.right);
}
public void Mirror(TreeNode root) {
if (root == null) return;
TreeNode temp = root.left;
root.left = root.right;
root.right = temp;
Mirror(root.left);
Mirror(root.right);
}
public TreeNode buildTree(int[] nums) {
int index = 0;
TreeNode root = new TreeNode(nums[index++]);
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
pointA:
while (index < nums.length) {
Queue<TreeNode> temp = new LinkedList<>();
while (!queue.isEmpty()) {
TreeNode cur = queue.poll();
if (index < nums.length) {
cur.left = new TreeNode(nums[index++]);
temp.offer(cur.left);
}
if (index < nums.length) {
cur.right = new TreeNode(nums[index++]);
temp.offer(cur.right);
} else {
break pointA;
}
}
queue = temp;
}
return root;
}
//先序遍历
public void prePrint(TreeNode root) {
if (root == null) return;
System.out.print(root.val + ",");
if (root.left != null) prePrint(root.left);
if (root.right != null) prePrint(root.right);
}
public void preIterator(TreeNode root) {
if (root == null)
return;
Stack<TreeNode> stack = new Stack<>();
TreeNode p = root;
while (!stack.empty() || p != null) {
while (p != null) {
System.out.print(p.val + "-->");//若节点不为空先访问再压栈(每个节点都可以看成根节点)
stack.push(p);
p = p.left;//将当前节点置为p的左孩子,若不为空继续访问并压栈
}
//当p为空时,说明根节点和左孩子打印遍历完毕了,接下来出栈遍历右孩子
if (!stack.empty()) {
p = stack.pop();
p = p.right;
}
}
}
//中序遍历
public void inPrint(TreeNode root){
if (root == null) return;
if (root.left != null) inPrint(root.left);
System.out.print(root.val + ",");
if (root.right != null) inPrint(root.right);
}
public void inIterator(TreeNode root) {
if (root == null)
return;
Stack<TreeNode> stack = new Stack<>();
TreeNode p = root;//让p指向根节点
while (!stack.empty() || p != null) {
//一直遍历到左子树最下边,边遍历边保存根节点到栈中(每个节点都可以看成一个新的子树的根节点)
while (p != null) {
stack.push(p);//若节点的左孩子不为空,将左孩子压栈,因为需要借助遍历过的节点进入右子树
p = p.left;
}
//当p为空时,说明已经到达左子树最下边,这时需要出栈了
if (!stack.isEmpty()) {
p = stack.pop();
System.out.print(p.val + "-->");//访问根节点
p = p.right;//进入右子树,此时p是右子树的根节点(开始新一轮的遍历)
}
}
}
//后序遍历
public void postPrintTree(TreeNode root) {
if (root == null) return;
if (root.left != null) postPrintTree(root.left);
if (root.right != null) postPrintTree(root.right);
System.out.print(root.val + ",");
}
public void postIterator(TreeNode root) {
if (root == null)
return;
Stack<TreeNode> stack = new Stack<TreeNode>();
TreeNode pre = null;//当前节点的之前访问的节点
TreeNode current;
stack.push(root);
while (!stack.empty()) {
current = stack.peek();
if ((current.left == null && current.right == null) || //当前节点是叶子节点,可以直接访问该节点
(pre != null && (pre == current.left || pre == current.right)))
//当前一个节点不为空并且是当前节点的左孩子或者右孩子,当是左孩子时说明当前节点右孩子为空,当是右孩子时,说明左右孩子都访问过了,且都不为空
{
System.out.print(current.val + "-->");
stack.pop();
pre = current;
} else //当前节点为栈顶元素 如果当前节点不是叶子节点,在当前节点之前访问的那个节点不是当前节点的孩子,则进行压栈
{
if (current.right != null) //先压栈右节点再压栈左节点 这样出栈时是先左后右
{
stack.push(current.right);
}
if (current.left != null) {
stack.push(current.left);
}
}
}
}
public TreeNode reConstructBinaryTree(int[] pre, int[] in) {
return reConstructBinaryTree(pre, in, 0, in.length - 1);
}
public TreeNode reConstructBinaryTree(int[] pre, int[] in, int begin, int end) {
TreeNode node;
if (begin > end) return null;
else if (begin == end) return new TreeNode(in[begin]);
int index = -1;
BEGIN:
for (int i : pre) {
for (int j = begin; j <= end; j++) {
if (in[j] == i) {
index = j;
break BEGIN;
}
}
}
if (index == -1) return null;
node = new TreeNode(in[index]);
node.left = reConstructBinaryTree(pre, in, begin, index - 1);
node.right = reConstructBinaryTree(pre, in, index + 1, end);
return node;
}
public void levelOrder(TreeNode root) {
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()) {
Queue<TreeNode> temp = new LinkedList<>();
while (!queue.isEmpty()) {
TreeNode cur = queue.poll();
System.out.print(cur.val + ",");
if (cur.left != null) temp.offer(cur.left);
if (cur.right != null) temp.offer(cur.right);
}
queue = temp;
}
System.out.println();
}
}
树的遍历
最新推荐文章于 2023-03-14 17:04:32 发布