代码如下
import java.util.*;
class TreeNode {
int val;
TreeNode left;
TreeNode right;
public TreeNode(int val) {
this.val = val;
}
}
public class Main {
static Map<Integer, TreeNode> cache = new HashMap<>();
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while(scanner.hasNext()) {
int nodeNum = scanner.nextInt();
int rootNo = scanner.nextInt();
int n = nodeNum;
int[][] info = new int[nodeNum][3];
int i = 0;
while(n > 0) {
info[i][0] = scanner.nextInt();
info[i][1] = scanner.nextInt();
info[i][2] = scanner.nextInt();
i++;
n--;
}
TreeNode root = constructTree(rootNo, info);
print(root);
zigzagPrint(root);
}
}
private static void print(TreeNode root) {
if (root == null) {
return;
}
System.out.print("Level 1 : ");
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
TreeNode last = root;
TreeNode nLast = null;
int level = 1;
while(!queue.isEmpty()) {
TreeNode head = queue.poll();
System.out.print(head.val + " ");
if (head.left != null) {
queue.offer(head.left);
nLast = head.left;
}
if (head.right != null) {
queue.offer(head.right);
nLast = head.right;
}
if (last == head) {
System.out.println();
level++;
if (!queue.isEmpty()) {
System.out.printf("Level %d : ", level);
}
last = nLast;
}
}
}
private static void zigzagPrint(TreeNode root) {
if (root == null) {
return;
}
Deque<TreeNode> deque = new LinkedList<>();
boolean orientation = true;
int level = 1;
deque.offer(root);
TreeNode last = root;
TreeNode nLast = null;
System.out.print("Level 1 from left to right: ");
while(!deque.isEmpty()) {
TreeNode head = null;
if (orientation) {
head = deque.poll();
} else {
head = deque.pollLast();
}
System.out.print(head.val + " ");
if (orientation) {
if (head.left != null) {
deque.offer(head.left);
if (nLast == null) {
nLast = head.left;
}
}
if (head.right != null) {
deque.offer(head.right);
if (nLast == null) {
nLast = head.right;
}
}
} else {
if (head.right != null) {
deque.offerFirst(head.right);
if (nLast == null) {
nLast = head.right;
}
}
if (head.left != null) {
deque.offerFirst(head.left);
if (nLast == null) {
nLast = head.left;
}
}
}
if (last == head) {
level++;
last = nLast;
System.out.println();
if (!deque.isEmpty()) {
if (orientation) {
System.out.printf("Level %d from right to left: ", level);
} else {
System.out.printf("Level %d from left to right: ", level);
}
orientation = !orientation;
nLast = null;
}
}
}
}
private static TreeNode constructTree(int rootNo,int [][] info) {
for(int i = 0;i < info.length;i++) {
int curNo = info[i][0];
TreeNode curNode = getOrCacheNode(curNo);
int leftNo = info[i][1];
TreeNode leftNode = getOrCacheNode(leftNo);
int rightNo = info[i][2];
TreeNode rightNode = getOrCacheNode(rightNo);
curNode.left = leftNode;
curNode.right = rightNode;
}
return getOrCacheNode(rootNo);
}
private static TreeNode getOrCacheNode(int no) {
if (no == 0) {
return null;
}
TreeNode exist = cache.get(no);
if (exist == null) {
exist = new TreeNode(no);
cache.put(no, exist);
}
return exist;
}
}把输入的数字存入info二维数组,constructTree方法用于构造树并返回树的根。
首先介绍按层打印的方法。
首先做判空处理,如果根空那么直接返回,什么都不打印。
如果根不空,把根入队,打印"Level 1 : ", 注意空格要与示例中相同。同时初始化层数level为1,并定义两个指针,last指向当前层最后一个元素,初始化是树根,nLast指向下一层的最后一个元素,因为现在暂且不知道,所以指向空即可。
当队列非空时循环处理,把队首元素拉出记为head,打印head的值,如果head左孩子不空,把head左孩子入队,nLast指向head左孩子,如果head右孩子不空,把head右孩子入队,nLast执行head右孩子。判断取出的元素是否已经是当前行最后一个,如果是,那么把层级数level加1,打印换行,之后再打印"Level 下一行号",并把当前行最后一个元素指针last指向nLast,nLast指向null或者保持不变均可。这里有一个小坑,如果已经扫到当前行最后一个元素且队列已经空了,那么是不应该再进入下一行并打印Level的,所以打印前要先判断队列非空。
接下来介绍zigzag打印的方法。
有了顺序打印的基础,zigzag只需要把队列变为双端队列,定义一个orientation的boolean类型变量表示当前行是从左到右还是从右到左,之后根据这个左右顺序不同来操作nLast指针移动和入队方式即可。
定义orientation为true表示当前行为从左向右。先做root判空,如果非空那么尾插(尾部插入,offer()或者offerLast())入队。首先直接打印"Level 1 from left to right: ",如果队列非空执行循环,如果检测到当前行方向是从左到右,那么就头弹(头部弹出,poll()或者pollFirst())记为head,否则尾弹(尾部弹出,pollLast())同样记为head,打印head对应的值。如果从左到右,那么就先取左孩子,再取右孩子;如果从右到左,就先取右孩子,再取左孩子。再从左到右取的过程中,均采用尾插。且只有nLast非空时才做赋值。如果是从右到左的过程,那么均采用头插法,nLast指针同样只有空时才做赋值。检测到当前节点是当前层的左后一个时,根据方向分别打印不同的串,把层级加一并改变方向,注意nLast一定要置空,否则在循环里就不动了。

京公网安备 11010502036488号