按层遍历二叉树
准备工作
1.一个Node节点类
/**
* @Deacription 二叉树节点
* @Author BarryLee
* @Date 2019/12/7 9:11
*/
public class Node {
public int value;
public Node left;
public Node right;
public Node(int value) {
this.value = value;
}
}
2.初始化一棵树用于测试(可以画一下看看,很简单,这里省略)
Node head;
@Before
public void before() {
// 先构建一棵树
head = new Node(1);
head.left = new Node(2);
head.right = new Node(3);
head.left.left = new Node(4);
head.right.left = new Node(5);
head.right.right = new Node(6);
head.right.left.left = new Node(7);
head.right.right.right = new Node(8);
}
一、不打印当前层次
思路很简单,因为是按层来进行遍历,那肯定是使用队列(先进先出的原理)来实现了
1.先将头节点head放进队列
2.while循环遍历这个队列
3.poll拿出队列里的第一个节点cur
4.如果cur的左子节点不为空,放进队列
5.如果cur的右子节点不为空,放进队列
6.打印cur的值
@Test
public void test1() {
Queue<Node> queue = new LinkedList<>();
queue.add(head);
while(queue.size()>0) {
Node cur = queue.poll();
if(cur.left != null) {
queue.add(cur.left);
}
if(cur.right != null) {
queue.add(cur.right);
}
System.out.println(cur.value);
}
}
输出结果:
1 2 3 4 5 6 7 8
二、打印当前层次
基于上一个Demo,这个比不打印层次要复杂一点点,复杂在如何确定换行的时机,其实last和nlast两个变量就可以解决这个问题
解题思路
1.初始化变量,重点关注last和nlast
2.last表示当前行的最后一个节点,nlast表示下一行的最后一个节点
3.怎么确定last的值: 开始的时候为head没有问题,之后的每一行都是等于nlast
4.那么问题就变成了怎么确定nlast: 每次放入一个节点我们就把这个节点的子节点作为nlast(必须是从左往右)
再看一遍执行步骤
1.初始化参数,last==nlast==head。第一个节点进来队列,然后开始循环
2.弹出节点cur
3.如果左子节点不为空则进队列,并且nlast为cur的左子节点
4.如果右子节点不为空则进队列,并且nlast为cur的右子节点(所以现在的nlast就是head.right了)
5.打印cur:如果cur==last则换行,现在是头节点,所以换行
6.然后到了下一行,弹出head.left,重复步骤 3 & 4
7.注意,这时last是head.right,所以还没到换行的时机,经过上面的操作nlast变成了head.left.right,打印
8.然后继续遍历,弹出head.right,重复步骤 3 & 4
9.此时cur==last,该换行了,而nlast也变成了head.right.right
10.将nlast赋值给last,为什么呢,因为你要进下一行了呀,而下一行的最后一个节点就是nlast
11.如此反复,AC撒花
/**
* 按层遍历 -- 不打印当前是多少层
*/
@Test
public void test2() {
Queue<Node> queue = new LinkedList<>();
queue.add(head);
// 节点所在层次
int level = 0;
// 是否为当前层的第一个
boolean isFirst = true;
// 当前打印所在行的最后一个节点
Node last = head;
// 下一行的最后一个节点
Node nlast = head;
// 遍历
while(queue.size()>0) {
Node cur = queue.poll();
if(cur.left != null) {
queue.add(cur.left);
nlast = cur.left;
}
if(cur.right != null) {
queue.add(cur.right);
nlast = cur.right;
}
if(isFirst) {
System.out.print("level" + ++level + "->");
}
// 当前节点是当前行最后一个节点 -- 换行
if(last==cur) {
last = nlast;
isFirst = true;
System.out.println(cur.value);
} else {
isFirst = false;
System.out.print(cur.value + " ");
}
}
}
输出结果:
level1->1
level2->2 3
level3->4 5 6
level4->7 8
每天进步一点点!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。