算法通关村第五关-二叉树遍历(层数优先)之经典问题: 锯齿形层序遍历、N叉数层序遍历、获取每一层的最大值/平均数、获取二叉树右视图

锯齿形层序遍历
  • 情景:

二叉树如下:
     3
   /   \  
  8     9
 / \   /
20  11 6
锯齿形遍历:3 9 8 20 11 6
  • 在基本的层序遍历的基础上,如何实现锯齿形层序遍历?

  • 这样的思路能否完成呢:其他条件不变,改变存放节点值的顺序如何?(2023/09/10午)

  • 我们这里将 list 该换为 queue ,因为它可以提供了不同的入队方式

  • 具体代码如下:

 public static List> zigzagLevelOrder2(TreeNode root) {
        // 节点值列表
        List> ans = new LinkedList<>();
        if (root == null)
            return ans;
        // 队列,控制遍历节点顺序
        Deque queue = new LinkedList<>();
        // 根节点入队
        queue.offer(root);
        // 控制存放节点值顺序
        boolean isOrderLeft = true;
        while (!queue.isEmpty()) {
            // 每层的节点值列表
            Deque levelList = new LinkedList<>();
            // 该层节点数
            int size = queue.size();
            for (int i = 0; i < size; i++) {
                // 出队,存值
                TreeNode poll = queue.poll();
                if (isOrderLeft) {
                    levelList.offerFirst(poll.val);
                } else {
                    levelList.offerLast(poll.val);
                }
                // 左右孩子节点入队
                if (poll.left != null) {
                    queue.offer(poll.left);
                }
                if (poll.left != null) {
                    queue.offer(poll.right);
                }
            }
            ans.add(new LinkedList(levelList));
            // 变换存放节点值顺序
            isOrderLeft = !isOrderLeft;
        }
        return ans;
    }
N叉数的层序遍历
  • 问题:将二叉树的情景改为N叉数,遍历结果也是很简单的,即将左右子节点改为若干子节点(2023/09/10午)
  • 具体代码如下:

 public static List> nLevelOrder(NTreeNode root) {
        List> ans = new ArrayList<>();
        Deque queue = new ArrayDeque<>();
​
        if (root != null)
            queue.addLast(root);
​
        while (!queue.isEmpty()) {
            Deque next = new ArrayDeque<>();
            List nd = new ArrayList<>();
​
            while (!queue.isEmpty()) {
                NTreeNode cur = queue.pollFirst();
                nd.add(cur.val);
                // 入队,将孩子节点依次入队
                for (NTreeNode chd : cur.children) {
                    if (chd != null)
                        next.add(chd);
                }
            }
            queue = next;
            ans.add(nd);
        }
        return ans;
    }
  • 这里暂时没看懂为什么加了个 queue,日后解答

获取每一层的最大数(扩展)
  • 出队每层节点时,累加节点值,求平均值即可:(2023/09/11早)
public static List averageOfLevels(TreeNode root) {
        List res = new ArrayList<>();
        if (root == null) return res;
        
        Queue list = new LinkedList<>();
        list.add(root);
        
        while (list.size() != 0) {
            int len = list.size();
            double sum = 0;
            for (int i = 0; i < len; i++) {
                TreeNode node = list.poll();
                
                sum += node.val;
                if (node.left != null) list.add(node.left);
                if (node.right != null) list.add(node.right);
            }
            res.add(sum / len);
        }
        return res;
    }
获取每一层的平均数(扩展)
  • 出队节点时,比较节点值,求取最大值即可:

  public static List largestValues2(TreeNode root) {
        List res = new ArrayList<>();
        if (root == null) return res;
​
        Queue list = new LinkedList<>();
        list.add(root);
​
        while (list.size() != 0) {
            int len = list.size();
            double max = Double.MIN_VALUE;
            for (int i = 0; i < len; i++) {
                TreeNode node = list.poll();
​
                max = Double.max(max, node.val);
                if (node.left != null) list.add(node.left);
                if (node.right != null) list.add(node.right);
            }
            res.add(max);
        }
        return res;
    }
获取二叉树的右视图(扩展)
  • 统计每一层出队的最后一个节点即可

public static List rightSideView(TreeNode root) {
        List res = new ArrayList<>();
        if (root == null) {
            return res;
        }
        Queue queue = new LinkedList<>();
        queue.offer(root);
        while (!queue.isEmpty()) {
            int size = queue.size();
            for (int i = 0; i < size; i++) {
                TreeNode node = queue.poll();
                if (node.left != null) {
                    queue.offer(node.left);
                }
                if (node.right != null) {
                    queue.offer(node.right);
                }
                if (i == size - 1) {  //将当前层的最后一个节点放入结果列表
                    res.add(node.val);
                }
            }
        }
        return res;
    }

通关(过关挑战)

  • 情景:获取一个二叉树的左视图(2023/09/12午)
public static List rightSideView(TreeNode root) {
        List res = new ArrayList<>();
        if (root == null) {
            return res;
        }
        Queue queue = new LinkedList<>();
        queue.offer(root);
        while (!queue.isEmpty()) {
            int size = queue.size();
            for (int i = 0; i < size; i++) {
                TreeNode node = queue.poll();
                if (node.left != null) {
                    queue.offer(node.left);
                }
                if (node.right != null) {
                    queue.offer(node.right);
                }
                if (i == 0) {  //将当前层的第一个节点放入结果列表
                    res.add(node.val);
                }
            }
        }
        return res;
    }

你可能感兴趣的:(算法通关村,算法,经验分享,java)