二叉树的DFS和BFS

74 阅读1分钟

DFS

深度优先遍历。

func depth(node: TreeNode?) -> Int {
    guard let node = node else { return 0 }
    return max(depth(node.left), depth(node.right)) + 1
}
  1. 第一步首先理解一下递归 如求一个链表的长度。
func length(node: ListNode?) -> Int {
    if node == nil { return 0 }
    return length(node?.next) + 1
}

这种就是典型的先递,到终止条件再归,得到最终的结果。

func length(node: ListNode?, result: Int = 0) -> Int {
    if node == nil { return result }
    length(node?.next, result + 1)
}

这种就是只递不归。

求出任意树的深度。比如页面视图的最大深度。

func depth(_ view: UIView?) -> Int {
    guard let view = view else { return 0 }

    // 这个地方使用了 swift 的语法糖,代码更精简
    let max = view.subviews.map { depth($0) }.max() ?? 0
    return max + 1
}

递归确实不好理解,但极为有必要掌握。

BFS

广度优先遍历

func levelOrder(_ root: TreeNode1?) -> [[Int]] {
    guard let root = root else { return [] }

    var result = [[Int]]()

    var queue = [TreeNode1]()
    queue.append(root)
    while !queue.isEmpty {
        var array = [Int]()
        for _ in 0 ..< queue.count {
            let node = queue.removeFirst()
            array.append(node.val)
            if let left = node.left {
                queue.append(left)
            }
            if let right = node.right {
                queue.append(right)
            }
        }
        result.append(array)
    }
    return result
}

大致说下这个算法的流程,就是我把某一层的所有节点加入队列,然后将当层的所有的节点出队(这里有个小技巧,出队的数量就是当前队列中元素的数量),当这个队列出队的时候,再加他的子节点加入队列,直到队列被清空。

这种常用的算法确实应该熟记在心。