当前位置: 首页 > Web前端 > JavaScript

Leetcode算法解答系列——二叉树的层序遍历

时间:2023-03-27 15:09:38 JavaScript

本题旨在分享在刷Leecode过程中发现的一些有趣或有价值的想法。[当然答案是基于js的]。(这道题应该算是二叉树的基础题了,推荐学习一下,不难,经典)题目相关原题地址:https://leetcode-cn.com/probl...问题描述:从上到下逐层打印二叉树,同一层的节点从左到右打印,每一层打印到一行,例如给定二叉树:[3,9,20,null,null,15,7]3/\920/\157返回其层级遍历的结果:[[3],[9,20],[15,7]]提示考虑可能有些同学很少用js刷leetcode,这里简单介绍一下,关于树型数据输入,用js表示。如上题内容,给定一棵二叉树的输入不是数组,而是应该是这样的:每个节点都是一个对象constroot={val:3,left:{//left表示左边当前节点的侧子节点val:9,left:null,//从上图可以看出节点9没有左右子节点right:null,},right:{val:20,left:{val:15,//对比上图可以看出节点15没有左右子节点left:null,right:null,},right:{val:7,//对比上图,可以看出节点7没有左右子节点left:null,right:null,},}}思路分析这道题比较基础。其实测试就是BFS+顺序遍历。怎么说呢?首先,BFS(BreadthFirstSearch)即广度优先搜索,意思是在遍历过程中,总是先遍历当前节点的所有相邻节点,放入一个队列中,比如上题的例子:step1:首先准备一个空队列(即数组)[],将根节点放入数组,即[3];step2:先取出队列的头节点(此时队列只有节点3,取出后队列为空),然后将其所有相邻节点(即中的左右子节点)相加二叉树)依次进入访问队列,所以此时队列元素为[920],step3:继续按照第二步的规则,取出节点9,将9的子节点放入队列(没有子节点);然后取出节点20,将节点20的子节点存入队列,队列剩余元素为[15,7];step4:继续按照第二步的规则,取出节点15,将子节点放入队列(无子节点);然后取出节点7,将节点7的子节点存入队列,此时队列剩余元素为[],队列为空时整个流程结束;仔细观察以上步骤,你发现了吗?除第一步初始化数据外,后续所有步骤均按步骤2的规则重复;观察每一步的结果:step2,取出[3];step3,取出[9,20];step4,取出退出[15,17];这里每一步的结果正是题目设计要求的每一层遍历的结果。整个过程的结束条件是节点队列为空。就这道题而言,大概的思路已经很清楚了,或者说上面的步骤已经是伪代码了(没办法,因为题本身就很典型-_-!)首先,第2步的规则一定是main函数,因为它在整个过程中循环;其次,初始条件/结束条件对应于根节点入队且队列为空。唯一的难点在于如何优雅地处理【分层输出】,这个我建议大家直接看我最后贴出的完整代码。完整代码那么其实可以直接看代码:varlevelOrder=function(root){if(!root){//如果根节点不存在,则直接结束return[];}const节点=[root];//初始化,对应前面分析中的初始条件,constres=[];while(nodes.length>0){//当节点队列为空时外层循环结束consttempRes=[];让isEmpty=false;//【注意点】这个内循环是处理分层输出的本质。大家可以仔细揣摩这个循环的情况。//尝试回答为什么这里不使用"i=0;i0;i--){constnode=nodes.转移();温度电阻。推(节点。瓦尔);如果(节点。左){节点。推(节点。左);}if(node.right){nodes.push(node.right);}}res.push(tempRes);}返回资源;费时),但是我想给大家两个问题思考一下:就是代码块中的问题,为什么内层循环的条件不是i=0;i<节点.长度;我++?如果是,如何?如果本题演化为输出深度优先遍历的结果,核心点应该怎么改?如果你能回答以上两个问题,你就基本了解了这个知识点!