二叉树的锯齿形层序遍历
一、题目简介
给定一个二叉树,返回其节点值的锯齿形层序遍历。(即先从左往右,再从右往左进行下一层遍历,以此类推,层与层之间交替进行)。
(题目来源:力扣(LeetCode))
例如:
给定二叉树 [3,9,20,null,null,15,7],
3
/ \
9 20
/ \
15 7
返回锯齿形层序遍历如下:
[
[3],
[20,9],
[15,7]
]
二、解决方法
1. BFS+双队列
package com.lxf.test;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
public class ZigzagLevelOrder {
public static void main(String[] args) {
zigzagLevelOrder(new TreeNode(1));
}
public static List<List<Integer>> zigzagLevelOrder(TreeNode root) {
//表明锯齿在左还是在右
boolean flag=true;
//存储所有层的list数据
List<List<Integer>> lists=new LinkedList<List<Integer>>();
//存储当前层数据数据
List<Integer> list=new LinkedList<Integer>();
//存储树当前层所有节点的链表
LinkedList<TreeNode> treeCurNodes=new LinkedList<TreeNode>();
//存储树下一层节点的链表
LinkedList<TreeNode> treeNextNodes=new LinkedList<TreeNode>();
if(root==null) {
return lists;
}
//添加第一个节点
treeCurNodes.add(root);
//当下一层有节点时就一直遍历
while(treeNextNodes!=null) {
//现在这一层有节点就遍历获取这一层的值,并存储下一层节点
//如果没有直接将从本层切换到下层(下一层没有节点为止)
if(treeCurNodes.size()>0) {
//将本层的子节点存储到下一层
//如果当前层是反序,反插
//如果是正序,正插
if(flag) {
if(treeCurNodes.peek().left!=null) {
treeNextNodes.add(treeCurNodes.peek().left);
}
if(treeCurNodes.peek().right!=null) {
treeNextNodes.add(treeCurNodes.peek().right);
}
}else {
if(treeCurNodes.peek().right!=null) {
treeNextNodes.add(treeCurNodes.peek().right);
}
if(treeCurNodes.peek().left!=null) {
treeNextNodes.add(treeCurNodes.peek().left);
}
}
//再将当前层当前节点取出并获取它的值
list.add(treeCurNodes.poll().val);
}else {
//切换至下一层
//保存本层数据
lists.add(list);
//重置本层,赋值为下一层
treeCurNodes=new LinkedList<TreeNode>();
while(treeNextNodes.size()>0) {
treeCurNodes.add(treeNextNodes.pollLast());
}
//切换标志位(获取当前层子节点的顺序)
flag=!flag;
//重置下一层
if(treeCurNodes.size()<1) {
treeNextNodes=null;
}else {
treeNextNodes=new LinkedList<TreeNode>();
}
//重置存储数据的list
list=new ArrayList<Integer>();
}
}
return lists;
}
};
// 1 cur:3 next:2 3 cur:3 2 flag=false
// / \ cur:3 2 next:5641 cur: 1465 flag=true
// 2 3 cur:1465 next: 78910111213 cur:13121110987 flag=false
// / \ / \
// 1 4 6 5
// / \ / \ / \ / \
// 7 8 9 10 11 12 13
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) {
val = x; }
}
优化:
package com.lxf.test;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
public class ZigzagLevelOrder {
public static void main(String[] args) {
TreeNode root = new TreeNode(1);
TreeNode t2 = new TreeNode(2);
TreeNode t3 = new TreeNode(3);
TreeNode t4 = new TreeNode(4);
TreeNode t5 = new TreeNode(5);
root.left=t2;
root.right=t3;
t2.left=t4;
t2.right=t5;
List<List<Integer>> lists = zigzagLevelOrder(root);
for (List<Integer> list : lists) {
for (Integer integer : list) {
System.out.print(integer+" ");
}
System.out.println();
}
}
public static List<List<Integer>> zigzagLevelOrder(TreeNode root) {
//表明锯齿在左还是在右
boolean flag = true;
//存储所有层的list数据
List<List<Integer>> lists = new LinkedList<List<Integer>>();
//存储当前层数据数据
LinkedList<Integer> list = new LinkedList<Integer>();
//存储树当前层所有节点的链表
LinkedList<TreeNode> treeCurNodes = new LinkedList<TreeNode>();
if (root == null) {
return lists;
}
//添加第一个节点
treeCurNodes.add(root);
//当下一层有节点时就一直遍历
while (!treeCurNodes.isEmpty()) {
int size = treeCurNodes.size();
for (int i = 0; i < size; i++) {
//将本节点的子节点添加到treeCurNodes中(如果是增强for循环会有问题)
if (treeCurNodes.peek().left != null) {
treeCurNodes.add(treeCurNodes.peek().left);
}
if (treeCurNodes.peek().right != null) {
treeCurNodes.add(treeCurNodes.peek().right);
}
//根据标志位进行尾插或者头插
if (flag) {
list.addLast(treeCurNodes.poll().val);
} else {
list.addFirst(treeCurNodes.poll().val);
}
}
//保存本层数据
// lists.add(list);这种方法不行,同一对像,到时候一变全便
lists.add(new ArrayList<>(list));
//切换标志位
flag = !flag;
//重置存储数据的list
list.clear();
}
return lists;
}
};
// 1 cur: 3 next:2 3 cur:3 2 flag=false
// / \ cur: 3 2 next:5641 cur:1465 flag=true
// 2 3 cur:1465 next: 78910111213 cur:13121110987 flag=false
// / \ / \
// 1 4 6 5
// / \ / \ / \ / \
// 7 8 9 10 11 12 13
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) {
val = x;
}
}
2. BFS+双端队列
package com.lxf.test;
import java.util.Deque;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
class Solution {
public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
List<List<Integer>> ans = new LinkedList<List<Integer>>();
if (root == null) {
return ans;
}
Queue<TreeNode> nodeQueue = new LinkedList<TreeNode>();
nodeQueue.offer(root);
boolean isOrderLeft = true;
while (!nodeQueue.isEmpty()) {
//存储当前层值得双端队列
Deque<Integer> levelList = new LinkedList<Integer>();
//当前层的长度
int size = nodeQueue.size();
for (int i = 0; i < size; ++i) {
//当前层当前节点
TreeNode curNode = nodeQueue.poll();
//isOrderLeft:true-->反插
//isOrderLeft:true-->正插
if (isOrderLeft) {
levelList.offerLast(curNode.val);
} else {
levelList.offerFirst(curNode.val);
}
//获取下一层节点
if (curNode.left != null) {
nodeQueue.offer(curNode.left);
}
if (curNode.right != null) {
nodeQueue.offer(curNode.right);
}
}
ans.add(new LinkedList<Integer>(levelList));
isOrderLeft = !isOrderLeft;
}
return ans;
}
}