
Title:
Running Time of Connected Component  Intro to Algorithms

Description:

It's important to analyze the running time of this algorithm

so we have some idea of how efficient it is.

And again, that's going to involve counting up the number of primitive steps,

primitive statements, time that the algorithm takes when solving a problem.

We'll assume, as before, that n represents the number of nodes in the graph

and m represents the number of edges.

And it turns out that the basic strategy that we use for this algorithm

is a kind of graph search.

There's 2 principal flavors of graft search, depth first search and breadth first search.

This one that we've been talking about is a form of depth first search.

Later we're going to see a version of breadth first search

when we start looking at shortest paths.

But this particular algorithm is not concerned about the length of the paths,

it's just trying to figure out which nodes can be reached by any kind of path.

So taking a look at this algorithm here,

one of the things that we can note right off the bat

is statements like this one, marked(node) = True,

can only be executed once for each node in the graph.

So even though it's a little bit hard to tell exactly when this is going to execute,

we know at the end of the day every node is going to get marked

and no node is going to get marked twice.

So that means once for each node in the graph we're going to execute this statement

and this statement and this loop.

And what does this loop do?

It goes through and basically visits all the edges that come out of this particular node (node).

And for each of those edges, well, it does some work.

It checks whether or not it's marked, which we're going to assume is a unit time operation,

some kind of nice hash table and it behaves nicely,

and a recursive call, and we're going to somehow have to account for

all the stuff that happens in this recursive call, but let's not worry about that for the moment.

It's going to do this one main computation, this adding whatever value it gets back

to this quantity here, then it returns.

So these statements here are going to get executed once per node.

This statement is going to get executed once per node.

This statement is going to get executed once per edge in the graph

because for each node it's going to visit all the edges emanating from that node.

So even though it's very difficult to keep track of what's going to be executed when,

we know that the total running time here is going to be big theta

of the number of nodes plus the total number of edges in the graph.

So that's what's happening in this marked component.

And then what's happening outside here, this marked gets executed once at all,

then for every node in the graph it may or may not execute this statement,

which does the call to mark component.

So we're going to iterate over all the nodes,

and again, we're going to do some work but not more than constant work per node.

And if we look at our running time here, adding another n in here doesn't change the big theta.

Again, even though it's very complex to figure out which statements are executing when,

the actual running time is big theta of n + m.

It's worth pointing out that this is linear in the size of the graph.

The graph consists of some number of nodes and some number of edges,

and that's the whole story.

So this is actually linear in the size of the graph.