拓扑排序
紧接着之前的无向图的最小生成树,接下来是对于无向图的拓扑排序的实现。
拓扑排序的本质就是在有向图中寻找一个不重复的输出所有顶点的顺序
那么它有一下的几点特征
- 一个有向图的拓扑排序不一定唯一;
- 一个有向无环图一定存在拓扑排序;
- 一个有向右环图一定不存在拓扑排序;
- 可以通过拓扑排序判断一个 AOV网络是否有环;
算法思路如下:
- 将入度为0的顶点输出;
- 将入度为0的节点删去其顶点以及所有的出边;
- 重复1,2知道所有的点都输出或者剩下的点的入度都不为0;
数据结构如下:
typedef struct VexNode{
int in;//入度域
int data;
EdgeNode firstedge;//第一条边
}VexNode;
typedef struct EdgeNode{
int vex;
int weight;
EdgeNode *next;
}EdgeNode;
typedef struct Mgraph{
VexNode Vertexs[MAX];
int vexnum,edgenum;
}Mgraph;
那么对于这样的一个图它的存储结构为
算法流程
- 申请一个栈用来存储,当前未输出的入度为0的点;
- 首先遍历一遍顶点数组初始化栈;
- 之后输出顶点的个数不为顶点总数且栈不为空的时候继续循环;
- 栈顶出栈,输出出栈的节点,并根据其所对应的边表将与其邻接的顶点的入度减一,若此时入度为0则仅栈;
- 循环结束后,若计数器中的值为顶点的总数则表明生成拓扑序列成功,否则失败;
代码如下:
int Toposort(Mgraph *G){
int counter=0;
VexNode *e;
int top=0,gettop,k;
int *stack=(int *)malloc(G->vexnum*sizeof(int));
for(i=0;i<G->vexnum;i++){
if (G->vertexs[i].in==0){
stack[++top]=i;
}
}
while (top!=0){
gettop=stack[top];
top—-;
printf(“%d->”,G->vertexs[gettop].data);
counter++;
for (e=G->vertexs[gettop].firstedge;e;e=e->next)
k=e->vex;
G->vertexs[k]->in-=1;
if (k==0){
stack[++top]=k;
}
}
if (counter==G->vexnum){
printf(“ok”);
}
else
printf(“error”);
}