适用于排课系统开发的拓扑排序
对有向图进行拓扑排序的方法(可运用的排课等):
(1)初始时拓扑序列为空间;
(2)任意选择一个入度为0的顶点,将其放入拓扑序列中,同时从图中删除该顶点以及从该顶点出发的弧形;
(3)重复(2),直到不存在入度为0的顶点为止(若所有顶点都进入拓扑序列返回则完成拓扑排序,否则由于有向图中存在回路无法完成拓扑排序)。
#define MAXVNUM 50 //最在顶点数
typedef struct ArcNode{ //表节点类型
int adjvex; //邻接顶点编号
struct ArcNode *nextarc; //指示下一邻接顶点
}ArcNode;
typedef struct AdjList{ //头节点类型
char vdata; //顶点的数据信息
ArcNode *firstarc; //指向邻接表的第一个表结点
}
typedef struct LinkedDigraph{ //图的类型
int n; //图中顶点个数
AdjList Vhead[MAXVNUM]; //所有顶点的头结点数组
}LinkedDiagraph;
int *TopSort(LinkedDigraph G){
ArcNode *p; //临时指针,指示表结点
Queue Q; //临时队列,保存入度为0的顶点编号
int d=0; //临时变量,用作数组元素的下标
int j=0,w=0; //临时变量,用作顶点编号
int *topOrder,*inDegree;
topOrder=(int *)malloc((G.n+1)*sizeof(int));//存储拓扑序列中的顶点编号
inDegree=(int *)malloc((G.n+1)*sizeof(int));//存储图G中各顶点的入度
if(!inDegree || !topOrder){
return null;
}
InitQueue(&Q); //构造一个空队列
for(j=1;j<=G.n;j++){ //初始化
topOrder[j]=0;
inDegree[j]=0;
}
for(j=1;j<=G.n;j++){ //求图G中各顶点的入度
for(p=G.Vhead[j].firststarc;p;p=p->nextarc){
inDegree[p->adjvex]+=1;
}
}
for(j=1;j<G.n;j++){ //将图G中入度为0的顶点保存在队列中
if(0==inDegree[j]
EnQueue(&Q,j);
}
while(!IsEmpty(Q)){
DeQueue(&Q,&w); //队头顶点出队列并用w保存该顶点的编号
topOrder[k+1]=w; //将顶点w的所有邻接顶点的入度减1(模拟删除顶点w及从该顶点出发的弧的操作)
for(p=G.Vhead[j].firstarc;p;p=p->nextarc){
inDegree[p->adjvex]-=1;
if(0==inDegree[p->adjbex])
EnQueue(&Q,p->adjvex);
}
}
free(inDegree);
if(k!=G.n)
return NULL;
return topOrder;
}