题目描述
请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推。
思路:
对比从上到下打印二叉树https://blog.csdn.net/orangefly0214/article/details/83743664
广度优先遍历有向图,树都要用到队列。而本题也是考察广度优先遍历,不过
对于二叉树的奇数行:从左到右打印,与BFS遍历顺序一样。
偶数行:从右到左打印,与BFS遍历顺序相反。
1.当二叉树的根节点(节点1)打印之后,它的左子节点(节点2)和右子节点(节点3)先后保存到一个数据容器中。先保存2,再保存3(即先保存左节点,再保存右节点).
2.在打印第2层时,先打印节点3,再打印节点2,因此保存这个节点的容器应该是先进后出的,所以可以考虑用栈来实现。接着打印第2层的两个节点,先打印3,再打印2,并将它们的子节点保存到容器中。而再打印第3层时,先打印的是2的子节点4,5,再打印3的子节点6,7。因此我们在保存这些子节点时,按照栈的特点,应该保存为7,6,5,4。所以在打印第二层的节点时,应该先保存右节点,再保存左节点。
3.打印第3层,和上面过程一样,在打印的同时,将子节点保存到栈中,先保存左子节点,再保存右子节点。和保存第一层节点的顺序是相同的。
总结规律:按之字形顺序打印二叉树需要两个栈,打印奇数层的时候,将下一层的节点先左子节点,后右子节点入栈1。打印偶数层的时候,将下一层的节点先右子节点,再左子节点入栈2。
实现1:
import java.util.ArrayList;
import java.util.Stack;
/*
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
public class Solution {
public ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
int level=1;
Stack<TreeNode> s1=new Stack<>();
Stack<TreeNode> s2=new Stack<>();
s1.push(pRoot);
ArrayList<ArrayList<Integer>> list=new ArrayList<ArrayList<Integer>>();
while(!s1.isEmpty()||!s2.isEmpty()){
if(level%2!=0){
//奇数层
ArrayList<Integer> temp=new ArrayList<>();
while(!s1.isEmpty()){
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.isEmpty()){
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;
}
}