算法通关村——树的层次遍历

二叉树层次遍历的经典问题

语言描述

层次遍历就是,从第一层开始,每一层从左向右遍历

第一层只有根节点,只输出根节点,之后进入第二层从左向右遍历

难点在于,在二叉树中,左孩子和右孩子两个节点无法直接相互访问到。也就需要一个队列来帮助遍历。

在这里插入图片描述

红框里面就是用队列辅助层次遍历

103.二叉树的锯齿形层次遍历

锯齿形层序遍历 。(即先从左往右,再从右往左进行下一层遍历,以此类推,层与层之间交替进行)。

第一个想法,设置单双数行,偶数行从左向右入队(根节点算第0层),奇数行从右向左入队

以下是错误代码,逻辑混乱。本质是容器用得不熟练

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
        if(root == null) {
            return new LinkedList<List<Integer>>();
        }
        //答案
        List<List<Integer>> ans = new LinkedList<List<Integer>>();
        Queue<TreeNode> queue = new LinkedList<TreeNode>();
        //根节点入队
        queue.add(root);
        //flag记录行的奇偶,0为偶
        int flag = 1;
        //队列非空
        while(!queue.isEmpty()) {
            //记录上一次加入队列的节点数,即为本次处理的节点数
            int size = queue.size();
            //临时数组,存放一行的val
            List<Integer> tmp = new ArrayList<Integer>();
            switch(flag){
                case 0:
                    for(int i = 0; i < size; i++) {
                        TreeNode node = queue.poll();
                        tmp.add(node.val);
                        if(node.left != null) {
                            queue.offer(node.left);
                        }
                        if(node.right != null) {
                            queue.offer(node.right);
                        }
                    }
                    ans.add(tmp);
                    flag = 1;
                    break;
                case 1:
                    for(int i = 0; i < size; i++) {
                        TreeNode node = queue.poll();
                        tmp.add(node.val);
                        if(node.right != null) {
                            queue.add(node.right);
                        }
                        if(node.left != null) {
                            queue.offer(node.left);
                        }
                    }
                    ans.add(tmp);
                    flag = 0;
                    break;
            }
        }
        return ans;
    }
}

正确代码

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
        if(root == null) {
            return new LinkedList<List<Integer>>();
        }
        //答案
        List<List<Integer>> ans = new LinkedList<List<Integer>>();
        Queue<TreeNode> queue = new LinkedList<TreeNode>();
        //根节点入队
        queue.offer(root);
        //
        boolean isOrderLeft = true;
        //队列非空
        while(!queue.isEmpty()) {
            //记录上一次加入队列的节点数,即为本次处理的节点数
            int size = queue.size();
            //临时数组,存放一行的val
            Deque<Integer> tmp = new LinkedList<Integer>();
            for(int i = 0; i < size; i++) {
                //此处入队顺序不用变
                TreeNode curNode = queue.poll();
                if(isOrderLeft) {
                    tmp.offerLast(curNode.val);
                } else {
                    tmp.offerFirst(curNode.val);
                }
                if(curNode.left != null) {
                    queue.offer(curNode.left);
                }
                if(curNode.right != null) {
                    queue.offer(curNode.right);
                }
            }
            ans.add(new LinkedList<Integer>(tmp));
            isOrderLeft = !isOrderLeft;
        }
        return ans;
    }
}

429.N叉树的层次遍历

/*
// Definition for a Node.
class Node {
    public int val;
    public List<Node> children;

    public Node() {}

    public Node(int _val) {
        val = _val;
    }

    public Node(int _val, List<Node> _children) {
        val = _val;
        children = _children;
    }
};
*/

class Solution {
    public List<List<Integer>> levelOrder(Node root) {
        if(root == null) {
            return new ArrayList<List<Integer>>();
        }
        //答案
        List<List<Integer>> ans = new ArrayList<List<Integer>>();
        //辅助队列
        Deque<Node> queue = new LinkedList<Node>();
        //将根节点添加至队尾
        queue.addLast(root);
        while(!queue.isEmpty()) {
            //先取出上一层得到的 待处理层的节点数量
            int size = queue.size();
            //存储该层节点
            List<Integer> tmp = new ArrayList<Integer>();
            //逐个节点处理
            for(int i = 0; i < size; i++) {
                //从队首取出 待处理节点 ,并加入tmp数组
                Node cur = queue.poll();
                tmp.add(cur.val);
                for(Node a : cur.children) {
                    queue.addLast(a);
                }
            }
            ans.add(tmp);
        }
        return ans;
    }
}

637.二叉树的层平均

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public List<Double> averageOfLevels(TreeNode root) {
        if(root == null) {
            return new ArrayList<Double>();
        }
        //答案
        List<Double> ans = new ArrayList<Double>();
        //辅助队列
        Deque<TreeNode> queue = new LinkedList<TreeNode>();
        //根节点入队
        queue.addLast(root);
        while(!queue.isEmpty()) {
            Double tmp = 0.0;
            int size = queue.size();
            for(int i = 0; i < size; i++) {
                //将队中第一个元素取出
                TreeNode a = queue.pollFirst();
                tmp += a.val;
                if(a.left != null) {
                    queue.addLast(a.left);
                }
                if(a.right != null) {
                    queue.addLast(a.right);
                }
            }
            tmp /= size;
            ans.add(tmp);
        }
        return ans;
    }
}

199.二叉树的右视图

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public List<Integer> rightSideView(TreeNode root) {
        if(root == null) {
            return new ArrayList<Integer>();
        }
        List<Integer> ans = new ArrayList<Integer>();
        //辅助队列
        Deque<TreeNode> queue = new LinkedList<TreeNode>();
        //根节点入队
        queue.addLast(root);
        while(!queue.isEmpty()) {
            int size = queue.size();
            TreeNode node = null;
            //相当于取到每一行最右侧的节点
            for(int i = 0; i < size; i++) {
                node = queue.poll();
                if(node.left != null) {
                    queue.addLast(node.left);
                }
                if(node.right != null) {
                    queue.addLast(node.right);
                }
            }
            ans.add(node.val);
        }
        return ans;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值