The BFS and DFS algorithms differ essentially only in that one uses a queue in its implementation and the other uses a stack.
There are two basic ways to represent a graph: using an adjacency matrix or an adjacency list.
Adjacency Matrix: Consider a graph G=(V,E) with n nodes and assume the set of nodes is V={1,…,n}. An adjacency matrix is an nxn matrix A where A[u,v] is equal to 1 if the graph contains the edge (u,v) and 0 otherwise. If the graph is undirected, A is symmetric with A[u,v]=A[v,u] for all nodes u and v in V. The adjacency matrix allows us to check in O(1) time if a given edge (u,v) is present in the graph. However:
Adjacency List: In this representation, there is a record for each node v, containing a list of all nodes to which v has edges. In other words, we have an array Adj where Adj[v] is a record containing a list of all nodes adjacent to node v. For an undirected graph G=(V,E), each edge e=(v,w) in E occurs on two adjacency lists, node w appears on the list for node v and node v appears on the list for node w.
A queue is a set from which we extract elements in first-in, first-out (FIFO) order; we select elements in the same order in which they were added. A stack is a set from which we extract elements in last-in, first-out (LIFO) order; each time we select an element, we choose the one that was added most recently. Both queues and stacks can be implemented via a doubly linked list. In both cases, we select the first element in the list, the difference is where we insert a new element. In a queue, we insert a new element at the end of the list as the last element, whereas in a stack we insert a new element in the first position on the list. Doubly linked lists have FIRST and LAST pointers, so insertion can be done in constant time.
This implementation runs in O(n+m) time.
This implementation runs in O(n+m) time.