概述
如何在层序遍历n叉树时,将每层元素分开?本文通过广度优先搜索(BFS)的方式解决这个问题。其实DFS也是可以的。
题目
给定一个 N 叉树,返回其节点值的层序遍历。 (即从左到右,逐层遍历)。
例如,给定一个3叉树:
+---------+
| |
| 1 |
| |
+----------+-----+---+-------------+
| | |
| | |
| | |
+---------+-+ +-----+-------+ +-+---------------+
| | | | | |
| | | | | |
| 3 | | 2 | | 4 |
| | | | | |
+-----+-----------++ +-------------+ +-----------------+
| |
| |
| |
| |
| |
| |
| |
+-------+-----+ +-----+-----------+
| | | |
| | | |
| 5 | | 6 |
| | | |
+-------------+ +-----------------+
返回其层序遍历:
[
[1],
[3,2,4],
[5,6]
]
说明:
树的深度不会超过1000。
树的节点总数不会超过5000。
解答
- 特意在main方法中新建了一棵树,可以用于调试
分隔符法
- 利用Queue进行广度优先搜索BFS,新建一个Node类作为分隔符S,利用引用比较来确定分隔符。
- 在Queue中root节点后添加S,以后每次从Queue中取出(head)S便在当前Queue中(tail)添加一个S,这样便分隔出一层,其余按照BFS的做法。这样,则每次前一层的元素遍历完,便会删除一个S,由于前一层所有元素的子元素已经添加到Queue中(即下一层的所有元素),所以删除S时便在末尾添加一个S,将当前层隔离开,以便后续添加不会搞混。当最后一层的所有元素迭代完时,碰到S不应该再添加S,所以要特判,否则会死循环。
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.List;
import java.util.Queue;
// Definition for a Node.
class Node {
public int val;
public List<Node> children;
public Node() {}
public Node(int _val,List<Node> _children) {
val = _val;
children = _children;
}
}
class Solution {
public static void main(String[] args) {
Node five = new Node(5, new ArrayList<>());
Node six = new Node(6, new ArrayList<>());
ArrayList<Node> l3 = new ArrayList<>();
l3.add(five);
l3.add(six);
Node three = new Node(3, l3);
Node two = new Node(2, new ArrayList<>());
Node four = new Node(4, new ArrayList<>());
List<Node> l2 = new ArrayList<>();
l2.add(three);
l2.add(two);
l2.add(four);
Node root = new Node(1, l2);
List<List<Integer>> lists = new Solution().levelOrder(root);
for (List<Integer> list : lists) {
System.out.println("---------------------");
for (Integer integer : list) {
System.out.println(integer);
}
System.out.println("-------------------------------------");
}
}
private static List<List<Integer>> zero = new ArrayList<>();
public List<List<Integer>> levelOrder(Node root) {
if (root == null) {
return zero;
}
Node SPECIAL = new Node();
List<List<Integer>> result = new ArrayList<>();
List<Integer> now = new ArrayList<>();
Queue<Node> queue = new ArrayDeque<>();
queue.add(root);
queue.add(SPECIAL);
while (queue.isEmpty() == false) {
Node poll = queue.poll();
if (poll == SPECIAL) {
result.add(now);
now = new ArrayList<>();
//最后一层时
if (queue.isEmpty() == false) {
queue.add(SPECIAL);
}
continue;
}
now.add(poll.val);
if (poll.children != null) {
queue.addAll(poll.children);
}
}
return result;
}
}
思考
- 如何利用DFS实现呢?
附录
- 推荐AsciiFlow这个网站用于画图