算法思想:
设u是v的祖先,则调用DFS访问u的过程中,必然会在这个过程结束之前递归地对v进行调用,即v的DFS函数结束时间先于u的结束时间。
从而可以考虑DFS调用过程设置一个时间标记,在DFS调用结束时,对各定点计时,因此,祖先的结束时间必然大于子孙的结束时间。
1.采用深度优先搜索,初始化标记是否访问的数组visited,初始化表示结束时间的数组finishtime。设置变量time表示该顶点结束时间,初始化为0.
2.对边表结点进行深度优先搜索遍历,遍历结束后,对总时间进行更新,同时保存当前遍历节点的时间。
3.按照结束时间从大到小,得到拓扑序列。
#include<stdio.h>
#include<malloc.h>
#define maxnum 1000
//边表结点
typedef struct ArcNode{
int adjvex;
int info//权值
struct ArcNode *next;
}ArcNode
//顶点表节点
typedef struct VNode{
int data;
struct ArcNode *firstarc;
}VNode;
typedef struct{
int adjlist[MaxSize];
int n,e;
}
void dfs(AGraph *g, int v, int visited[], int *time,int finishedtime[])
{
visited[v] = 1;
ArcNode *p = g->adjlist[v].firstarc;
while(p!=NULL){
if(visited[p->adjvex]==0){
dfs(g,p->adjvex,visited,time,finishedtime);
}
p = p->next;
}
time++;
finishedtime[time] = v;
}
void TopoOrder(Agraph *g){
int finished[g->n], visited[g->n] = {0};
int time = 0;
for(int i = 0;i<g->n;i++){
if(visited[i]==0)
dfs(g,i,visited,&time,finishedtime);
}
int max = 0;
for(int i = 0;i<g->n;i++)
{
for(int j = 0;j<g->n;j++)
if(finishedtime[j] >= finishedtime[max])
max = j;
printf("%d ",max);
finishedtime[max] = -1;
}
}