先按照注释的提示新建三个头文件Graph,Lqueue,stack,把相应头文件的实现代码分别拷进去,最后在源程序中包含这三个头文件。
在main()函数中调用各种功能时(比如求关键路径),先实例化一个模板的对象,如Graph<int> gph;
接下来要调用创建图的函数(共有三种存储结构:邻接矩阵的,邻接表的,十字链表的---可根据单词缩写判断是哪个函数)
例如要求关键路径,需先创建一个以邻接表作存储结构的图。可调用gph.CreateAlgraph();
这时创建工作完成了,可以调用求关键路径的函数了。gph.Criticalpath();
这时已经可以运行求解了。但为了不浪费资源,我们还需要调用一个销毁邻接表的函数来回收空间。
最后再加一句gph.DestroyAlgraph();
这时整个程序就OK了。
关于图的其它功能函数,还请读者自己慢慢看。本人就不赘述了!
//**********Graph.h
#ifndef _GRAPH_H
#define _GRAPH_H
#include “Lqueue.h”
#include “stack.h”
template <class TElemType>
struct Treenode
{
TElemType data;
Treenode<TElemType> *lchild,*nextsibling;
}; //用于深度优先生成森林
template <class TElemType>
class Graph
{
public:
void CreateUDN();
void DestroyUDN();
void CreateDN();
void DestroyDN();
void CreateAlgraph();
void DestroyAlgraph();
void CreateOlgraph();
void DestroyOlgraph();
void DFS(int v,bool *visited);
void DFSTraverse();
void BFSTraverse();
void DFSForest(Treenode<TElemType> *&T);
void DFSTree(int v,Treenode<TElemType> *&T,bool *visited);
void PreDFSForest(Treenode<TElemType> *T);
void DFSOlgraph(int v,bool *visited,int *finished); //表示顺向深度优先搜索
void DFSOlgraph(int v,bool *visited);
void Conponderance(); //求有向图的强连通分量
void Minispantree_prim(); //PRIM算法求最小生成树
void DFSAlgraph(int v,int *low,int *visited);
void DFSAlgraph(int v,int *visited); //检验头结点是否关节点
void FindCritic(); //无向图求其关节点
void TopologicalSort(); //有向图拓扑排序,检验环的存在与否
float * TopologicalOrder(stack<int> &sre,int &e);
void Criticalpath(); //求有向无环图关键路径
void Shortestpath_DIJ(TElemType data1,TElemType data2); //对环不适用,如从V1到V1就不适用
void Shortestpath_FLOYD(TElemType data1,TElemType data2);
private:
int count;
template <class TElemType>
struct Mgraph{
int vexnum;
int arcnum;
TElemType *vertex;
int **AdjMatrix;
};
Mgraph<TElemType> gph; //邻接矩阵存储
struct Arcnode
{
int adjvex;
Arcnode *nextarc;
float weight;
};
template <class TElemType>
struct Vexnode
{
TElemType data;
Arcnode *firarc;
};
struct ALgraph
{
int vexnum;
int arcnum;
bool kind;
Vexnode<TElemType> *vex;
};
ALgraph algraph; //邻接表存储
struct ArcBox
{
int headvex,tailvex;
ArcBox *hlink,*tlink;
float weight;
};
template <class TElemType>
struct Vertex
{
TElemType data;
ArcBox *firstin,*firstout;
};
struct Olgraph
{
int vexnum,arcnum;
Vertex<TElemType> *vex;
};
Olgraph olgraph; //有向图的十字链表存储结构
};
//*********Graph.cpp
template <class TElemType>
void Graph<TElemType>::CreateUDN()
{
cout << “输入无向网的顶点数和边数:” << endl;
cin >> gph.vexnum >> gph.arcnum;
gph.vertex = (TElemType *)malloc(gph.vexnum * sizeof(TElemType));
int i,j,m,n; //m,n表示顶点信息对应的序号,w是权值
int w;
TElemType v1,v2;
cout << “输入顶点信息:” << endl;
for(i = 0;i < gph.vexnum;i++)
cin >> gph.vertex[i];
gph.AdjMatrix = (int **)malloc(gph.vexnum * sizeof(int *));
for(i = 0;i < gph.vexnum;i++)
gph.AdjMatrix[i] = (int *)malloc(gph.vexnum * sizeof(int));
for(i = 0;i < gph.vexnum;i++)
for(j = 0;j < gph.vexnum;j++)
gph.AdjMatrix[i][j] = INT_MAX; //INT_MAX
cout << “输入一条边依附的两点及权值:” << endl;
for(int k = 0;k < gph.arcnum;k++)
{
cin >> v1 >> v2 >> w;
for(i = 0;i < gph.vexnum;i++)
{
if(v1 == gph.vertex[i]) m = i;
if(v2 == gph.vertex[i]) n = i;
}
gph.AdjMatrix[m][n] = gph.AdjMatrix[n][m] = w;
}
}
template <class TElemType>
void Graph<TElemType>::DestroyUDN()
{
free(gph.vertex);
for(i = 0;i < gph.vexnum;i++)
free(gph.AdjMatrix[i]);
free(gph.AdjMatrix);
}
template <class TElemType>
void Graph<TElemType>::CreateDN()
{
cout << “输入有向图的顶点数和边数:” << endl;
cin >> gph.vexnum >> gph.arcnum;
gph.vertex = (TElemType *)malloc(gph.vexnum * sizeof(TElemType));
int i,j,m,n; //m,n表示顶点信息对应的序号,w是权值
int w;
TElemType v1,v2;
cout << “输入顶点信息:” << endl;
for(i = 0;i < gph.vexnum;i++)
cin >> gph.vertex[i];
gph.AdjMatrix = (int **)malloc(gph.vexnum * sizeof(int *));
for(i = 0;i < gph.vexnum;i++)
gph.AdjMatrix[i] = (int *)malloc(gph.vexnum * sizeof(int));
for(i = 0;i < gph.vexnum;i++)
for(j = 0;j < gph.vexnum;j++)
gph.AdjMatrix[i][j] = INT_MAX; //INT_MAX
cout << “输入弧尾弧头两点及权值:” << endl;
for(int k = 0;k < gph.arcnum;k++)
{
cin >> v1 >> v2 >> w;
for(i = 0;i < gph.vexnum;i++)
{
if(v1 == gph.vertex[i]) m = i;
if(v2 == gph.vertex[i]) n = i;
}
gph.AdjMatrix[m][n] = w;
}
}
template <class TElemType>
void Graph<TElemType>::DestroyDN()
{
for(int i = 0;i < gph.vexnum;i++)
free(gph.AdjMatrix[i]);
free(gph.AdjMatrix);
free(gph.vertex);
}
template <class TElemType>
void Graph<TElemType>::CreateAlgraph()
{
int i,j,m,n;
float w;
TElemType v1,v2;
Arcnode *p;
cout << “输入图类型(1是无向图,0是有向图):” << endl;
cin >> algraph.kind;
cout << “输入顶点数和边数:” << endl;
cin >> algraph.vexnum >> algraph.arcnum;
algraph.vex = (Vexnode<TElemType> *)malloc(algraph.vexnum * sizeof(Vexnode<TElemType>));
cout << “输入顶点信息:” << endl;
for(i = 0;i < algraph.vexnum;i++)
{
cin >> algraph.vex[i].data;
algraph.vex[i].firarc = NULL;
}
if(algraph.kind)
{
cout << “输入各边依附的两点和权值:” << endl;
for(i = 0;i < algraph.arcnum;i++)
{
cin >> v1 >> v2 >>w;
for(j = 0;j < algraph.vexnum;j++)
{
if(v1 == algraph.vex[j].data) m = j;
if(v2 == algraph.vex[j].data) n = j;
}
p = (Arcnode *)malloc(2*sizeof(Arcnode));
p[0].adjvex = n;p[0].weight = w;
p[1].adjvex = m;p[1].weight = w;
p[0].nextarc = algraph.vex[m].firarc;algraph.vex[m].firarc = p;
p[1].nextarc = algraph.vex[n].firarc;algraph.vex[n].firarc = ++p;
}
}
else
{
cout << “输入各边的弧尾与弧头结点及有向边的权值:” << endl;
for(i = 0;i < algraph.arcnum;i++)
{
cin >> v1 >> v2 >> w;
for(j = 0;j < algraph.vexnum;j++)
{
if(v1 == algraph.vex[j].data) m = j;
if(v2 == algraph.vex[j].data) n = j;
}
p = (Arcnode *)malloc(sizeof(Arcnode));
p->adjvex = n;p->weight = w;
p->nextarc = algraph.vex[m].firarc;algraph.vex[m].firarc = p;
}
}
} //构造完成
template <class TElemType>
void Graph<TElemType>::DestroyAlgraph()
{
int i;
Arcnode *p,*q;
for(i = 0;i < algraph.vexnum;i++)
{
p = algraph.vex[i].firarc;
if(p)
{
q = p->nextarc;
while(q)
{
free(p);
p = q;
q = q->nextarc;
}
free(p);
}
}
free(algraph.vex);
}
template <class TElemType>
void Graph<TElemType>::CreateOlgraph()
{
int i,j,m,n;
float w;
TElemType v1,v2;
ArcBox *p;
cout << “输入有向图的顶点数和边数:” << endl;
cin >> olgraph.vexnum >> olgraph.arcnum;
olgraph.vex = (Vertex<TElemType> *)malloc(olgraph.vexnum * sizeof(Vertex<TElemType>));
cout << “输入顶点的信息:” << endl;
for(i = 0;i < olgraph.vexnum;i++)
{
cin >> olgraph.vex[i].data;
olgraph.vex[i].firstin = olgraph.vex[i].firstout = NULL;
}
cout << “输入各边的弧尾与弧头结点及有向边的权值:” << endl;
for(i = 0;i < olgraph.arcnum;i++)
{
cin >> v1 >> v2 >> w;
for(j = 0;j < olgraph.vexnum;j++)
{
if(v1 == olgraph.vex[j].data) m = j;
if(v2 == olgraph.vex[j].data) n = j;
}
p = (ArcBox *)malloc(sizeof(ArcBox));
p->headvex = n;p->tailvex = m;
p->weight = w;
p->hlink = olgraph.vex[n].firstin;olgraph.vex[n].firstin = p;
p->tlink = olgraph.vex[m].firstout;olgraph.vex[m].firstout = p;
}
} //end CreateOlgraph
template <class TElemType>
void Graph<TElemType>::DestroyOlgraph()
{
int i;
ArcBox *p,*q;
for(i = 0;i < olgraph.vexnum;i++)
{
p = olgraph.vex[i].firstout;
if(p)
{
q = p->tlink;
while(q)
{
free(p);
p = q;
q = q->tlink;
}
free(p);
}
}
free(olgraph.vex);
}
template <class TElemType>
void Graph<TElemType>::DFS(int v,bool *visited)
{
cout << algraph.vex[v].data << endl;
visited[v] = true;
Arcnode *p;
int v1;
for(p = algraph.vex[v].firarc;p;p = p->nextarc)
{
v1 = p->adjvex;
if(!visited[v1]) DFS(v1,visited);
}
}
template <class TElemType>
void Graph<TElemType>::DFSTraverse()
{
int i,v;
bool *visited = (bool *)malloc(algraph.vexnum * sizeof(bool));
for(i = 0;i < algraph.vexnum;i++)
visited[i] = false;
for(v = 0;v < algraph.vexnum;v++)
if(!visited[v]) DFS(v,visited);
free(visited);
} //EndDFSTraverse
template <class TElemType>
void Graph<TElemType>::BFSTraverse()
{
Lqueue<int> Lq;
Lq.InitQueue();
Arcnode *p;
bool *visited = (bool *)malloc(algraph.vexnum * sizeof(bool));
int v1;
for(int i = 0;i < algraph.vexnum;i++)
visited[i] = false;
for(int v = 0;v < algraph.vexnum;v++)
{
if(!visited[v])
{
cout << algraph.vex[v].data << endl;
visited[v] = true;
Lq.EnQueue(v);
while(!Lq.QueueEmpty())
{
Lq.DeQueue(v1);
for(p = algraph.vex[v1].firarc;p;p = p->nextarc)
{
v1 = p->adjvex;
if(!visited[v1])
{
cout << algraph.vex[v1].data << endl;
visited[v1] = true;
Lq.EnQueue(v1);
}
}
}
}
}
Lq.ClearQueue();
free(visited);
} //EndBFSTraverse
template <class TElemType>
void Graph<TElemType>::DFSForest(Treenode<TElemType> *&T)
{
Treenode<TElemType> *q,*r;
T = NULL;
int v;
bool *visited = (bool *)malloc(algraph.vexnum * sizeof(bool));
for(int i = 0;i < algraph.vexnum;i++)
visited[i] = false;
for(v = 0;v < algraph.vexnum;v++)
{
if(!visited[v])
{
visited[v] = true;
r = (Treenode<TElemType> *)malloc(sizeof(Treenode<TElemType>));
r->data = algraph.vex[v].data;
r->lchild = r->nextsibling = NULL;
if(!T) T = r;
else q->nextsibling = r;
q = r;
DFSTree(v,r,visited);
}
}
free(visited);
}
template <class TElemType>
void Graph<TElemType>::DFSTree(int v,Treenode<TElemType> *&T,bool *visited)
{
Arcnode *w;
Treenode<TElemType> *p,*q;
int v1;
bool first = true;
for(w = algraph.vex[v].firarc;w;w = w->nextarc)
{
v1 = w->adjvex;
if(!visited[v1])
{
visited[v1] = true;
p = (Treenode<TElemType> *)malloc(sizeof(Treenode<TElemType>));
p->data = algraph.vex[v1].data;
p->lchild = p->nextsibling = NULL;
if(first) {T->lchild = p;first = false;}
else q->nextsibling = p;
q = p;
DFSTree(v1,p,visited);
}
}
} //EndDFSTree
template <class TElemType>
void Graph<TElemType>::PreDFSForest(Treenode<TElemType> *T)
{
if(T)
{
cout << T->data << ” “;
PreDFSForest(T->lchild);
PreDFSForest(T->nextsibling);
}
}
template <class TElemType>
void Graph<TElemType>::DFSOlgraph(int v,bool *visited,int *finished)
{
ArcBox *p;
int v1;
visited[v] = true;
for(p = olgraph.vex[v].firstout;p;p = p->tlink)
{
v1 = p->headvex;
if(!visited[v1])
DFSOlgraph(v1,visited,finished);
}
finished[count++] = v;
}
template <class TElemType>
void Graph<TElemType>::DFSOlgraph(int v,bool *visited)
{
ArcBox *p;
int v1;
visited[v] = true;
cout << olgraph.vex[v].data << ” “;
for(p = olgraph.vex[v].firstin;p;p = p->hlink)
{
v1 = p->tailvex;
if(!visited[v1])
DFSOlgraph(v1,visited);
}
}
template <class TElemType>
void Graph<TElemType>::Conponderance()
{
int v;
count = 0;
bool *visited = (bool *)malloc(olgraph.vexnum * sizeof(bool));
int *finished = (int *)malloc(olgraph.vexnum * sizeof(int));
for(int i = 0;i < olgraph.vexnum;i++)
{visited[i] = false;finished[i] = -1;}
for(v = 0;v < olgraph.vexnum;v++)
{
if(!visited[v])
{
visited[v] = true;
DFSOlgraph(v,visited,finished);
}
}
for(i = 0;i < olgraph.vexnum;i++) visited[i] = false;
cout << “强连通分量如下:” << endl;
for(i = olgraph.vexnum-1; i >= 0;i–)
{
v = finished[i];
if(!visited[v])
{
DFSOlgraph(v,visited);
cout << endl;
}
}
free(visited);
free(finished);
}
template <class TElemType>
void Graph<TElemType>::Minispantree_prim()
{
struct closedge
{
int adjvex;
int lowcost;
};
closedge *edge = (closedge *)malloc(gph.vexnum * sizeof(closedge));
int i,j,k = 0,u;
int min;
for(i = 0;i < gph.vexnum;i++)
{
if(i != k)
{
edge[i].adjvex = 0;
edge[i].lowcost = gph.AdjMatrix[k][i];
}
}
edge[k].lowcost = 0;
cout << “最小生成树的边如下:” << endl;
for(i = 1;i < gph.vexnum;i++)
{
min = INT_MAX;
for(j = 0;j < gph.vexnum;j++)
if(edge[j].lowcost != INT_MAX &&edge[j].lowcost != 0 && edge[j].lowcost < min)
{
min = edge[j].lowcost;
k = j;
}
u = edge[k].adjvex;
edge[k].lowcost = 0;
cout << “(” << gph.vertex[u] << “,” << gph.vertex[k] << “)” << ” “;
for(j = 0;j < gph.vexnum;j++)
if(gph.AdjMatrix[j][k] < edge[j].lowcost)
{
edge[j].lowcost = gph.AdjMatrix[j][k];
edge[j].adjvex = k;
}
}
free(edge);
cout << endl;
}
template <class TElemType>
void Graph<TElemType>::DFSAlgraph(int v,int *low,int *visited)
{
int min;
bool flag = true;
visited[v] = min = ++count;
Arcnode *p;
int v1;
for(p = algraph.vex[v].firarc;p;p = p->nextarc)
{
v1 = p->adjvex;
if(!visited[v1])
{
DFSAlgraph(v1,low,visited);
if(low[v1] < min) min = low[v1];
if(low[v1] >= visited[v] && flag == true && v != 0) {cout << algraph.vex[v].data << ” “;flag = false;}
}
else if(visited[v1] < min) min = visited[v1];
}
low[v] = min;
}
template <class TElemType>
void Graph<TElemType>::DFSAlgraph(int v,int *visited)
{
count++;
visited[v] = count;
Arcnode *p;
int v1;
for(p = algraph.vex[v].firarc;p;p = p->nextarc)
{
v1 = p->adjvex;
if(!visited[v1]) DFSAlgraph(v1,visited);
}
}
template <class TElemType>
void Graph<TElemType>::FindCritic()
{
count = 0;
Arcnode *p;
int v;
int *visited = (int *)malloc(algraph.vexnum * sizeof(int));
int *low = (int *)malloc(algraph.vexnum * sizeof(int));
for(int i = 0;i < algraph.vexnum;i++)
visited[i] = 0;
cout << “关节点如下:” << endl;
DFSAlgraph(0,low,visited);
for(i = 1;i < algraph.vexnum;i++)
visited[i] = 0;
visited[0] = 1;
count = 1;
p = algraph.vex[0].firarc;v = p->adjvex;
DFSAlgraph(v,visited);
if(count < algraph.vexnum) cout << algraph.vex[0].data;
cout << endl;
free(visited);
free(low);
}
template <class TElemType>
void Graph<TElemType>::TopologicalSort()
{
stack<int> topo;
topo.InitStack();
int count = 0;
int *indegree = (int *)malloc(algraph.vexnum * sizeof(int));
int i,v,v1;
Arcnode *p;
for(i = 0;i < algraph.vexnum;i++) indegree[i] = 0;
for(i = 0;i < algraph.vexnum;i++)
for(p = algraph.vex[i].firarc;p;p = p->nextarc)
{
v = p->adjvex;
indegree[v]++;
}
for(i = 0;i < algraph.vexnum;i++)
if(indegree[i] == 0) topo.Push(i);
while(!topo.StackEmpty())
{
topo.Pop(v);
count++;
cout << algraph.vex[v].data << ” “;
for(p = algraph.vex[v].firarc;p;p = p->nextarc)
{
v1 = p->adjvex;
if(0 == –indegree[v1]) topo.Push(v1);
}
}
if(count < algraph.vexnum) cout << “有向图中存在环” << endl;
free(indegree);
topo.DestroyStack();
}
template <class TElemType>
float * Graph<TElemType>::TopologicalOrder(stack<int> &sre,int &e)
{
stack<int> topo;
topo.InitStack();
sre.InitStack();
float *re = (float *)malloc(algraph.vexnum * sizeof(float));
int *indegree = (int *)malloc(algraph.vexnum * sizeof(int));
int i,v,v1,count = 0;
for(i = 0;i < algraph.vexnum;i++) re[i] = 0;
Arcnode *p;
for(i = 0;i < algraph.vexnum;i++) indegree[i] = 0;
for(i = 0;i < algraph.vexnum;i++)
for(p = algraph.vex[i].firarc;p;p = p->nextarc)
{
v = p->adjvex;
indegree[v]++;
}
for(i = 0;i < algraph.vexnum;i++)
if(indegree[i] == 0) topo.Push(i);
while(!topo.StackEmpty())
{
topo.Pop(v);
sre.Push(v);
count++;
for(p = algraph.vex[v].firarc;p;p = p->nextarc)
{
v1 = p->adjvex;
if(0 == –indegree[v1]) topo.Push(v1);
if(re[v] + p->weight > re[v1]) re[v1] = re[v] + p->weight;
}
}
e = v;
topo.DestroyStack();
if(count < algraph.vexnum) return NULL;
return re;
}
template <class TElemType>
void Graph<TElemType>::Criticalpath()
{
float *rl = (float *)malloc(algraph.vexnum * sizeof(float));
stack<int> sre;
int e;
float *re = TopologicalOrder(sre,e);
if(re)
{
int i,v,v1;
Arcnode *p;
for(i = 0;i < algraph.vexnum;i++) rl[i] = re[e];
while(!sre.StackEmpty())
{
sre.Pop(v);
for(p = algraph.vex[v].firarc;p;p = p->nextarc)
{
v1 = p->adjvex;
if(rl[v1] – p->weight < rl[v]) rl[v] = rl[v1] – p->weight;
}
}
cout << “关键路径如下:” << endl;
for(i = 0;i < algraph.vexnum;i++)
for(p = algraph.vex[i].firarc;p;p = p->nextarc)
{
v1 = p->adjvex;
if(rl[v1]-p->weight == re[i]) cout << “(” << algraph.vex[i].data << “,” << algraph.vex[v1].data << “) “;
}
cout << endl;
free(re);
}
else cout << “有向图中存在环,不合要求!” << endl;
free(rl);
sre.DestroyStack();
}
template <class TElemType>
void Graph<TElemType>::Shortestpath_DIJ(TElemType data1,TElemType data2)
{
int i,j,v,u,k,min;
stack<int> S;
S.InitStack();
int *spath = (int *)malloc(gph.vexnum * sizeof(int));
int *pathrecord = (int *)malloc(gph.vexnum * sizeof(int));
bool *visited = (bool *)malloc(gph.vexnum * sizeof(bool));
for(i = 0;i < gph.vexnum;i++) visited[i] = false;
for(i = 0;i < gph.vexnum;i++)
{
if(data1 == gph.vertex[i]) v = i;
if(data2 == gph.vertex[i]) u = i;
}
for(i = 0;i < gph.vexnum;i++)
{
spath[i] = gph.AdjMatrix[v][i];
pathrecord[i] = v;
}
spath[v] = 0;visited[v] = true;pathrecord[v] = -1;
for(i = 1;i < gph.vexnum;i++)
{
min = INT_MAX;
for(j = 0;j < gph.vexnum;j++)
{
if(!visited[j])
{
if(spath[j] < min) {min = spath[j];k = j;}
}
}
visited[k] = true;
for(j = 0;j < gph.vexnum;j++)
if(!visited[j] && gph.AdjMatrix[k][j] < INT_MAX && spath[k]+gph.AdjMatrix[k][j] < spath[j])
{
spath[j] = spath[k]+gph.AdjMatrix[k][j];
pathrecord[j] = k;
}
}
free(visited);
cout << spath[u] << endl;
S.Push(u);
for(v = pathrecord[u];v != -1;v = pathrecord[v])
S.Push(v);
while(!S.StackEmpty())
{
S.Pop(i);
cout << gph.vertex[i] << ” “;
}
cout << endl;
S.DestroyStack();
free(spath);
free(pathrecord);
}
template <class TElemType>
void Graph<TElemType>::Shortestpath_FLOYD(TElemType data1,TElemType data2)
{
int i,j,k,v,u,m;
int **D = (int **)malloc(gph.vexnum * sizeof(int *));
bool ***path = (bool ***)malloc(gph.vexnum * sizeof(bool **));
for(i = 0;i < gph.vexnum;i++)
{
D[i] = (int *)malloc(gph.vexnum * sizeof(int));
path[i] = (bool **)malloc(gph.vexnum * sizeof(bool *));
if(data1 == gph.vertex[i]) v = i;
if(data2 == gph.vertex[i]) u = i;
}
for(i = 0;i < gph.vexnum;i++)
for(j = 0;j < gph.vexnum;j++)
path[i][j] = (bool *)malloc(gph.vexnum *sizeof(bool));
for(i = 0;i < gph.vexnum;i++)
for(j = 0;j < gph.vexnum;j++)
{
D[i][j] = gph.AdjMatrix[i][j];
for(k = 0;k < gph.vexnum;k++)
path[i][j][k] = false;
if(D[i][j] < INT_MAX)
{
path[i][j][i] = true;path[i][j][j] = true;
}
}
for(k = 0;k < gph.vexnum;k++)
for(i = 0;i < gph.vexnum;i++)
for(j = 0;j < gph.vexnum;j++)
if(D[i][k] != INT_MAX && D[k][j] != INT_MAX && D[i][k]+D[k][j] < D[i][j])
{
D[i][j] = D[i][k] + D[k][j];
for(m = 0;m < gph.vexnum;m++)
path[i][j][m] = path[i][k][m] || path[k][j][m];
}
cout << “从” << gph.vertex[v] << “到” << gph.vertex[u] << “的最短路径及经过的点如下:” << endl;
cout << D[v][u] << endl;
for(i = 0;i < gph.vexnum;i++)
if(path[v][u][i] == true) cout << i << ” “;
cout << endl;
for(i = 0;i < gph.vexnum;i++)
{
free(D[i]);
free(path[i]);
}
free(D);
free(path);
}
#endif
//***********end
//****Lqueue.h
#ifndef _LQUEUE_H
#define _LQUEUE_H
#define MAXQSIZE 100
typedef int Status;
template <class QElemType>
class Lqueue
{
public:
void InitQueue();
void DestroyQueue();
void ClearQueue();
Status QueueEmpty();
Status QueueLength();
void GetHead(QElemType & e);
void EnQueue(QElemType e);
void DeQueue(QElemType & e);
private:
struct SqQueue
{
QElemType * base;
int front;
int rear;
};
SqQueue Q;
};
//********Lqueue.cpp********
template <class QElemType>
void Lqueue<QElemType>::InitQueue()
{
Q.base = (QElemType *)malloc(MAXQSIZE * sizeof(QElemType));
if(!Q.base) exit(0);
Q.front = Q.rear = 0;
}
template <class QElemType>
void Lqueue<QElemType>::DestroyQueue()
{
free(Q.base);
}
template <class QElemType>
void Lqueue<QElemType>::ClearQueue()
{
Q.front = Q.rear = 0;
}
template <class QElemType>
Status Lqueue<QElemType>::QueueEmpty()
{
if(Q.front == Q.rear) return 1;
return 0;
}
template <class QElemType>
Status Lqueue<QElemType>::QueueLength()
{
return (Q.rear – Q.front + MAXQSIZE)%MAXQSIZE;
}
template <class QElemType>
void Lqueue<QElemType>::GetHead(QElemType & e)
{
if(Q.front == Q.rear) cout << “ERROR” << endl;
else
{
e = Q.base[Q.front];
}
}
template <class QElemType>
void Lqueue<QElemType>::EnQueue(QElemType e)
{
if((Q.rear + 1)%MAXQSIZE == Q.front) cout << “ERROR” << endl;
else
{
Q.base[Q.rear] = e;
Q.rear = (Q.rear + 1)%MAXQSIZE;
}
}
template <class QElemType>
void Lqueue<QElemType>::DeQueue(QElemType & e)
{
if(Q.front == Q.rear) cout << “ERROR” << endl;
else
{
e = Q.base[Q.front];
Q.front = (Q.front + 1)%MAXQSIZE;
}
}
//******************Lqueue.cpp***************
#endif //*****Lqueue.h********
//*****stack.h
#ifndef _STACK_H
#define _STACK_H
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
typedef int Status;
template<class QElemType>
class stack
{
public:
void InitStack();
void DestroyStack();
void ClearStack();
Status StackEmpty();
Status StackLength();
void GetTop(QElemType & e);
void Push(QElemType e);
void Pop(QElemType & e);
private:
struct SqStack{
QElemType *base;
QElemType *top;
int stacksize;
}S;
};
//******stack.cpp——
template<class QElemType>
void stack<QElemType>::InitStack()
{
S.base = (QElemType *)malloc(STACK_INIT_SIZE * sizeof(QElemType));
if(!S.base) exit(0);
S.top = S.base;
S.stacksize = STACK_INIT_SIZE;
}
template <class QElemType>
void stack<QElemType>::DestroyStack()
{
free(S.base);
}
template <class QElemType>
void stack<QElemType>::ClearStack()
{
S.top = S.base;
}
template <class QElemType>
Status stack<QElemType>::StackEmpty()
{
if(S.top == S.base) return 1;
else return 0;
}
template <class QElemType>
Status stack<QElemType>::StackLength()
{
return (S.top – S.base);
}
template <class QElemType>
void stack<QElemType>::GetTop(QElemType & e)
{
if(S.top != S.base)
e = *(S.top – 1);
else cout << “ERROR” << endl;
}
template <class QElemType>
void stack<QElemType>::Push(QElemType e)
{
if(S.top – S.base >= S.stacksize)
{
S.base = (QElemType *)realloc(S.base,(S.stacksize + STACKINCREMENT) * sizeof(QElemType));
if(!S.base) exit(0);
S.top = S.base + S.stacksize;
S.stacksize += STACKINCREMENT;
}
*S.top++ = e;
}
template <class QElemType>
void stack<QElemType>::Pop(QElemType & e)
{
if(S.top == S.base) cout << “ERROR” << endl;
else
e = * –S.top;
}
//**********stack.cpp
#endif //stack.h ****
#include <iostream>
#include “Graph.h”
using namespace std;
int main()
{
/*Graph<int> gph;
gph.CreateDN();
int a,b;
cout << “输入终点和起点:”;
cin >> a >> b;
gph.Shortestpath_DIJ(a,b);
gph.DestroyDN();
return 0;*/
Graph<int> gph;
gph.CreateAlgraph();
gph.Criticalpath();
gph.DestroyAlgraph();
return 0;
}