算法通关村第六关|白银|二叉树的层次遍历【持续更新】

1.二叉树基本的层序遍历

仅仅遍历并输出全部元素。

java 复制代码
List<Integer> simpleLevelOrder(TreeNode root) {
    if (root == null) {
        return new ArrayList<Integer>();
    }
    List<Integer> res = new ArrayList<Integer>();
    LinkedList<TreeNode> queue = new LinkedList<TreeNode>();
    queue.add(root);
    while (queue.size() > 0) {
        TreeNode t = queue.remove();
        res.add(t.val);
        if (t.left != null) {
            queue.add(t.left);
        }
        if (t.right != null) {
            queue.add(t.right);
        }
    }
    return res;
}

2.二叉树层序遍历,但是按层分开

用 size 标记。

java 复制代码
public List<List<Integer>> levelOrder(TreeNode root) {
	if (root == null) {
        return new ArrayList<List<Integer>>();
	}

	List<List<Integer>> res = new ArrayList<List<Integer>>();
	LinkedList<TreeNode> queue = new LinkedList<TreeNode>();
	queue.add(root);
	while (queue.size() > 0) {
        // 获取当前层的元素个数
        int size = queue.size();
        ArrayList<Integer> temp = new ArrayList<Integer>();
        for (int i = 0; i < size; i++) {
            TreeNode t = queue.remove();
            temp.add(t.val);
            if (t.left != null) {
                queue.add(t.left);
            }
            if (t.right != null) {
                queue.add(t.right);
            }
        }
        res.add(temp);
    }
	return res;
}

3.二叉树层序遍历-自底向上

自底向上,逐层从左向右遍历。

和从根节点开始遍历基本一样,只不过是在往结果里存储的时候顺序改变。

java 复制代码
public List<List<Integer>> levelOrderBottom(TreeNode root) {
	List<List<Integer>> levelOrder = new LinkedList<List<Integer>>();
	if (root == null) {
        return levelOrder;
    }
	Queue<TreeNode> queue = new LinkedList<TreeNode>();
	queue.offer(root);
	while (!queue.isEmpty()) {
        List<Integer> level = new ArrayList<Integer>();
        int size = queue.size();
        for (int i = 0; i < size; i++) {
            TreeNode node = queue.poll();
            level.add(node.val);
            TreeNode left = node.left, right = node.right;
            if (left != null) {
                queue.offer(left);
            }
            if (right != null) {
                queue.offer(right);
            }
        }
        // add(index, element)
        // 将元素添加到指定的索引处,原来的链表的索引向后移动
        // 每次都往索引0处放,达到后来的先放的效果
        levelOrder.add(0, level);
    }
	return levelOrder;
}

4.二叉树的锯齿形层序遍历

锯齿形层序遍历就是先从左往右遍历一层,再从右往左遍历一层。

和上面的算法基本一样,只不过要用一个布尔型的变量指示从左向右还是从右向左,从右向左的话就需要从链表的前边进行添加。

java 复制代码
public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
	List<List<Integer>> ans = new LinkedList<List<Integer>>();
	if (root == null) {
        return ans;
    }
	Queue<TreeNode> queue = new LinkedList<TreeNode>();
	queue.offer(root);
	// 为true是从左向右遍历,为false是从右向左遍历
	boolean isOrderLeft = true;
	while (!queue.isEmpty()) {
        Deque<Integer> levelList = new LinkedList<Integer>();
        int size = queue.size();
        for (int i = 0; i < size; i++) {
            TreeNode curNode = queue.poll();
            if (isOrderLeft) {
                levelList.offerLast(curNode.val);
            } else {
                levelList.offFirst(curNode.val);
            }
            if (curNode.left != null) {
                queue.offer(curNode.left);
            }
            if (curNode.right != null) {
                queue.offer(curNode.right);
            }
        }
        ans.add(levelList);
        isOrderLeft = !isOrderLeft;
    }
	return ans;
}

5.N叉树的层序遍历

