BFS template: (from wikipedia)
1 procedure BFS(G,v) is 2 create a queue Q 3 create a set V 4 add v to V 5 enqueue v onto Q 6 while Q is not empty loop 7 t ← Q.dequeue() 8 if t is what we are looking for then 9 return t 10 end if 11 for all edges e in G.adjacentEdges(t) loop 12 u ← G.adjacentVertex(t,e) 13 if u is not in V then 14 add u to V 15 enqueue u onto Q 16 end if 17 end loop 18 end loop 19 return none 20 end BFS
Recursive DFS template:
1 procedure DFS(G,v): 2 label v as discovered 3 for all edges from v to w in G.adjacentEdges(v) do 4 if vertex w is not labeled as discovered then 5 recursively call DFS(G,w)
Stack-based DFS implementation1
def dfs(G,s):
visited = {s}
stack = [iter(G[s])]
while stack:
try:
w = stack[-1].next()
if w not in visited:
visited.add(w)
stack.append(iter(G[w]))
except StopIteration:
stack.pop()
Stack-based DFS implementation2 (DFS in reverse order of adj list)
1 procedure DFS-iterative(G,v): 2 let S be a stack 3 S.push(v) 4 while S is not empty 5 v ← S.pop() 6 if v is not labeled as discovered: 7 label v as discovered 8 for all edges from v to w in G.adjacentEdges(v) do 9 S.push(w)The non-recursive implementation is similar to breadth-first search but differs from it in two ways: it uses a stack instead of a queue, and it delays checking whether a vertex has been discovered until the vertex is popped from the stack rather than making this check before pushing the vertex.
Code for Stack-based DFS Implementation1
The from start to current path is maintained implicitly in the stack.
#include <iostream>
#include <vector>
#include <stack>
#include <set>
#include <unordered_set>
using namespace std;
struct GraphNode
{
int label;
vector<GraphNode*> adjs;
GraphNode(int x): label(x){}
};
typedef vector<GraphNode*>::iterator adj_iter;
vector<vector<pair<GraphNode*, adj_iter> > > allSimplePathDFSIterative(GraphNode *start)
{
vector<vector<pair<GraphNode*, adj_iter> > > result;
vector<pair<GraphNode*,adj_iter> > stack;
unordered_set<GraphNode*> hash;
stack.push_back(make_pair(start, start->adjs.begin()));
while(!stack.empty())
{
GraphNode *cur = stack.back().first;
adj_iter iter = stack.back().second;
if(iter == cur->adjs.begin())
{
cout << cur->label << endl;
hash.insert(cur);
if(true/*current path meets requirement*/)
{
result.push_back(stack);
}
}
if(iter != cur->adjs.end())
{
GraphNode *next = *iter;
stack.back().second = ++iter;
if(hash.count(next) == 0)
{
stack.push_back(make_pair(next, next->adjs.begin()));
}
}
else
{
stack.pop_back();
}
}
return result;
}
int main() {
GraphNode *n0 = new GraphNode(0);
GraphNode *n1 = new GraphNode(1);
GraphNode *n2 = new GraphNode(2);
GraphNode *n3 = new GraphNode(3);
GraphNode *n4 = new GraphNode(4);
GraphNode *n5 = new GraphNode(5);
n0->adjs.push_back(n1);
n0->adjs.push_back(n2);
n0->adjs.push_back(n5);
n1->adjs.push_back(n0);
n1->adjs.push_back(n2);
n2->adjs.push_back(n0);
n2->adjs.push_back(n1);
n2->adjs.push_back(n3);
n2->adjs.push_back(n4);
n3->adjs.push_back(n2);
n3->adjs.push_back(n4);
n3->adjs.push_back(n5);
n4->adjs.push_back(n2);
n4->adjs.push_back(n3);
n5->adjs.push_back(n0);
n5->adjs.push_back(n3);
auto res = allSimplePathDFSIterative(n0);
for(int i=0; i<res.size(); i++)
{
for(int j=0; j<res[i].size(); j++)
{
cout << res[i][j].first->label << " ";
}
cout << endl;
}
return 0;
}
参考:
http://en.wikipedia.org/wiki/Depth-first_search
http://en.wikipedia.org/wiki/Breadth-first_search
Stack-based graph traversal ≠ depth first search http://11011110.livejournal.com/279880.html
http://algs4.cs.princeton.edu/41undirected/NonrecursiveDFS.java