图功能的实现C++(最短路径,关键路径,拓扑排序,关节点,~~~~~~~~~~等等)

先按照注释的提示新建三个头文件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;
}

    原文作者:拓扑排序
    原文地址: https://blog.csdn.net/chenjian_0704/article/details/4662667
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