6.2.1 BFS 广度优先搜索
template<typename Tv, typename Te> void graph<Tv, Te>::BFS(int v, int& clock)
{
queue<int> Q;
status(v) = DISCOVERED;
Q.enqueue(v);
while (!Q.empty())
{
v = Q.dequeue();
dTime(v) = ++clock;
for (int u = firstNbr(v); u >= 0; u = nextNbr(v, u))
{
if (status(u) == UNDISCOVERED)
{ cout << "(v,u)" << "(" << v<<"," << u << ")" << endl;
status(u) = DISCOVERED;
type(v, u) = TREE;
parent(u) = v;
Q.enqueue(u);
}
else
{
type(v, u) = CROSS;
}
}
status(v) = VISITED;
}
}
template<typename Tv, typename Te> void graph<Tv, Te>::bfs(int s)
{
reset();
int clock = 0;
int v = s;
do
{
if(status(v)==UNDISCOVERED)
BFS(v,clock);
v++;
cout << "v----" << v << endl;
} while ((v = (++v%n)) != s);
}
6.2.2 DFS 深度优先搜索
template<typename Tv, typename Te> void graph<Tv, Te>::DFS(int v, int& clock)
{
status(v) = DISCOVERED;
dTime(v) = ++clock;
for (int u = firstNbr(v); u > -1; u = nextNbr(v, u))
{
switch (status(u))
{
case UNDISCOVERED:
status(u) = DISCOVERED;
type(v, u) = TREE;
parent(u) = v;
DFS(u, clock);
break;
case DISCOVERED:
type(v, u) = BACKWARD;
break;
default:
type(v, u) = (dTime(v) < dTime(u)) ? FORWARD : CROSS;
break;
}
}
status(v) = VISITED;
fTime(v) = ++clock;
}
template<typename Tv, typename Te> void graph<Tv, Te>::dfs(int s)
{
reset();
int clock = 0;
int v = s;
do
{
if (status(v) == UNDISCOVERED)
DFS(v, clock);
cout << "v----" << v << endl;
} while ((v=(++v%n)) != s);
}
6.2.3 DFS应用-拓扑排序
template<typename Tv, typename Te> bool graph<Tv, Te>::TSort(int v, int& clock, stack<Tv>* S)
{
status(v) = DISCOVERED;
dTime(v) = ++clock;
for (int u = firstNbr(v); u > -1; u = nextNbr(v, u))
{
switch (status(u))
{
case UNDISCOVERED:
status(u) = DISCOVERED;
type(v, u) = TREE;
parent(u) = v;
if (!TSort(u, clock, S))
return false;
break;
case DISCOVERED:
type(v, u) = BACKWARD;
return false;
default:
type(v, u) = (dTime(v) < dTime(u)) ? FORWARD : CROSS;
break;
}
}
status(v) = VISITED;
S->push(vdata(v));
return true;
}
template<typename Tv, typename Te> stack<Tv>* graph<Tv, Te>::tSort(int s)
{
reset();
stack<Tv>* S=new stack<Tv>;
int v = s;
int clock = 0;
do
{
if (status(v) == UNDISCOVERED)
{
if (!TSort(v, clock, S))
{
while (!(S->empty()))
{
S->pop();
}
break;
}
}
} while ((v=(++v)%n)!=s);
return S;
}
6.2.4 优先级搜索(PFS)
template<typename Tv, typename Te> template<typename PU> void graph<Tv, Te>::PFS(int s, PU prioUpdater)
{
priority(s) = 0;
status(s) = VISITED;
cout << "选中的顶点:" << vdata(s) << endl;
parent(s) = -1;
while (true)
{
for (int w = firstNbr(s); w > -1; w = nextNbr(s, w))
{
prioUpdater(this, s, w);
}
for (int shortest = INT_MAX, w = 0; w < n; w++)
{
if (status(w) == UNDISCOVERED)
if (priority(w) < shortest)
{
shortest = priority(w);
s = w;
}
}
if (status(s) == VISITED) break;
status(s) = VISITED;
cout << "选中的顶点:"<<vdata(s) << endl;
cout << parent(s) << endl;
type(parent(s), s) = TREE;
}
}
template<typename Tv, typename Te> template<typename PU> void graph<Tv, Te>::pfs(int s, PU prioUpdater)
{
reset();
int v = s;
do
{
if (status(v) == UNDISCOVERED)
PFS(v, prioUpdater);
} while ((v = (++v%n)) != s);
}
6.2.5 PFS应用-最小支撑树(Prim算法)
template<typename V, typename E> struct PrimPU
{
void operator()(graph<V, E>* g, int uk, int v)
{
if (g->status(v) == UNDISCOVERED)
if ((g->weight(uk, v)) < (g->priority(v)))
{
g->priority(v) = g->weight(uk, v);
g->parent(v) = uk;
cout << "寻找顶点(uk,v)" << "(" << uk << "," << v << ")" <<"----w---"<<g->weight(uk,v)<< endl;
}
}
};
template<typename Tv, typename Te> void graph<Tv, Te>::prim(int s)
{
PrimPU<Tv, Te> prioUpdater;
pfs(s, prioUpdater);
}
6.2.6 PFS应用-最短路径(Dijkstra算法)
template<typename V, typename E> struct DijkstraPU
{
void operator()(graph<V, E>* g, int uk, int v)
{
if (g->status(v) == UNDISCOVERED)
{
if ((g->weight(uk, v) + g->priority(uk)) < (g->priority(v)))
{
g->priority(v) = g->weight(uk, v) + g->priority(uk);
g->parent(v) = uk;
}
}
}
};
template<typename Tv, typename Te> void graph<Tv,Te>::dijkstra(int s)
{
DijkstraPU<Tv, Te> prioUpdater;
pfs(s, prioUpdater);
}