【二叉树的层序遍历】
层序遍历,顾名思义,就是按层次来遍历整棵二叉树。层次是怎么定义的呢?二叉树的根节点为第1层或者第0层...
那么如何实现层次遍历呢?
要想实现层次遍历,就需要借助队列,因为队列的特点是先进先出,利用此特点,我们可以将已经访问的节点的子节点存进队列里,实现每个层次的顺序不变。
以下是关于二叉树层序遍历的实现
1.二叉树的层序遍历
实现思路1:按层遍历,简化思路(根+左孩子+右孩子)。我们利用队列,先让根节点入队列,再分别让左孩子和右孩子入队列,在左孩子和右孩子入队列的同时当前第一个节点出队列,那么循环何时终止呢?直到队列中所有的节点的都出队时。
2.二叉树的层序遍历的优化(层数)
实现思路2:构造element类(节点、层数),将同层的节点放在一起。其思路大体与思路2一致。
3.二叉树层序遍历问题的变形(完全二叉树的判定)
实现思路3:根据完全二叉树的定义,我们可以观察到完全二叉树的层序遍历每层节点之间没有null,所以我们可以利用二叉树的层序遍历来解决。
- 层序遍历树,直到遇到null;
- 检查队列中是否还有not null的存在;
- 带空的层序遍历,遇到null之后是否还有not null出现,如果有不是完全二叉树,没有则为完全二叉树。
代码中的树的层序遍历是:1 2 3 4 5 6 7 8
代码如下:
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
public class Tree1 {
//【层序遍历】
public static void levelOrderTraversal(Node root) {
if (root == null) {
return;
}
Queue<Node> queue=new LinkedList<>();
queue.add(root);
while(!queue.isEmpty()) {
Node front = queue.poll();//检索并删除
if(front.left!=null){
queue.add(front.left);
}
if(front.left!=null){
queue.add(front.right);
}
}
}
//【层序遍历的优化:分层】
//构造element
static class Element {
int level;
Node node;
//构造方法
public Element(int level, Node node) {
this.level = level;
this.node = node;
}
}
public List<List<Integer>> levelOrder(Node root) {
//List是接口,接口不能自己实例化,必须通过子类实例化。
List<List<Integer>> retList = new ArrayList<>();
if (root == null) {
return retList;
}
Queue<Element> queue = new LinkedList<>();
Element e = new Element(0, root);
queue.add(e);
while (!queue.isEmpty()) {
Element front = queue.poll();
if (front.level == retList.size()) {//难点
retList.add(new ArrayList<>());
}
retList.get(front.level).add(front.node.val);
if (front.node.left != null) {
queue.add(new Element(front.level + 1, front.node.left));
}
if (front.node.right != null) {
queue.add(new Element(front.level + 1, front.node.right));
}
}
return retList;
}
//【层序遍历的应用:判断完全二叉树】
//层序遍历节点,直到遇到null,检查队列中是否还有节点(not null)存在
public boolean isCompeteTreeNode(Node root){
Queue<Node> queue=new LinkedList<>();
queue.add(root);
while(true) {
Node front = queue.poll();
if (front == null) {
break;
}
queue.add(front.left);
queue.add(front.right);
}
while(!queue.isEmpty()){
Node node=queue.poll();//难点
if(node!=null){
return false;
}
}
return true;
}
public static void main(String[] args){
Node n1=new Node();
n1.val=1;
n1.left=new Node();
n1.left.val=2;
n1.left.left=new Node();
n1.left.left.val=4;
n1.left.right=new Node();
n1.left.right.val=5;
n1.left.right.right=new Node();
n1.left.right.right.val=8;
n1.right=new Node();
n1.right.val=3;
n1.right.left=new Node();
n1.right.left.val=6;
n1.right.right=new Node();
n1.right.right.val=7;
levelOrderTraversal(n1);
Tree1 L=new Tree1();
//静态方法无法调用非静态方法,构造一个对象,调用这个对象的引用
L.levelOrder(n1);
L.isCompeteTreeNode(n1);
}
}