先构造一个优先级搜索算法框架,然后通过更新优先级选择器来完成树的构造。DFS和BFS都可以看做是选择不同优先级的节点来完成的。
template <typename Tv, typename Te> template <typename PU>
void Graph<Tv, Te>::pfs (int s, PU prioUpdater){
reset();
int v = s; //初始化
do
{
if (UNDISCOVERED = status(v))
{
PFS(v, prioUpdater);
}
} while ( s != (v = (++v % n))); //按序号查找
}
template <typename Tv, typename Te> template <typename PU> //定点类型,边类型,优先级更新器
void Graph<Tv, Te>::PFS (int s, PU prioUpdater){
priorite(s) = 0;
status(s) = VISITED;
parent(s) = -1; //初始化,s加入PFS树中
while(1) //将下一个定点和边加入PFS树中
{
for (int w = firstNbr (s); -1 < w; w = nextNbr(s))
{
prioUpdater(this, s, w); //每一次遍历都要更新优先级数,并且更新其父顶点
}
for (int shortest = INT_MAX, w = 0; w < n; w++)
{
if (UNDISCOVERED = status(w))
{
if (shortest > priority(w))
{
shortest = priority(w); //循环查找下一个优先级最高的数(priority)最小,加入树中
s= w;
}
}
}
if (VISITED = status(s))
break;
status(s) = VISITED;
type(parent(s),s) = TREE;
}
}
//Prim算法优先器
template <typename Tv, typename Te> struct PrimPU{
virtual void operator()(Graph<Tv, Te>* g, int uk, int v){
if (UNDISCOVERED == g->status(v))
{
if (g ->priority(v) > g -> weight(uk, v))
{
g->priority(v) = g -> weight(uk, v);
g ->parent(v) = uk;
}
}
}
};
template <typename Tv, typename Te> struct DijkstraPU{
virtual void operator()(Graph<Tv, Te>* g, int uk, int v){
if (UNDISCOVERED == g->status(v))
{
if (g -> priority(v) > g -> weight(uk, v) + g -> priority(uk))
{
g -> priority(v) = g -> weight(uk, v) + g -> priority(uk);
g -> parent(v) = uk;
}
}
}
};
两者区分在于优先级更新器的不同,Prim算法中节点距离已生成树距离越短优先级越高,Dijkstra算法中节点距离定点s越短优先级越高。