手动创建一棵二叉树,然后利用前序、中序、后序、层序进行遍历
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Stack;
public class BinaryTree {
private static class Node{
int val;
Node left;
Node right;
Node(int newVal){
val = newVal;
}
}
//前序遍历(递归)
public static void preOrder(Node node){
if(node == null){
return;
}
System.out.print(node.val + " ");
preOrder(node.left);
preOrder(node.right);
}
//前序遍历(非递归)
//主要的思路:利用栈保存未打印的结点,然后逐个出栈处理,在此过程中更新栈
public static void preOrderUnRec(Node node){
Stack<Node> stack = new Stack<>();
stack.push(node);
Node temp;
while(!stack.isEmpty()){
temp = stack.pop();
if(temp != null){ // root == null时,只会空转一个循环,因此无需判断
System.out.print(temp.val + " ");
stack.push(temp.right);//注意:这里的入栈顺序先是right后left
stack.push(temp.left);// 以保证从栈中取出时为先left后right
}
}
}
//中序遍历
public static void inOrder(Node node){
if(node == null){
return;
}
inOrder(node.left);
System.out.print(node.val + " ");
inOrder(node.right);
}
//中序遍历(非递归)
public static void inOrderUnRec(Node node){
Stack<Node> stack = new Stack<>();
Node cur = node;
while(cur != null || !stack.isEmpty()){ //当root==null时,不会进入循环,因此无需判断
while(cur != null){ //当前结点开始,从上到下将最左边的那一列结点入栈
stack.push(cur);
cur = cur.left;
}
cur = stack.pop(); //取出栈顶的结点(该节点左节点为null,因此现在改打印它)
System.out.print(cur.val + " ");
cur = cur.right; //定位到已打印的结点的右子结点
}
}
//后序遍历
public static void postOrder(Node node){
if(node == null){
return;
}
postOrder(node.left);
postOrder(node.right);
System.out.print(node.val + " ");
}
//后序遍历(非递归)
//主要思路:利用栈保存未打印的结点,然后逐个出栈,进行判断,并根据需要更新栈
// 因为处理完左右子树后,再处理根(回溯),所以需要一个记录上一个被打印的结点的引用
public static void postOrderUnRec(Node node){
if(node == null){
return;
}
Stack<Node> stack = new Stack<>();
stack.push(node);
//cur:当前结点 pre:上一个被打印的结点
Node cur, pre = null;
while(!stack.isEmpty()){
//查看(你是取出)栈顶的结点
cur = stack.peek();
//如果当前结点没有孩子结点(叶子结点)
//或者孩子结点都已经被打印过(这里不可能出现有两个子结点却只打印了其中一个的情况)
//说明该打印当前结点
if((cur.left == null && cur.right == null) || (pre != null && (pre == cur.left || pre == cur.right))){
System.out.print(cur.val + " "); //打印当前结点
stack.pop(); //被打印的结点(当前结点)出栈
pre = cur; //更新pre的值
}else{
if(cur.right != null){ //若未轮到当前结点,将当前结点的右子结点、左子节点入栈
stack.push(cur.right);//注意:这里的入栈顺序是先right后left
}
if(cur.left != null){ //以保证从栈中取出时先left后right
stack.push(cur.left);
}
}
}
}
//层序遍历
public static void levelTraversal(Node root){
Queue<Node> q = new LinkedList<>();
q.add(root);
while(!q.isEmpty()){
Node temp = q.poll();
if(temp != null){
System.out.print(temp.val + " ");
q.add(temp.left);
q.add(temp.right);
}
}
}
public static void main(String[] args) {
Node node1 = new Node(1);
Node node2 = new Node(2);
Node node3 = new Node(3);
Node node4 = new Node(4);
Node node5 = new Node(5);
Node node6 = new Node(6);
node1.left = node2;
node1.right = node3;
node2.left = node4;
node2.right = node5;
node3.left = node6;
System.out.println("先序遍历:");
preOrder(node1);
System.out.println();
System.out.println("先序遍历(非递归):");
preOrderUnRec(node1);
System.out.println();
System.out.println("中序遍历:");
inOrder(node1);
System.out.println();
System.out.println("中序遍历(非递归):");
inOrderUnRec(node1);
System.out.println();
System.out.println("后序遍历:");
postOrder(node1);
System.out.println();
System.out.println("后序遍历(非递归):");
postOrderUnRec(node1);
System.out.println();
System.out.println("层序遍历:");
levelTraversal(node1);
System.out.println();
}
}
结果:
先序遍历:
1 2 4 5 3 6
先序遍历(非递归):
1 2 4 5 3 6
中序遍历:
4 2 5 1 6 3
中序遍历(非递归):
4 2 5 1 6 3
后序遍历:
4 5 2 6 3 1
后序遍历(非递归):
4 5 2 6 3 1
层序遍历:
1 2 3 4 5 6