diff --git a/thu_dsa/chp6/Graph.md b/thu_dsa/chp6/Graph.md index f0cc12b..da87e9a 100644 --- a/thu_dsa/chp6/Graph.md +++ b/thu_dsa/chp6/Graph.md @@ -98,7 +98,16 @@ void Graph::bfs(int start){ > bfs算法复杂度的分析。 -当采用邻接矩阵表示时,BFS中为了找到当前顶点的全部邻居,需要完全遍历邻接矩阵的一行,需要$O(n)$的时间。 +当采用邻接矩阵表示时,BFS中为了找到当前顶点的全部邻居,需要完全遍历邻接矩阵的一行,需要$O(n)$的时间,所有顶点都会入队一次,出队一次,故上面$O(n)$的遍历操作一共需要进行n次,故访问所有顶点需要$O(n^2)$的时间复杂度。此外,图中的每条边都需要进行一次标记,所以一共需要$O(n^2 + e) = O(n^2)$的时间。 + +而当采用邻接表表示图时,对于当前顶点访问到它的邻居只需要$O(1)$的时间,所有顶点都会被访问一次,所有边也会被访问一次,所以需要$O(n + e)$的时间,这个结果和图的规模相当,已经是期望的最优结果了。 + +但是,如果考虑到计算机体系结构中的缓存,当采用邻接矩阵表示时,邻接矩阵的结构很容易触发缓存机制,从而使邻接矩阵中一行数据全部存放到缓存中。由于缓存的速度往往是内存的百十万倍,这样,尽管从渐进的分析,仍然是$O(n^2)$的时间复杂度,但是前面的常数项已经非常小,可以忽略到为了找到全部邻居而需要的时间,从而仍然可以达到$O(n + e)$的时间复杂度。 > bfs的应用。 +由上面所述,bfs显然可以用来进行连通性的检测。凡是连通的顶点都可以在一次BFS中被发现,因此对一个图进行bfs,调用BFS的次数,即是图的连通分量的个数。 + +此外,由bfs访问顶点的次序可以看出,bfs总是优先访问离当前顶点最近的顶点,这使得bfs可以用以发现图中的最短路径。但是这里的最短路径只能是拓扑结构的最短路径,或者说无权图,或者等权图的最短路径。 + +然后,邓公说还可以用来做连通分量的分解,无向图的环路检测,以后再探索一下。