题目描述
请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推。
分析:
- 使用双栈s1 和s2 ,来分别存储奇数层和偶数层的节点,
- 每打印一个节点,就把此节点的下一层的左右节点加入队列
- 使用list来记录打印节点的顺序
用到栈的特性:后进先出
- 打印奇数层 的节点node,并把node的左右子节点遍历入栈,下一层(偶数层)pop出栈就变成了逆序遍历(从右到左);
if (node != null) { temp1.add(node.val); //System.out.print(node.val + " ");//打印奇数层 的节点node s2.push(node.left);//奇数层,正序遍历入栈,下一层(偶数层)pop出栈就变成了逆序遍历 s2.push(node.right); }
- 打印偶数层 的节点node,并把node的右左子节点遍历入栈,下一层(奇数层)pop出栈就变成了顺序遍历(从左到右);
if (node != null) { temp2.add(node.val); // System.out.print(node.val + " ");//分别打印这一行的元素 s1.push(node.right);//偶数层,逆序遍历入栈,下一层(奇数层)pop出栈就变成了顺序遍历 s1.push(node.left); }
/**
* 大家的实现很多都是将每层的数据存进ArrayList中,偶数层时进行reverse操作,
* 在海量数据时,这样效率太低了。
*/
代码:
import java.util.ArrayList;
import java.util.Stack;
public class Test1 {
public ArrayList<ArrayList<Integer>> Print(TreeNode pRoot) {//最终要返回一个list,且list的每一个元素是 数组ArrayList<Integer>
int layer = 1;
//s1存奇数层节点
Stack<TreeNode> s1 = new Stack<TreeNode>();
s1.push(pRoot);
//s2存偶数层节点
Stack<TreeNode> s2 = new Stack<TreeNode>();
//list存储打印顺序的数组, list的每一个元素是 数组ArrayList<Integer>
ArrayList<ArrayList<Integer>> list = new ArrayList<ArrayList<Integer>>();
while (!s1.empty() || !s2.empty()) {
ArrayList<Integer> temp1 = new ArrayList<Integer>();
while (!s1.empty()) {
TreeNode node = s1.pop();
if (node != null) {
temp1.add(node.val);
System.out.print(node.val + " ");
s2.push(node.left);//奇数层,正序遍历入栈,下一层(偶数层)pop出栈就变成了逆序遍历
s2.push(node.right);
}
}
if (!temp1.isEmpty()) {
list.add(temp1);//把temp数组加进来
layer++;//换行
System.out.println();
}
ArrayList<Integer> temp2 = new ArrayList<Integer>();
while (!s2.empty()) {
TreeNode node = s2.pop();
if (node != null) {
temp2.add(node.val);
System.out.print(node.val + " ");//分别打印这一行的元素
s1.push(node.right);//偶数层,逆序遍历入栈,下一层(奇数层)pop出栈就变成了顺序遍历
s1.push(node.left);
}
}
if (!temp2.isEmpty()) {
// list.add(temp);//把temp数组加进来
layer++;
System.out.println();
}
}
return list;//没有输出的返回语句
}
public static void main(String[] args) {
TreeNode root=new TreeNode(8);
root.left = new TreeNode(6);
root.right = new TreeNode(10);
root.left.left = new TreeNode(5);
root.left.right = new TreeNode(7);
root.right.left = new TreeNode(9);
root.right.right = new TreeNode(11);
Test1 test1 =new Test1();
test1.Print(root);
}
}
打印结果:
扩展部分:
- 使用layer来记录层数(因为使用了双栈,非必需)
-
public ArrayList<ArrayList<Integer>> Print(TreeNode pRoot) {//最终要返回一个list,且list的每一个元素是 数组ArrayList<Integer> int layer = 1; //s1存奇数层节点 Stack<TreeNode> s1 = new Stack<TreeNode>(); s1.push(pRoot); //s2存偶数层节点 Stack<TreeNode> s2 = new Stack<TreeNode>(); //list存储打印顺序的数组, list的每一个元素是 数组ArrayList<Integer> ArrayList<ArrayList<Integer>> list = new ArrayList<ArrayList<Integer>>(); while (!s1.empty() || !s2.empty()) { if (layer % 2 != 0) { ArrayList<Integer> temp = new ArrayList<Integer>(); while (!s1.empty()) { TreeNode node = s1.pop(); if (node != null) { temp.add(node.val); System.out.print(node.val + " "); s2.push(node.left);//奇数层,正序遍历入栈,下一层(偶数层)pop出栈就变成了逆序遍历 s2.push(node.right); } } if (!temp.isEmpty()) { list.add(temp);//把temp数组加进来 layer++;//换行 System.out.println(); } } else { ArrayList<Integer> temp = new ArrayList<Integer>(); while (!s2.empty()) { TreeNode node = s2.pop(); if (node != null) { temp.add(node.val); System.out.print(node.val + " ");//分别打印这一行的元素 s1.push(node.right);//偶数层,逆序遍历入栈,下一层(奇数层)pop出栈就变成了顺序遍历 s1.push(node.left); } } if (!temp.isEmpty()) { // list.add(temp);//把temp数组加进来 layer++; System.out.println(); } } } return list;//没有输出的返回语句 }
需要注意:stack.empty() 和arr. isEmpty() 没什么区别