假设有向图以邻接表存储,每个顶点的名称都用一个字母表示。先输入顶点的数量,再输入各个顶点的名称,最后输入各条边。在输入边时,每次输入两个顶点的名称。输入不存在的两个顶点代表边输入结束。代码主要参考了严蔚敏老师的数据结构教材。在VC++ 6.0和Dev-C++下编译通过。
#include "stdio.h"
#include "stdlib.h"
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
typedef int Status;
typedef int Boolean;
typedef int SElemType;
#define STACK_INIT_SIZE 20
#define STACKINCREMENT 10
typedef struct SqStack
{
SElemType *base;
SElemType *top;
int stacksize;
}SqStack;
typedef struct ArcNode
{
int adjvex;
struct ArcNode *nextarc;
int weight;
}ArcNode;
typedef struct VNode
{
char data;
struct ArcNode *firstarc;
}VNode;
typedef VNode AdjList[100];
typedef struct
{
AdjList vex;
int vexnum;
}ALGraph;
Status InitStack(SqStack &S)
{
S.base=(SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType));
if(!S.base)
exit(-1);
S.top=S.base;
S.stacksize=STACK_INIT_SIZE;
return OK;
}
Status DestroyStack(SqStack &S)
{
free(S.base);
S.base=NULL;
S.top=NULL;
S.stacksize=0;
return OK;
}
Status StackEmpty(SqStack S)
{
if(S.top==S.base)
return TRUE;
else
return FALSE;
}
Status Push(SqStack &S,SElemType e)
{
if(S.top - S.base >= S.stacksize)
{
S.base = (SElemType *)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(SElemType));
if(!S.base)
exit (-1);
S.top = S.base + S.stacksize;
S.stacksize += STACKINCREMENT;
}
*(S.top)=e;
S.top++;
return OK;
}
Status Pop(SqStack &S,SElemType &e)
{
if(S.top==S.base)
return ERROR;
e=*(S.top-1);
--S.top;
return OK;
}
int getIndex(char name, ALGraph G)
{
int i;
for(i=0;i<G.vexnum;i++)
if(G.vex[i].data==name)
return i;
return -1;
}
void CountInDegree(ALGraph G, int indegree[])
{
int i;
ArcNode *p;
for(i=0;i<G.vexnum;i++)
indegree[i]=0;
for(i=0;i<G.vexnum;i++)
for(p=G.vex[i].firstarc;p!=NULL;p=p->nextarc)
indegree[p->adjvex]++;
}
int TopologicalOrder(ALGraph G)
{
ArcNode *p;
SqStack S;
int indegree[200],i,count,v,w;
CountInDegree(G,indegree);
InitStack(S);
for( i=0; i<G.vexnum; ++i)
if (!indegree[i])
Push(S, i);
count=0;
while (!StackEmpty(S))
{
Pop(S, v);
++count;
printf("%c ",G.vex[v].data);
for(p=G.vex[v].firstarc;p!=NULL;p=p->nextarc)
{
w=p->adjvex;
--indegree[w];
if (!indegree[w])
Push(S, w);
}
}
printf("\n");
DestroyStack(S);
if (count<G.vexnum)
{
printf("图中有回路");
return 0;
}
else
return 1;
}
void CreateGraph(ALGraph &G)
{
int i,j,k,n;
char a,b;
ArcNode *q;
printf("Input number of node: ");
scanf("%d",&n);
G.vexnum=n;
for(k=0;k<G.vexnum;k++)
{
printf(" node %d= ",k);
fflush(stdin);
scanf("%c",&(G.vex[k].data));
G.vex[k].firstarc=NULL;
}
for(;;)
{
printf("Insert edge u v: ");
fflush(stdin);
scanf("%c %c",&a,&b);
i=getIndex(a,G);
j=getIndex(b,G);
if(i==-1 && j==-1)
break;
q=(ArcNode *)malloc(sizeof(ArcNode));
q->adjvex=j;
q->nextarc=G.vex[i].firstarc;
G.vex[i].firstarc=q;
}
}
int main()
{
ALGraph G;
CreateGraph(G);
printf("拓扑排序为:\n");
TopologicalOrder(G);
printf("\n");
return 0;
}