拓扑排序是对一个有向图构造拓扑序列,解决工程是否能顺利进行的问题。构造时有 2 种结果:
此图全部顶点被输出:说明说明图中无「环」存在, 是 AOV 网
没有输出全部顶点:说明图中有「环」存在,不是 AOV 网
AOV(Activity On Vertex Network) :一种 有向 无回路 的图
代码实现如下:
首先建立图的邻接表类型(当然邻接矩阵也行):
const int MAXV = 1000;
typedef struct ANode {
int adjvex;//该边结点的编号
struct ANode* nextarc;//指向下一个边结点
int weight;//该边结点的其他信息,如权重等
}ArcNode;//边结点类型
typedef struct Vnode {
int count;//该边结点的入度值,即前面有几个顶点进入该结点
ArcNode* firstarc;//指向第一个边结点
}VNode;//邻接表的头结点类型
typedef struct {
VNode adjlist[MAXV];//邻接表的头结点数组
int n, e;//顶点数n和边数e
}AdjGraph;//邻接表类型
以下就是拓扑排序算法:
基本思路是把没有前驱顶点的点入栈,然后一个一个出栈,出栈的同时改变其他入度不为0的点,并把新的入度为0的顶点入栈,直到栈空为止!
void Topsort(AdjGraph*G)//拓扑排序算法
{
int i, j;
int St[MAXV], top = -1;//St为存放入度为0的栈,初始化时top为-1
ArcNode* p;
for (i = 0;i < G->n;i++)
G->adjlist[i].count = 0;//把所有头结点的入度值初始化为0
for (i = 0;i < G->n;i++)//求所有顶点的入度
{
p = G->adjlist[i].firstarc;
while (p != NULL)
{
G->adjlist[p->adjvex].count++;
p = p->nextarc;
}
}
for(i=0;i<G->n;i++)//把入度为0的结点进栈
if (G->adjlist[i].count == 0)
{
top++;
St[top] = i;
}
while (top > -1)//栈不空进行循环
{
i = St[top];top--;//出栈第一个顶点
cout << i << " ";
p = G->adjlist[i].firstarc;//找到第一个邻接点
while (p != NULL)//将顶点i的出边邻接点入度减一
{
j = p->adjvex;
G->adjlist[i].count--;//那么第一个使用的点变成-1,再也不需要用它了
if (G->adjlist[j].count == 0)//把改变入度后入度为0的点入栈
{
top++;
St[top] = j;
}
p = p->nextarc;//找下一个邻接点直到该条邻接表结束为止
}
}
}