1、题目描述
【JZ59】请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推。
知识点:栈、树、队列。
难度:☆
2、解题思路
本题考查 BFS (宽度优先搜索)的使用。
对二叉树进行 BFS 的首选就是使用一个队列 Queue ,开始时把根结点入队,然后开始 BFS 算法,每一次都从队列中取出一个结点,每处理完一个结点就把它的左右子结点入队(如果不为空),等把一层的结点都处理完毕的时候,队列里刚好就是完整的下一层的所有结点。
本题的求解思路类似,只是多了一个左右顺序调换,如果把原来的二叉树的每一行左到右顺序都看成正序,那么,题意的要求是偶数层正序,奇数层逆序。
按照队列进行 BFS 搜索的特点,每当处理好一层,队列里刚好是下一层的正序。为了让下一层能够逆序,我们可以利用栈 Stack 的结构。队列每取出一个结点处理完毕,它的左右子结点先不入队,而是入栈(如果左右子结点不为空)。等一层处理完毕,则把 Stack 里面的元素全部倒入到队列 Queue 中,那么此时的队列保存的结点的顺序就是下一层的逆序。
3、解题代码
package pers.klb.jzoffer.hard;
import java.util.*;
/**
* @program: JzOffer2021
* @description: 之字形顺序打印二叉树
* @author: Meumax
* @create: 2020-07-20 10:22
**/
public class ZPrintTree {
public ArrayList<ArrayList<Integer>> Print(TreeNode pRoot) {
ArrayList<ArrayList<Integer>> lists = new ArrayList<ArrayList<Integer>>();
if (pRoot == null) {
return lists;
}
Queue<TreeNode> queue = new LinkedList<>();
Stack<TreeNode> stack = new Stack();
queue.add(pRoot);
boolean direction = true; // 当前层的遍历顺序,true:左到右 false:右到左
while (true) {
int size = queue.size();
if (size == 0) break;
ArrayList<Integer> list = new ArrayList<Integer>();
while (size != 0) {
TreeNode node = queue.poll();
list.add(node.val);
if (direction) {
if (node.left != null) stack.push(node.left);
if (node.right != null) stack.push(node.right);
}else{
if (node.right != null) stack.push(node.right);
if (node.left != null) stack.push(node.left);
}
size--;
}
while (!stack.isEmpty()) queue.add(stack.pop());
lists.add(list);
direction = !direction; // 掉转方向
}
return lists;
}
}
public class TreeNode {
public int val = 0;
public TreeNode left = null;
public TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
4、解题心得
对树的 BFS 搜索优先考虑队列,当一层处理完毕,队列里保存的元素刚好是下一层的结点。有种打枪装子弹的味道。
本文介绍了一种特殊的二叉树遍历方法——之字形打印,通过使用队列和栈结合BFS算法,实现了从左到右及从右至左交替打印二叉树各层节点的功能。
4205

被折叠的 条评论
为什么被折叠?



