算法思想如下:
利用邻接表存储图,先设一个辅助数组indegree[]来计算所有节点的入度;首先把入度为零的节点入栈,当栈不为空时,把栈中的元素出栈,然后删除输出元素为弧尾的所有弧,并判断相应节点的入度是否为零,为零,则压入栈中。重复执行,直到栈空。
#include <stdio.h>
#include <stdlib.h>
#define MAX 30
int indegree[MAX];//用来存储所有节点的入度之和
typedef struct ArcNode{
struct ArcNode *nextarc;
int adjvex;
}ArcNode;
typedef struct{
ArcNode *firstarc;
char data;
}VNode,Vertice[MAX];
typedef struct{
int vexnum,arcnum;
Vertice vex;
}ALGraph;
typedef struct{
int top;
int *base;
int stacksize;
}SqStack;
int LocateVex(ALGraph G, char v){
for(int i = 0; i < G.vexnum; i ++){
if(v == G.vex[i].data)
return i;
}
return -1;
}
void CreateALGraph(ALGraph &G){
int i,j,k;
char v1[3],v2[3];
ArcNode *p,*s;
printf("输入节点和边的数目:\n");
scanf("%d%d",&G.vexnum,&G.arcnum);
printf("输入结点:\n");
for(i = 0; i < G.vexnum; i ++){
scanf("%s",v1);
G.vex[i].data = v1[0];
G.vex[i].firstarc = NULL;
}
printf("输入各条边:\n");
for(i = 0; i < G.arcnum; i ++){
scanf("%s%s",&v1,&v2);
j = LocateVex(G,v1[0]); k = LocateVex(G,v2[0]);
s = (ArcNode *)malloc(sizeof(ArcNode));
s->adjvex = k; s->nextarc = NULL;
if(!G.vex[j].firstarc){
G.vex[j].firstarc = s;
}
else{
p = G.vex[j].firstarc;
while(p->nextarc)
p = p->nextarc;
p->nextarc = s;
}
}
}
void FindInputDgeree(ALGraph G){//计算所有节点的入度
ArcNode *p;
int i;
for(i = 0; i < G.vexnum; i ++)
indegree[i] = 0;
for(i = 0; i < G.vexnum; i ++){
p = G.vex[i].firstarc;
while(p){
indegree[p->adjvex] ++;
p = p->nextarc;
}
}
}
void InitStack(SqStack &S){
S.base = (int *)malloc(sizeof(int) * MAX);
if(!S.base)
return ;
S.top = 0;
S.stacksize = MAX;
}
void Push(SqStack &S, int i){
if(S.top >= S.stacksize){
S.base = (int *)realloc(S.base,(S.top + MAX) * sizeof(int));
if(!S.base)
return ;
S.stacksize += MAX;
}
S.base[S.top ++] = i;
}
int StackEmpty(SqStack S){
if(!S.top )
return 1;
return 0;
}
void Pop(SqStack &S, int &i){
if(!S.top)
return;
i = S.base[-- S.top];
}
void TopologicalSort(ALGraph G){
FindInputDgeree(G);
int count = 0,i;
SqStack S; ArcNode *p;
InitStack(S);
for(i = 0; i < G.vexnum; i ++)
if(!indegree[i])//把入度为零的节点入栈
Push(S,i);
printf("拓扑序列如下:\n");
while(!StackEmpty(S)){
Pop(S,i);
printf("%c",G.vex[i].data); count ++;
p = G.vex[i].firstarc;
while(p){
if(!(-- indegree[p->adjvex]))//判断去掉一条边后节点的入度是否为零
Push(S,p->adjvex);
p = p->nextarc;
}
if(!StackEmpty(S)) printf("-->");
}
if(count < G.vexnum)
printf("该图为有向有环图");
printf("\n");
}
int main(){
ALGraph G;
CreateALGraph(G);//建立图
TopologicalSort(G);//进行拓扑排序
return 0;
}