二叉树—层序遍历

【二叉树的层序遍历】

层序遍历,顾名思义,就是按层次来遍历整棵二叉树。层次是怎么定义的呢?二叉树的根节点为第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);
        }
}

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值