问题
This is a generic BFS implementation:
For a connected graph with V
nodes and E
total number of edges, we know that every edge will be considered twice in the inner loop. So if the total number of iterations in the inner loop of BFS is going to be 2 * number of edges E
, isn't the runtime going to be O(E)
instead?
回答1:
This is a case where one needs to look a little deeper at the implementation. In particular, how do I determine if a node is visited or not?
The traditional algorithm does this by coloring the vertices. All vertices are colored white at first, and they get colored black as they are visited. Thus visitation can be determined simply by looking at the color of the vertex. If you use this approach, then you have to do O(V) worth of initialization work setting the color of each vertex to white at the start.
You could manage your colors differently. You could maintain a data structure containing all visited nodes. If you did this, you could avoid the O(V) initialization cost. However, you will pay that cost elsewhere in the data structure. For example, if you stored them all in a balanced tree, each if w is not visited
now costs O(log V).
This obviously gives you a choice. You can have O(V+E) using the traditional coloring approach, or you can have O(E log V) by storing this information in your own data structure.
You specify a connected graph in your problem. In this case, O(V+E) == O(E) because the number of vertices can never be more than E+1. However, the time complexity of BFS is typically given with respect to an arbitrary graph, which can include a very sparse graph.
If a graph is sufficiently sparse (say, a million vertices and five edges), the cost of initialization may be great enough that you want to switch to a O(E ln V) algorithm. However, these are pretty rare in a practical setting. In a practical setting, the speed of the traditional approach (giving each vertex a color) is just so blinding fast compared to the more fancy data structures that you choose this traditional coloring scheme for everything except the most extraordinarily sparse graphs.
If you maintained a dedicated color property on your vertices with an invariant rule that all nodes are black between algotihm invocations, you could drop the cost to O(E) by doing each BFS twice. On your first pass, you could set them all to white, and then do a second pass to turn them all black. If you had a very sparse graph, this could be more efficient.
回答2:
Well, let's break it up into easy pieces...
You've kept a visited array, and by looking it up, you decide whether to
push
anode
into thequeue
or not. Once visited, you don'tpush
it again. So, how many nodes get pushed into the queue:(of course) V nodes
. And it's complexity is O(V).Now, each time, you take out
a node
from queue and visit all of itsneighboring nodes
. Now, following this way,for all of V nodes
, how many node you'll come across. Well, it's thenumber of edges
if the graph isunidirectional
, or,2 * number of edges
if the graph isbidirectional
. So, the complexity would beO(E)
forunidirectional
andO(2 * E)
forbidirectional
.
So, the ultimate(i.e. total) complexity would be O(V + E)
or O(V + 2 * E)
or generally
, we may say O(v + E)
.
回答3:
Because there might be graph having edges less than number of vertices. Consider this graph:
1 ---- 2
|
|
3 ---- 4
There are 4 vertices but only 3 edges, and in BFS you have to traverse each and every vertex. Thatswhy time complexity is O(V+E) as it considers both V as well as E.
来源:https://stackoverflow.com/questions/63321659/why-is-the-complexity-of-bfs-ove-instead-of-oe