了解使用 BFS 进行树遍历的时间复杂度

Understanding Time Complexity for tree traversal using BFS

本文关键字:遍历 时间复杂度 BFS 了解      更新时间:2023-10-16

我试图理解当我使用 BFS 遍历具有 n 个节点(不一定是二叉树(的树时的时间复杂度。根据我的理解,它应该是 O(n^2(,因为我的外部循环运行了 n 次,即直到队列不为空并且因为树包含 n 个节点。我的内部 for 循环必须不断将与特定节点关联的子节点添加到队列中。(每个节点都有一个字典,其中包含其所有子节点的地址(因此,例如,如果根节点有 n-1 个节点(因此所有这些节点都没有子节点(,那么时间复杂度不是 n*(n-1( = O(n^2(。

我的理解正确吗?有什么方法可以在 O(n( 中完成此操作吗?请解释一下。

节点数和边的数量来描述图算法的复杂性通常更有用。通常 |V|用于表示节点数,并且 |E|表示边数。

在BFS,我们访问了每个|V|节点一次,并将其所有邻居添加到队列中。而且,在算法结束时,图形中的每个边都只处理了一次。因此我们可以说BFS是O(|V|+ |E|(。

在完全连接的图形中,|E|= |V|(|V|- 1)/2.所以你是对的,复杂度是 O(|V|^2( 表示完全连接的图形;但是,O(|V|+ |E|(被认为是对已知稀疏的图形的更严格的分析。

Big-O表示法表示时间复杂度的上限。你当然可以说BFS的时间复杂度是O(n2(,但这不是一个严格的上限。

要获得严格的上限,您可以像这样考虑BFS:每个节点只会添加到队列中一次,每个节点只会从队列中删除一次。每次添加和删除操作仅消耗 O(1( 时间,因此时间复杂度为 O(n(。

编辑

要在树上实现 O(n( BFS,可以尝试实现以下伪代码。

procedure bfs(root: root of the tree)
    q := an empty queue
    push root into q
    while q is not empty
        v := the element at the head of q
        for u := children of v
            push u into q
        pop v out of q