描述:
在有向无环图,顶点之间存在先后关系,遍历某个顶点前必须前遍历其前驱顶点。
拓扑排序一般应用于计划的安排:完成一项任务后才可进行下一项。
思路:
输出图中入度为0的顶点,并记录其下标,之后删除该顶点所连接的弧,重复这个过程直到图中找不到入度为0的顶点为止。
如果执行完算法后图中还有顶点没有输出,则说明图中存在环,输出错误信息。
代码:
//图结构的定义
typedef struct AMGraph
{
int vex[ARRAYSIZE]={0};//顶点数组
int arc[ARRAYSIZE][ARRAYSIZE];//邻接矩阵,表示顶点之间的关系
int vexnum=0,arcnum=0;//顶点个数和弧个数
int type=0;//1表示无向图,2表示有向图,3表示无向网,4表示有向网
}AMGraph;
int GetInDegree(AMGraph &G,int e);//求顶点的入度
//拓扑排序
void topo_sort(AMGraph &G)
{
int num=-1;//用于表示当前顶点的下标
set<int> record;//用于记录已处理的顶点的下标的容器
//寻找入度为0的顶点
for(int i=0;i<G.vexnum;i++)
{
if(GetInDegree(G,G.vex[i])==0)
num=i;
}
int n=record.size();
while(num!=-1 && n!=G.vexnum)
{
cout << G.vex[num] << endl;
record.insert(num);//记录已处理的顶点的下标
//删除该顶点所连接的弧
for(int i=0;i<G.vexnum;i++)
{
if(G.type==2)
G.arc[num][i]=0;
else if(G.type==4)
G.arc[num][i]=INT_MAX;
}
num=-1;
//寻找入度为0的顶点
for(int i=0;i<G.vexnum;i++)
{
//检测第i个顶点是否已处理过,有则continue
if(record.find(i)==record.end())
{
if(GetInDegree(G,G.vex[i])==0)
{
num=i;
break;
}
}
else continue;
}
}
if(n!=G.vexnum)//退出循环后若图中还有顶点未输出,说明图中存在环
{
cout << "出错!图中存在环" << endl;
}
}