1、概述
2、基本的层次遍历
如上图逻辑 [3, 9, 20, 15, 7]
public class SimpleLevelOrder {
public static void main(String[] args) {
BinaryTree bTree = new BinaryTree();
bTree.root = bTree.buildBinaryTree();//建树
List<Integer> level = simpleLevelOrder(bTree.root);
System.out.println(level.toString());
System.out.println(level);
}
public static List<Integer> simpleLevelOrder(TreeNode root){
if(root == null){
return new ArrayList<Integer>();
}
List<Integer> res = new ArrayList<>();
LinkedList<TreeNode> queue = new LinkedList<>();
//根节点放入队列,不断遍历
queue.add(root);
//size = 0时,即这一层完毕,该遍历下一层了
while(queue.size() > 0){
TreeNode t = queue.remove();
res.add(t.val);
//移出后,把它的左孩子和右孩子加入队列
if(t.left != null){
queue.add(t.left);
}
if(t.right != null){
queue.add(t.right);
}
}
return res;
}
}
public class TreeNode {
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode(int val){
this.val = val;
}
public TreeNode(int val, TreeNode left, TreeNode right){
this.val = val;
this.left = left;
this.right = right;
}
}
public class BinaryTree {
public TreeNode root;
public BinaryTree() {
root = null;
}
public TreeNode buildBinaryTree() {
TreeNode node = new TreeNode(3);
node.left = new TreeNode(9);
node.right = new TreeNode(20);
node.right.right = new TreeNode(7);
node.right.left = new TreeNode(15);
return node;
}
}
3、层次遍历按层输出
用一个size记录层元素的个数,每一层size个元素出队后,刚好可以把该层作为list存储,下次for循环遍历下一层的元素。[[3],[9,20],[15,7]]
public static List<List<Integer>> level102Order(TreeNode root){
if(root == null){
return new ArrayList<List<Integer>>();
}
List<List<Integer>> res = new ArrayList<List<Integer>>();
LinkedList<TreeNode> queue = new LinkedList<>();
queue.add(root);
while(queue.size() > 0){
//以层为单位
int size = queue.size();
ArrayList<Integer> tmp = new ArrayList<>();
//以层出队列,并把它的子孩子加入队列
for (int i = 0; i < size; i++) {
TreeNode t = queue.remove();
tmp.add(t.val);
if(t.left != null){
queue.add(t.left);
}
if(t.right != null){
queue.add(t.right);
}
}
res.add(tmp);
}
return res;
}
4、自底向上层序遍历
与上面只是1个区别,待输出的最外层列表在添加层时从0处加,即res.add(0,tmp)
[[15,7],[9,20],[3]]
public class LevelOrderBottom {
public static void main(String[] args) {
BinaryTree bTree = new BinaryTree();
bTree.root = bTree.buildBinaryTree();
List<List<Integer>> level = levelOrderBottom(bTree.root);
System.out.println(level);
}
public static List<List<Integer>> levelOrderBottom(TreeNode root){
List<List<Integer>> res = new LinkedList<List<Integer>>();
if(root == null){
return res;
}
Queue<TreeNode> queue = new LinkedList<TreeNode>();
queue.offer(root);
while(!queue.isEmpty()){
//以层为单位
List<Integer> tmp = new LinkedList<>();//ArrayList<>和LinkedList<>都可以,定义头不是全写也可以
int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode t = queue.poll();
tmp.add(t.val);//不是queue,是add,没有offer
if(t.left != null){
queue.offer(t.left);
}
if(t.right != null){
queue.offer(t.right);
}
}
//入一层节点,因为是自底向上,所以从0入
res.add(0,tmp);
}
return res;
}
}
5、锯齿形层序遍历
奇数层:从左至右输出,偶数层:从右往左输出
如果从左至右,我们每次将被遍历到的元素插入至双端队列的末尾。
从右至左,我们每次将被遍历到的元素插入至双端队列的头部。
public static List<List<Integer>> zigzagLevelOrder(TreeNode root){
List<List<Integer>> res = new LinkedList<List<Integer>>();
if(root == null){
return res;
}
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
boolean isOrderLeft = true;//是否从左往右,1行,默认true
while(!queue.isEmpty()){
//以层为单位
Deque<Integer> tmp = new LinkedList<>();
int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode t = queue.poll();
if(isOrderLeft == true){
tmp.offerLast(t.val);
}else{
tmp.offerFirst(t.val);
}
if(t.left != null){
queue.offer(t.left);
}
if(t.right != null){
queue.offer(t.right);
}
}
res.add(new LinkedList<Integer>(tmp));//定义头转换一下,不能是Deque
isOrderLeft = !isOrderLeft;//别忘了,锯齿形。而且不能用-号时!号
}
return res;
}
6、N叉树层序遍历
与前面差不多,只不过当节点出队列的时候不像之前:如果有,把它们的左右子孩子加入队列。而现在是一个集合,一个集合的孩子加入队列。
public static List<List<Integer>> nLevelOrder(NTreeNode root){
List<List<Integer>> res = new ArrayList<List<Integer>>();
if(root == null){
return res;
}
Queue<NTreeNode> queue = new LinkedList<>();
queue.offer(root);
while(!queue.isEmpty()){
List<Integer> temp = new ArrayList<>();
int size = queue.size();
for (int i = 0; i < size; i++) {
NTreeNode t = queue.poll();
temp.add(t.val);
for(NTreeNode node: t.children){
queue.offer(node);
}
}
res.add(temp);
}
return res;
}