import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
import java.util.Stack;
/**
* 定义节点类
* 为了简单就不定义getter/setter方法了
*/
class Node {
public int value;
public Node left;
public Node right;
public Node() {
this(0);
}
public Node(int v) {
this.value = v;
this.left = null;
this.right = null;
}
}
/**
* 对二叉树进行操作的工具类
*/
class PrintBinaryTree {
private PrintBinaryTree(){
throw new RuntimeException("该工具类不应该被实例化");
}
/**
* 层序遍历二叉树(每一行从左到右,整体上从上到下)
* 主要思路:利用队列先进先出的性质保存顺序
* @param root 要遍历的二叉树的根节点
*/
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.value + " ");
q.add(temp.left);
q.add(temp.right);
}
}
}
/**
* 前序遍历二叉树(递归) root->left->right
* @param root 要遍历的二叉树的根节点
*/
public static void preOrderRec(Node root) {
if (root == null) {
return;
}
System.out.print(root.value + " ");
preOrderRec(root.left);
preOrderRec(root.right);
}
/**
* 前序遍历二叉树(非递归) root->left->right
* 主要思路:利用栈保存未打印的节点,然后逐个出栈处理,在此过程中更新栈
* @param root 要遍历的二叉树的根节点
*/
public static void preOrderUnRec(Node root) {
Stack<Node> stack = new Stack<>();
stack.push(root);
Node temp;
while (!stack.empty()) {
temp = stack.pop();
if (temp != null) {
System.out.print(temp.value + " ");
stack.push(temp.right);
stack.push(temp.left);
}
}
}
/**
* 后序遍历二叉树(递归)
* @param root 要遍历的二叉树的根节点
*/
public static void postOrderRec(Node root) {
if (root == null) {
return;
}
postOrderRec(root.left);
postOrderRec(root.right);
System.out.print(root.value + " ");
}
/**
* 后序遍历二叉树(非递归) left->right->root
* 主要思路:利用栈保存未打印的节点,然后逐个出栈,进行判断,并根据需要更新栈
* 因为是处理完左右子树后,再处理根(回溯),所以需要一个记录上一个被打印的节点的引用
* @param root 要遍历的二叉树的根节点
*/
public static void postOrderUnRec(Node root) {
if (root == null) {
return;
}
Stack<Node> stack = new Stack<>();
stack.push(root);
Node cur, pre = null;
while (!stack.empty()) {
cur = stack.peek();
if ((cur.left == null && cur.right == null) ||
(pre != null && (pre == cur.left || pre == cur.right))) {
System.out.print(cur.value + " ");
stack.pop();
pre = cur;
} else {
if (cur.right != null)
stack.push(cur.right);
if (cur.left != null)
stack.push(cur.left);
}
}
}
/**
* 中序遍历二叉树(递归)
* @param root 要遍历的二叉树的根节点
*/
public static void inOrderRec(Node root) {
if (root == null) {
return;
}
inOrderRec(root.left);
System.out.print(root.value + " ");
inOrderRec(root.right);
}
/**
* 中序遍历二叉树(非递归) left->root->right
* 主要思路:模拟递归的过程,将左子树节点不断的压入栈,直到左叶子,然后处理栈顶节点的右子树
* @param root 要遍历的二叉树的根节点
*/
public static void inOrderUnRec(Node root) {
Stack<Node> stack = new Stack<>();
Node cur = root;
while (cur != null || !stack.isEmpty()) {
while (cur != null) {
stack.push(cur);
cur = cur.left;
}
cur = stack.pop();
System.out.print(cur.value + " ");
cur = cur.right;
}
}
/**
* 前序递归构造二叉树 root->left->right
* @param scanner 输入流,用于读取节点值
* @return 构造完成的二叉树的根节点
*/
public static Node createTreeNode(Scanner scanner) {
assert scanner!=null;
Node root = null;
int data = scanner.nextInt();
if (data > 0) {
root = new Node(data);
root.left = createTreeNode(scanner);
root.right = createTreeNode(scanner);
}
return root;
}
}
/**
* 测试类
*/
public class BinaryTree{
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
Node root = PrintBinaryTree.createTreeNode(sc);
sc.close();
System.out.print("层序遍历:");
PrintBinaryTree.levelTraversal(root);
System.out.print("\n中序递归遍历:");
PrintBinaryTree.inOrderRec(root);
System.out.print("\n中序非递归遍历:");
PrintBinaryTree.inOrderUnRec(root);
System.out.print("\n前序递归遍历:");
PrintBinaryTree.preOrderRec(root);
System.out.print("\n前序非递归遍历:");
PrintBinaryTree.preOrderUnRec(root);
System.out.print("\n后序递归遍历:");
PrintBinaryTree.postOrderRec(root);
System.out.print("\n后序非递归遍历:");
PrintBinaryTree.postOrderUnRec(root);
}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)