如果说深度优先遍历是在一个方向上“一头扎到底”,那么广度优先遍历则恰恰相反:先在各个方向上各走出1步,再在各个方向上走出第2步、第3步……一直到各个方向全部走完。听起来有些抽象,下面让我们通过二叉树的**层序遍历**,来看一看广度优先是怎么回事。<br /> 层序遍历,顾名思义,就是二叉树按照从根节点到叶子节点的层次关系,一层一层横向遍历各个节点。<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/955151/1612856386554-bdf87963-7767-4184-981d-7ac4fc0c9203.png#height=138&id=x3bEY&margin=%5Bobject%20Object%5D&name=image.png&originHeight=554&originWidth=781&originalType=binary&ratio=1&size=215720&status=done&style=none&width=195)<br />上图就是一个二叉树的层序遍历,每个节点左侧的序号代表该节点的输出顺序。<br />可是,二叉树同一层次的节点之间是没有直接关联的,如何实现这种层序遍历呢?<br />这里同样需要借助一个数据结构来辅助工作,这个数据结构就是队列。
详细遍历步骤如下:
- 根节点1进入队列。
2. 节点1出队,输出节点1,并得到节点1的左孩子节点2、右孩子节点3。让节点2和节点3入队。
3. 节点2出队,输出节点2,并得到节点2的左孩子节点4、右孩子节点5。让节点4和节点5入队。
4. 节点3出队,输出节点3,并得到节点3的右孩子节点6。让节点6入队。
5. 节点4出队,输出节点4,由于节点4没有孩子节点,所以没有新节点入队。
6. 节点5出队,输出节点5,由于节点5同样没有孩子节点,所以没有新节点入队。
7. 节点6出队,输出节点6,节点6没有孩子节点,没有新节点入队。
到此为止,所有的节点都遍历输出完毕。
实现代码
/**
* 二叉树层序遍历
*/
import java.util.LinkedList;
import java.util.Queue;
class TreeNode {
int value;
TreeNode left;
TreeNode right;
TreeNode(int value) {
this.value = value;
}
}
public class Test {
public static void main(String[] args) {
TreeNode[] node = new TreeNode[10];// 以数组形式生成一棵完全二叉树
for (int i = 0; i < 10; i++) {
node[i] = new TreeNode(i);
}
for (int i = 0; i < 10; i++) {
if (i * 2 + 1 < 10)
node[i].left = node[i * 2 + 1];
if (i * 2 + 2 < 10)
node[i].right = node[i * 2 + 2];
}
// 广度优先遍历(也叫层序遍历)
levelOrderTraversal(node[0]);
}
public static void levelOrderTraversal(TreeNode biTree) {
Queue<TreeNode> queue = new LinkedList<TreeNode>();
//offer方法:向队列尾部插入元素(越界时返回假)
queue.offer(biTree);
while (!queue.isEmpty()) {
//poll方法:从队列头部删除元素(队列为空时返回null)
TreeNode node = queue.poll();
System.out.print(node.value + " ");
if (node.left != null) {
queue.offer(node.left);
}
if (node.right != null) {
queue.offer(node.right);
}
}
}
}