在图中用顶点表示活动,用弧表示活动间的优先关系,这样的有向图成为AOV网。
下面是AOV网的拓扑排序,可以用来检验类似:工程之间有约束关系的,检验看工程的安排是否合理;课程之间有约束的,课程的前后顺序安排是否合理,这就是拓扑排序的一个应用。
文件"topo.h"
#include<iostream>
#include<string>
#include<queue>
using namespace std;
const int MAX_VEX_NUM=20;
class ArcNode //表结点
{
public:
int adjvex;
ArcNode *nextarc;
};
class VNode //头结点
{
public:
string data;
int indegree;
ArcNode *firstarc;
};
class ALGraph
{
private:
VNode vertices[MAX_VEX_NUM];
int arcnum;
int vexnum;
public:
void Create_ALG()
{
//构造有向图
string v1,v2;
int i,j;
ArcNode *p=NULL;
cout<<"输入顶点数和边数:";
cin>>vexnum>>arcnum;
cout<<"输入顶点名称:";
for(i=0;i<vexnum;i++)
{
cin>>vertices[i].data;
vertices[i].firstarc=NULL;
vertices[i].indegree=0;
}
for(int k=0;k<arcnum;k++)
{
cout<<"按照尾->头的顺序输入每条边对应的两个顶点:";
cin>>v1>>v2;
i=Locate_Vex(v1);
j=Locate_Vex(v2);
while(i==-1 || j==-1)
{
cout<<"输入的顶点错误,重新输入:";
cin>>v1>>v2;
i=Locate_Vex(v1);
j=Locate_Vex(v2);
}
p=new ArcNode;
p->adjvex=j;
p->nextarc=vertices[i].firstarc;
vertices[i].firstarc=p;
vertices[j].indegree+=1; //作为有向弧的头的顶点入度加1
}
cout<<"图构造完成"<<endl;
}
int Locate_Vex(string v)
{
for(int k=0;k<vexnum && vertices[k].data!=v;k++);
if(k<vexnum)
return k;
else
return -1;
}
/*拓扑排序*/
/*------------------------------------------------
/ 对AOV网进行拓扑排序的方法是:
/ (1)在有向图中选取一个没有前驱的顶点,将其输出
/ (2)从图中删除该顶点和所有以他为尾的弧
/ 重复上述2个步骤,若有向图中全部顶点都被输出,则
/ 該图不存在环,否则,該图存在有向环路。
/ 为了实现以上操作,可增加一个记录顶点入度的数据成员,
/ 每个顶点的入度随着顶点的输出动态变化,入度为0即
/ 该顶点没有前驱,删除以该顶点为尾的弧也可以通过将
/ 与之相连的顶点的入度都减少1即可。为了减少重复检测
/ 入度为0的结点,这里借助队列来装入度为0的顶点,在队列
/ 非空时进行入度为0的顶点的出入队和输出,详细操作看代码
/------------------------------------------------*/
void Topo_Sort()
{
queue<int> s;
ArcNode *p=NULL;
for(int i=0;i<vexnum;i++)
if(!vertices[i].indegree)
s.push(i);
int count=0;
while(!s.empty())
{
int k=s.front();
s.pop();
cout<<vertices[k].data<<" ";
count++;
for(p=vertices[k].firstarc;p;p=p->nextarc)
{
int w=p->adjvex;
if(vertices[w].indegree)
vertices[w].indegree--;
if(!vertices[w].indegree)
s.push(w);
}
}
if(count<vexnum)
cout<<"图中含有有向环"<<endl;
}
};
主函数"main.cpp"
#include"topo.h"
int main()
{
ALGraph G;
G.Create_ALG();
cout<<"拓扑排序为:";
G.Topo_Sort();
cout<<endl;
return 0;
}
测试结果:
输入顶点数和边数:5 6
输入顶点名称:v1 v2 v3 v4 v5
按照尾->头的顺序输入每条边对应的两个顶点:v3 v5
按照尾->头的顺序输入每条边对应的两个顶点:v3 v1
按照尾->头的顺序输入每条边对应的两个顶点:v4 v5
按照尾->头的顺序输入每条边对应的两个顶点:v4 v2
按照尾->头的顺序输入每条边对应的两个顶点:v2 v1
按照尾->头的顺序输入每条边对应的两个顶点:v1 v5
图构造完成
拓扑排序为:v3 v4 v2 v1 v5
Press any key to continue
按照输入生成的有向图如下:

2468

被折叠的 条评论
为什么被折叠?



