适用于排课系统开发的拓扑排序

对有向图进行拓扑排序的方法(可运用的排课等):

(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;
}

原文地址:https://www.cnblogs.com/mingforyou/p/2225549.html