### 二叉樹的各種遍歷

```import java.util.ArrayList;
import java.util.Stack;

/**
* 二叉樹的遍歷：
* 遞歸和非遞歸先序、中序、后序遍歷
* 層次遍歷：不分層層次遍歷、分層層次遍歷、之字形遍歷
*/

class TreeNode {
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode( int val){
this.val = val;
}
}

public class TreeNodeTraversal {

//先序遍歷的遞歸實現
public static void preOrderRecur(TreeNode root){
if (root == null){
return;
}
System.out.print(root.val + " ");
preOrderRecur(root.left);
preOrderRecur(root.right);
}

//先序遍歷的非遞歸實現
public static void preOrderUnRecur(TreeNode root){
if (root != null){
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
while (!stack.empty()){
root = stack.pop();
System.out.print(root.val + " ");
if (root.right != null){
stack.push(root.right);
}
if (root.left != null){
stack.push(root.left);
}
}
}
}

//中序遍歷的遞歸實現
public static void inOrderRecur(TreeNode root){
if (root == null){
return;
}
inOrderRecur(root.left);
System.out.print(root.val + " ");
inOrderRecur(root.right);
}

//中序遍歷的非遞歸實現
public static void inOrderUnRecur(TreeNode root){
if(root != null){
Stack<TreeNode> stack = new Stack<>();
while (!stack.empty() || root != null){
if (root != null){
stack.push(root);
root = root.left;
}else {
root = stack.pop();
System.out.print(root.val + " ");
root = root.right;
}
}
}
}

//后序遍歷的遞歸實現
public static void postOrderRecur(TreeNode root){
if (root == null){
return;
}
inOrderRecur(root.left);
inOrderRecur(root.right);
System.out.print(root.val + " ");
}

//后序遍歷的非遞歸實現
public static void postOrderUnRecur(TreeNode root){
if (root != null){
Stack<TreeNode> stack1 = new Stack<>();
Stack<TreeNode> stack2 = new Stack<>();
stack1.push(root);
while (!stack1.empty()){
root = stack1.pop();
stack2.push(root);
if (root.left != null){
stack1.push(root.left);
}
if (root.right != null){
stack1.push(root.right);
}
}
while (!stack2.empty()){
System.out.print(stack2.pop().val + " ");
}
}
}

//不分層的層次遍歷
public ArrayList<Integer> PrintFromTopToBottom(TreeNode root) {
ArrayList<Integer> result = new ArrayList<>();//保存結果
if (root == null){
return result;
}

//用ArrayList來模擬隊列
ArrayList<TreeNode> queue = new ArrayList<>();
while (!queue.isEmpty()) {
TreeNode temp = queue.remove(0);
if (temp.left != null) {
}
if (temp.right != null) {
}
}
return result;
}

//分層層次遍歷
public ArrayList<ArrayList<Integer> > PrintFC(TreeNode root) {
ArrayList<ArrayList<Integer> > result = new ArrayList<>();//保存結果
if (root == null){
return result;
}
int count = 0;//保存當前行的節點個數
ArrayList<Integer> list = null;
queue.offer(root);
while (!queue.isEmpty()){
list = new ArrayList<>();
count = queue.size();//當前行的節點數
while (count-- > 0){
TreeNode temp = queue.poll();
if (temp.left != null){
queue.offer(temp.left);
}
if (temp.right != null){
queue.offer(temp.right);
}
}
}
return result;
}

//分層之字形遍歷
public static ArrayList<ArrayList<Integer> > PrintZ(TreeNode pRoot) {
ArrayList<ArrayList<Integer>> result = new ArrayList<>();//保存最終結果
if(pRoot==null){
return result;
}
Stack<TreeNode>[] stacks = new Stack[2];//保存中間節點
stacks[0] = new Stack<>();
stacks[1] = new Stack<>();
int flag = 0;
stacks[0].push(pRoot);
ArrayList<Integer> list = new ArrayList<>();
while(!stacks[flag].empty()){//待輸出元素不為空
TreeNode temp = stacks[flag].pop();
//根據當前的打印方向，判斷下一行的入棧順序
if(flag==0){
if(temp.left!=null){
stacks[1-flag].push(temp.left);
}
if(temp.right!=null){
stacks[1-flag].push(temp.right);
}
}else{
if(temp.right!=null){
stacks[1-flag].push(temp.right);
}
if(temp.left!=null){
stacks[1-flag].push(temp.left);
}
}
//當前行的元素打印完畢
if(stacks[flag].empty()){
list = new ArrayList<>();
flag = 1-flag;
}
}
return result;
}

public static void main(String[] args) {
TreeNode node1 = new TreeNode(8);
TreeNode node2 = new TreeNode(10);
TreeNode node3 = new TreeNode(6);
TreeNode node4 = new TreeNode(5);
TreeNode node5 = new TreeNode(7);
TreeNode node6 = new TreeNode(9);
TreeNode node7 = new TreeNode(11);
node1.left = node2;
node1.right = node3;
node2.left = node4;
node2.right = node5;
node3.left = node6;
node3.right = node7;

System.out.println(PrintZ(node1));
}
}```