#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#define MVEX 10
#define size sizeof(Arcnode)
#define queue_length 10
typedef struct Arcnode
{
int name;
struct Arcnode * next_arcnode;
// int info //节点的其他信息 譬如权重
}Arcnode;
typedef struct
{
int name;
Arcnode * next_arcnode;
}List[MVEX];
typedef struct
{
int vexnum, arcnum;
List L;
}Graph;
// 以上是建立图
typedef struct
{
int *base;
int head, tail, length;
}Queue; //建立队列
void Creat_Graph(Graph * G) //构建一个邻接链表 来存储
{
int i, j, m, n, k;
Arcnode * p, *q;
scanf("%d %d", &G->vexnum, &G->arcnum);
for(i = 0; i < G->vexnum; i++){
G->L[i].name = i;
G->L[i].next_arcnode = NULL;
}
for(i = 0; i < G->arcnum; i++){
scanf("%d %d", &m, &n);
p = (Arcnode *)malloc(size);
p->next_arcnode = G->L[m].next_arcnode;
p->name = n;
G->L[m].next_arcnode = p;
}
}
void InitStack(Queue * Q) //初始化一个队列
{
Q->base = (int *)malloc(queue_length);
if(!Q->base) exit(5);
Q->head = Q->tail = 0;
}
int Pop(Queue * Q) //出队列
{
int temp;
if(Q->head == Q->tail) exit(6);
temp = Q->base[Q->head++];
return temp;
}
void Push(Queue * Q, int i) //入队列
{
if(Q->tail - Q->head > Q->length) exit(7);
Q->base[Q->tail++] = i;
}
void FindInDegree(Graph G, int indegree[]) //把每个节点对应的入度存储到 indegree数组里
{
int i, k, mark_num = 0;
Arcnode * temp;
for(i = 0; i < G.vexnum; i++){
indegree[i] = 0;
}
for(i = 0; i < G.vexnum; i++){
temp = G.L[i].next_arcnode;
while(temp){
k = temp->name;
temp = temp->next_arcnode;
indegree[k]++;
}
}
}
bool TopologicalSort(Graph G, int topo[]) //拓扑排序算法
{
int indegree[G.vexnum], m, temp, i, k; //先定义一个入度数组indegree;
Arcnode * p;
Queue S; //定义一个队列 来存储入度为0的节点 加快排序, 以免重复检查入度已经为0的节点
FindInDegree(G, indegree);
InitStack(&S); //初始话一个队列
for(i = 0; i < G.vexnum; i++){
if(indegree[i] == 0) Push(&S, i);
} //先把入度为0的放到队列里
/* ***************初始化完成开始进行拓扑排序************** */
m = 0;
while(S.head != S.tail){
temp = Pop(&S);
topo[m++] = temp; //最先入度为0 的 存入到 topo数组里 最后数组里的值就是 排序完成后的序列
p = G.L[temp].next_arcnode;
while(p){ //寻找以temp节点为出度的 对应的相应的入度的节点 并且相应的入度节点的入度减一。
k = p->name;
indegree[k]--;
if(indegree[k] == 0) Push(&S, k);
p = p->next_arcnode;
}
}
if(m < G.vexnum) return "ERROR";
else return "OK";
}
int main()
{
Graph G;
int topo[queue_length], i;
Creat_Graph(&G);
TopologicalSort(G, topo);
for(i = 0; i < G.vexnum; i++) //输出拓扑排序的序列(序列不唯一,一旦同时有多个入度为0的节点 那么这些节点的序列任意)
printf("%d", topo[i]);
return 0;
}
//例子:
/*
6 8
0 1
0 2
0 3
3 4
5 4
2 4
2 1
5 3
*/
实验案例如下:
共6个节点分别为(0, 1, 2, 3, 4, 5)
关系为:
0-->1
0-->2
0-->3
3-->4
5-->4
2-->4
2-->1
5-->3
运行结果为: