二叉树的层次遍历(BFS和DFS)

leetcode 102题 :https://leetcode-cn.com/problems/binary-tree-level-order-traversal/

# 广度优先搜索(BFS)

自己的解法

/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */

func levelOrder(root *TreeNode) [][]int {
    var ret [][]int
    if root == nil {
        return ret
    }
    // 使用两个队列,队列1保存本层节点,队列2保存下一层节点
    queue := []*TreeNode{root}
    nQueue := []*TreeNode{}
    
    level := []int{}
    for len(queue)!=0{
        // 出队
        node := queue[0]
        queue = queue[1:]
        level = append(level,node.Val)
        
        // 子节点入队
        if node.Left!=nil{
            nQueue = append(nQueue,node.Left)
        }
        if node.Right!=nil{
            nQueue = append(nQueue,node.Right)
        }
        
        // 本层节点遍历完,继续遍历下一层
        if len(queue) == 0 {
            ret = append(ret,level)
            level = []int{}
            queue = nQueue
            nQueue = []*TreeNode{}
        }
    } 
    return ret
}

看了一下别人的题解,发现只需使用一个队列即可,代码也比较简洁

func levelOrder(root *TreeNode) [][]int {
    var ret [][]int
    if root == nil {
        return ret
    }
    queue := []*TreeNode{root}
    for len(queue)!=0{
        n := len(queue)
        level := make([]int,n)
        // 只遍历n次
        for i:=0 ;i <n; i++ {
            // 出队
            node := queue[0]
            queue = queue[1:]
            level[i] = node.Val
            // 子节点只入队,不会被遍历到
            if node.Left!=nil{
                queue = append(queue,node.Left)
            }
            if node.Right!=nil{
                queue = append(queue,node.Right)
            }
        }
        ret = append(ret,level)
        // 循环下一层
    } 
    return ret
}

# 深度优先搜索(DFS)

覃超老师的课中还提到了深度优先遍历的写法(先序遍历,递归,感觉go里面带切片参数的递归写起来不够优雅啊~)

func levelOrder(root *TreeNode) [][]int {
    ret := [][]int{}
    if root == nil {
        return nil
    }
    ret = preOrder(root,0,ret)
    return ret
}

func preOrder(root *TreeNode,h int, ret [][]int) [][]int {
    if root == nil {
        return ret
    }
    if len(ret) == h {
        ret = append(ret, []int{})
    }
    ret[h] = append(ret[h], root.Val)
    ret = preOrder(root.Left,h+1,ret)
    ret = preOrder(root.Right,h+1,ret)
    return ret
}

自己又尝试写DFS的非递归写法,但是发现比较麻烦,主要是节点属于哪一层需要额外记录。

反过头来思考递归写法,节点的层数已经在调用栈中记录了。

如果你有DFS比较好的非递归写法,麻烦写在评论中,谢谢~

发布了3 篇原创文章 · 获赞 0 · 访问量 68

猜你喜欢

转载自blog.csdn.net/weixin_40108561/article/details/104105072