简单算法 按之字形顺序打印二叉树(java)
描述
给定一个二叉树,返回该二叉树的之字形层序遍历,(第一层从左向右,下一层从右向左,一直这样交替)
例如:
给定的二叉树是{1,2,3,#,#,4,5}
该二叉树之字形层序遍历的结果是
[
[1],
[3,2],
[4,5]
]
想法:找两个栈分别储存奇数偶数层的二叉树结点
代码:
import java.util.ArrayList;
import java.util.*;
/*
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) {
ArrayList<ArrayList<Integer>> list = new ArrayList<ArrayList<Integer>>();
Stack<TreeNode> s1 = new Stack<TreeNode>();
s1.push(pRoot);//将头结点放入奇数层
Stack<TreeNode> s2 = new Stack<TreeNode>();
int flag = 1;//判断在奇数层还是偶数层所用
while(!s1.empty() || !s2.empty()){
if(flag % 2 != 0){
//判断在奇数层
ArrayList<Integer> a1 = new ArrayList<Integer>();//储存结点上的数
while(!s1.empty()){//把s1所有结点取出找到下一层结点并放入s2
TreeNode t1 = s1.pop();
if(t1 != null){
a1.add(t1.val);
s2.push(t1.left);
s2.push(t1.right);
}
}
if(!a1.isEmpty()){//判断a1是否有值,有值加入list
list.add(a1);
flag++;
}
}else{
//判断在偶数层
ArrayList<Integer> a2 = new ArrayList<Integer>();//储存结点上的数
while(!s2.empty()){//把s2所有结点取出找到下一层结点并放入s1
TreeNode t1 = s2.pop();
if(t1 != null){
a2.add(t1.val);
s1.push(t1.right);//这里顺序变了,因为是之字型遍历
s1.push(t1.left);
}
}
if(!a2.isEmpty()){//判断a2是否有值,有值加入list
list.add(a2);
flag++;
}
}
}
return list;
}
}
然后我又看见了一个利用LinkList集合可以正反遍历来实现:
思路:利用Java中的LinkedList的底层实现是双向链表的特点。
可用做队列,实现树的层次遍历
可双向遍历,奇数层时从前向后遍历,偶数层时从后向前遍历
public ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
ArrayList<ArrayList<Integer>> ret = new ArrayList<>();
if (pRoot == null) {
return ret;
}
ArrayList<Integer> list = new ArrayList<>();
LinkedList<TreeNode> queue = new LinkedList<>();
queue.addLast(null);//层分隔符
queue.addLast(pRoot);
boolean leftToRight = true;
while (queue.size() != 1) {
TreeNode node = queue.removeFirst();
if (node == null) {//到达层分隔符
Iterator<TreeNode> iter = null;
if (leftToRight) {
iter = queue.iterator();//从前往后遍历
} else {
iter = queue.descendingIterator();//从后往前遍历
}
leftToRight = !leftToRight;
while (iter.hasNext()) {
TreeNode temp = (TreeNode)iter.next();
list.add(temp.val);
}
ret.add(new ArrayList<Integer>(list));
list.clear();
queue.addLast(null);//添加层分隔符
continue;//一定要continue,到了这里因为是null分隔层所以不必找它是否有左右结点,直接跳过下面代码的这次循环
}
if (node.left != null) {
queue.addLast(node.left);
}
if (node.right != null) {
queue.addLast(node.right);
}
}
return ret;
}