【题目描述】请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推。
【解题思路1】
//1.使用两个栈来分别存储奇数层节点和偶数层节点。
//2.注意两个栈的插入顺序是不同的。
//3.对于奇数层来说,也就是从左往右的顺序,先添加左子树,然后添加右子树。对于偶数层,刚好相反,先添加右子树,然后添加左子树。
import java.util.ArrayList;
import java.util.Stack;
public class Solution {
public ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
int level = 1;
//s1存奇数层节点
Stack<TreeNode> s1 = new Stack<TreeNode>();
s1.push(pRoot);
//s2存偶数层节点
Stack<TreeNode> s2 = new Stack<TreeNode>();
ArrayList<ArrayList<Integer>> list = new ArrayList<ArrayList<Integer>>();
while (!s1.empty() || !s2.empty()) {
if (level%2 != 0) {
ArrayList<Integer> temp = new ArrayList<Integer>();
while (!s1.empty()) {
TreeNode node = s1.pop();
if(node != null) {
temp.add(node.val);
s2.push(node.left);
s2.push(node.right);
}
}
if (!temp.isEmpty()) {
list.add(temp);
level++;
}
} else {
ArrayList<Integer> temp = new ArrayList<Integer>();
while (!s2.empty()) {
TreeNode node = s2.pop();
if(node != null) {
temp.add(node.val);
s1.push(node.right);
s1.push(node.left);
}
}
if (!temp.isEmpty()) {
list.add(temp);
level++;
}
}
}
return list;
}
}
【解题思路2】
//1. 层序遍历
//2.当遍历到奇数层时,从左到右存储该层遍历的值。当遍历到偶数层时,从右到左存储该层遍历的值。
public class Solution {
public ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
ArrayList<ArrayList<Integer>> layers = new ArrayList<ArrayList<Integer>>();
if (pRoot == null)
return layers;
Deque<TreeNode> queue = new LinkedList<TreeNode>();
queue.offer(pRoot);
int depth = 0;
while (!queue.isEmpty()) {
depth ++;
ArrayList<Integer> layer = new ArrayList<Integer>();
int cur = 0, size = queue.size();
if ((depth & 1) == 0) { //如果是偶数层倒序添加
Iterator<TreeNode> it = queue.descendingIterator();
while (it.hasNext()) {
layer.add(it.next().val);
}
}
else { //如果是奇数层正序添加
Iterator<TreeNode> it = queue.iterator();
while (it.hasNext()) {
layer.add(it.next().val);
}
}
while (cur < size) {
TreeNode node = queue.poll();
if (node.left != null) {
queue.offer(node.left);
}
if (node.right != null) {
queue.offer(node.right);
}
cur ++;
}
layers.add(layer);
}
return layers;
}
}
a. (depth & 1) == 0 是用来判断depth是否为偶数。
上述思想在实现上,还有另外一个版本
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
public class Solution {
public ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>();
if(pRoot == null){
return result;
}
boolean leftToRight = true;
Queue<TreeNode> layer = new LinkedList<TreeNode>();
ArrayList<Integer> layerList = new ArrayList<Integer>();
layer.add(pRoot);
int start = 0, end = 1;
while(!layer.isEmpty()){
TreeNode cur = layer.remove();
if(leftToRight){
//从左向右存储
layerList.add(cur.val);
}else{
//从右向左反向存储
layerList.add(0,cur.val);
}
start++;
if(cur.left!=null){
layer.add(cur.left);
}
if(cur.right!=null){
layer.add(cur.right);
}
if(start == end){
end = layer.size();
start = 0;
result.add(layerList);
leftToRight = !leftToRight;
layerList = new ArrayList<Integer>();
}
}
return result;
}
}
【解题思路3】
//1.层序遍历,正常存储每一层的节点。
//2.奇数层正常打印,偶数层反转后再打印。
//3.此种方法reverse()的实现,复杂度较高。在测试用例数据量较大时,不适用。因此也不再给出具体实现。