java 复制代码
public List<List<Integer>> nLevelOrder(Node root) {
	List<List<Integer>> value = new ArrayList<>();
	Deque<Node> q = new ArrayDeque<>();
	if (root != null) {
        q.addLast(root);
    }
	while (!q.isEmpty()) {
        Deque<Node> next = new ArrayDeque<>();
        List<Integer> nd = new ArrayList<>();
        while (!q.isEmpty()) {
            Node cur = q.pollFirst();
            nd.add(cur.val);
            for (Node chd : cur.children) {
                if (chd != null) {
                    next.add(chd);
                }
            }
        }
    	q = next;
        value.add(nd);
    }
    return value;
}

6.在每个树行中找最大值

用一个变量记录每行的最大值就好了。

java 复制代码
public List<Integer> largestValues(TreeNode root) {
	List<Integer> res = new ArrayList<>();
	Deque<TreeNode> deque = new ArrayDeque<>();
	if (root != null) {
        deque.addLast(root);
    }
	while (!deque.isEmpty()) {
        int size = deque.size();
        int levelMaxNum = Integer.MIN_VALUE;
        for (int i = 0; i < size; i++) {
            TreeNode node = deque.poll();
            levelMaxNum = Math.max(node.val, levelMaxNum);
            if (node.left != null) {
                deque.addLast(node.left);
            }
            if (node.right != null) {
                deque.addLast(node.right);
            }
        }
        res.add(levelMaxNum);
    }
	return res;
}

7.在每个树行中找平均值

java 复制代码
public List<Double> averageOfLevels(TreeNode root) {
	List<Double> res = new ArrayList<>();
	if (root == null) {
        return res;
    }
	Queue<TreeNode> 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;
}

8.二叉树的右视图

java 复制代码
public List<Integer> rightSideView(TreeNode root) {
	List<Integer> res = new ArrayList<>();
	if (root == null) {
        return res;
    }
	Queue<TreeNode> 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;
}

9.最底层最左边的值

回想锯齿形遍历时的isOrderLeft,这道题就是这个值一直取false,即从右向左遍历。那么就可以先添加右节点,再添加左节点,达到反过来的效果。

java 复制代码
public int findBottomLeftValue(TreeNode root) {
	if (root.left == null && root.right == null) {
        return root.val;
	}
	Queue<TreeNode> queue = new LinkedList<>();
	queue.offer(root);
	TreeNode temp = new TreeNode(0);

	while (!queue.isEmpty()) {
        temp = queue.poll();
        if (temp.right != null) {
            queue.offer(temp.right);
        }
        if (temp.left != null) {
            queue.offer(temp.left);
        }
    }
	return temp.val;
}

10.力扣404题

【持续更新】。

如果对您有帮助,请点赞关注支持我,谢谢!❤

如有错误或者不足之处,敬请指正!❤

个人主页:星不易 ♥

算法通关村专栏:不易|算法通关村 ♥

相关推荐
SL_staff7 小时前
私有化低代码:面向强监管行业的可控数字化实践
java·低代码
饮水桶_T7 小时前
JAVA IO流笔记
开发语言·数据结构·算法
三翼鸟数字化技术团队7 小时前
高性能存储引擎RocksDB:原理与Java生态实践
java
SL_staff8 小时前
JVS-APS有限产能建模的七个刚性支点:面向产线真实约束的技术实现解析
java·开源·全栈
特立独行的猫A8 小时前
少 3 个环节、少 1 次 ABI、少 3500 行代码:cj-tauri 与 Ionic/Capacitor 的鸿蒙桥接机制对比
java·后端·python
星夜离尘568 小时前
MATLAB 离散数据分箱:半开区间、末端点与计数、加权和、平均
算法·matlab
Pniubi8 小时前
力扣76.最小覆盖子串
算法·leetcode·职场和发展
学长毕设8 小时前
基于SpringBoot的高校后勤报修管理系统-附源码
java·spring boot·后端
特立独行的猫A8 小时前
cj-tauri vs Rust/Tauri 同款播放器实测:编译 21 秒 vs 11 分钟,磁盘 12 MB vs 1.2 GB
java·后端·python
地平线开发者8 小时前
征程6|用 hrt\_model\_exec 看清 YOLOv5x 的输入、原始输出和后处理
人工智能·算法