第36期:二叉树的遍历(小白必看)

我准备了 1000 本电子书和计算机各领域高清思维导图 100 张,关注后回复【资源】,即可获取!更可回复【内推】加入 BAT 内推群!

第36期:二叉树的遍历(小白必看)

在上一节中,我们通过例题学习了二叉树最大深度与DFS,其实就是沿着一个方向一直向下遍历。那我们可不可以按照高度一层一层的访问树中的数据呢?当然可以,就是本节中我们要讲的BFS(宽度优先搜索),同时也被称为广度优先搜索。

我们仍然通过例题进行讲解。

01、题目分析


第102题:二叉树的层次遍历


给定一个二叉树,返回其按层次遍历的节点值。(即逐层地,从左到右访问所有节点)。


示例:

给定二叉树 [3,9,20,null,null,15,7],
    3   
   / \  
  9  20    
    /  \  
   15   7
返回其层次遍历结果:[[3],[9,20],[15,7]]

02、BFS介绍


BFS,广度/宽度优先。其实就是从上到下,先把每一层遍历完之后再遍历一下一层。假如我们的树如下:

第36期:二叉树的遍历(小白必看)
按照BFS,访问顺序如下:

a->b->c->d->e->f->g

了解了BFS,我们开始对本题进行分析。

03、递归求解


同样,我们先考虑本题的递归解法。想到递归,我们一般先想到DFS。我们可以对该二叉树进行先序遍历(根左右的顺序),同时,记录节点所在的层次level,并且对每一层都定义一个数组,然后将访问到的节点值放入对应层的数组中。

扫描二维码关注公众号,回复: 12351738 查看本文章

假设给定二叉树为[3,9,20,null,null,15,7],图解如下:

第36期:二叉树的遍历(小白必看)
第36期:二叉树的遍历(小白必看)
根据以上分析,代码如下:

func levelOrder(root *TreeNode) [][]int {
    return dfs(root, 0, [][]int{})
}

func dfs(root *TreeNode, level int, res [][]int) [][]int {
    if root == nil {
        return res
    }
    if len(res) == level {
        res = append(res, []int{root.Val})
    } else {
        res[level] = append(res[level], root.Val)
    }
    res = dfs(root.Left, level+1, res)
    res = dfs(root.Right, level+1, res)
    return res
}

04、BFS求解


上面的解法,其实相当于是用DFS的方法实现了二叉树的BFS。那我们能不能直接使用BFS的方式进行解题呢?当然,我们可以使用Queue的数据结构。我们将root节点初始化进队列,通过消耗尾部,插入头部的方式来完成BFS。

具体步骤如下图:
第36期:二叉树的遍历(小白必看)

根据以上分析,代码如下:

func levelOrder(root TreeNode) [][]int {
var result [][]int
if root == nil {
return result
}
// 定义一个双向队列
queue := list.New()
// 头部插入根节点
queue.PushFront(root)
// 进行广度搜索
for queue.Len() > 0 {
var current []int
listLength := queue.Len()
for i := 0; i < listLength; i++ {
// 消耗尾部
// queue.Remove(queue.Back()).(
TreeNode):移除最后一个元素并将其转化为TreeNode类型
node := queue.Remove(queue.Back()).(*TreeNode)
current = append(current, node.Val)
if node.Left != nil {
//插入头部
queue.PushFront(node.Left)
}
if node.Right != nil {
queue.PushFront(node.Right)
}
}
result = append(result, current)
}
return result
}


猜你喜欢

转载自blog.51cto.com/15076236/2608545