#include<stdio.h>
#include<stdlib.h>
#define MAX_VERTEX_NUM 20//顶点最大个数
typedef int Status;//函数的类型,其值是函数结果状态代码
typedef char VertexType;//顶点元素的类型
typedef int ElemType;
typedef struct ArcNode
{
int adjvex;
struct ArcNode *nextarc;
int weight;
}ArcNode;
typedef struct Vnode
{
VertexType data;
ArcNode *firstarc;
}VNode,AdjList[MAX_VERTEX_NUM];
typedef struct{
AdjList vertices;
int vexnum,arcnum;
int kind;
}ALGraph;
typedef struct SqStack
{
ElemType elem[MAX_VERTEX_NUM];
int top;
}SqStack;
//初始化栈
void InitStack(SqStack &S)
{
S.top=-1;
}
//判断栈空否,1为空
Status StackEmpty(SqStack S)
{
if(S.top==-1)
return 1;
else
return 0;
}
//入栈
Status Push(SqStack &S,ElemType e)
{
if(S.top==MAX_VERTEX_NUM-1)
return 0;
S.elem[++S.top]=e;
return 1;
}
//栈顶元素出栈
Status Pop(SqStack &S,ElemType *e)
{
if(S.top==-1)
return 0;
*e=S.elem[S.top--];
return 1;
}
//返回顶点v在图顶点向量中的位置
int LocateVex(ALGraph G,char v)
{
int i;
for(int i=0;v!=G.vertices[i].data&&i<G.vexnum;++i);
if(i>=G.vexnum)
return -1;
return i;
}
//建立邻接表
void creatDN(ALGraph &G)
{
int i,j;
char v1,v2;
ArcNode *s;
printf("输入有向图的顶点数:");
scanf("%d",&G.vexnum);
printf("输入有向图的边数:");
scanf("%d",&G.arcnum);
for(i=0;i<G.vexnum;i++)
{
printf("输入第%d的顶点的信息:",i+1);
scanf("%s",&G.vertices[i].data);
G.vertices[i].firstarc=NULL;
}
for(int i1=0;i1<G.arcnum;i1++)//该弧所指的顶点的位置
{
printf("输入第%d条边的弧尾顶点:",i1+1);
scanf("%s",&v1);
printf("输入第%d条边的弧头顶点:",i1+1);
scanf("%s",&v2);
i=LocateVex(G,v1);
j=LocateVex(G,v2);
s=(ArcNode *)malloc(sizeof(ArcNode));
s->adjvex=j;//弧所指的顶点的位置为j
s->nextarc=G.vertices[i].firstarc;
G.vertices[i].firstarc=s;
}
}
//输出邻接表
void printAdjList(ALGraph G)
{
int i;
ArcNode *p;
printf("%4s%6s%12s\n","编号","顶点","相邻边编号");
for(i=0;i<G.vexnum;i++)
{
printf("%4d%5c",i,G.vertices[i].data);
for(p=G.vertices[i].firstarc;p;p=p->nextarc)
printf("%3d",p->adjvex);//弧所指的顶点的位置
printf("\n");
}
}
//对顶点求入度,需要遍历邻接矩阵
void FindInDegree(ALGraph G,int *indegree)
{
ArcNode *s;
for(int i=0;i<G.vexnum;i++)
{
s=G.vertices[i].firstarc;
while(s)
{
indegree[s->adjvex]++;
s=s->nextarc;
}
}
}
//拓扑排序
int TopologicalSort(ALGraph G)
{
SqStack S;
int i,k,count,*indegree;
ArcNode *P;
indegree=(int *)malloc(G.vexnum*sizeof(int));
for(i=0;i<G.vexnum;i++)
indegree[i]=0;
FindInDegree(G,indegree);
InitStack(S);
for(i-0;i<G.vexnum;i++)
if(!indegree[i])Push(S,i);
count=0;
printf("图G的拓扑排序为:\n");
while(!StackEmpty(S))
{
Pop(S,&i);
printf("%5c",G.vertices[i].data);
++count;
ArcNode *p;
for(p=G.vertices[i].firstarc;p;p=p->nextarc)
{
k=p->adjvex;
if(!(--indegree[k]))
Push(S,k);
}
}
printf("\n");
if(count<G.vexnum)
return 0;
else
return 1;
}
int main()
{
ALGraph G;
creatDN(G);
printAdjList(G);
if(TopologicalSort(G));
else
printf("该有向图存在回路!\n");
}
#include<stdlib.h>
#define MAX_VERTEX_NUM 20//顶点最大个数
typedef int Status;//函数的类型,其值是函数结果状态代码
typedef char VertexType;//顶点元素的类型
typedef int ElemType;
typedef struct ArcNode
{
int adjvex;
struct ArcNode *nextarc;
int weight;
}ArcNode;
typedef struct Vnode
{
VertexType data;
ArcNode *firstarc;
}VNode,AdjList[MAX_VERTEX_NUM];
typedef struct{
AdjList vertices;
int vexnum,arcnum;
int kind;
}ALGraph;
typedef struct SqStack
{
ElemType elem[MAX_VERTEX_NUM];
int top;
}SqStack;
//初始化栈
void InitStack(SqStack &S)
{
S.top=-1;
}
//判断栈空否,1为空
Status StackEmpty(SqStack S)
{
if(S.top==-1)
return 1;
else
return 0;
}
//入栈
Status Push(SqStack &S,ElemType e)
{
if(S.top==MAX_VERTEX_NUM-1)
return 0;
S.elem[++S.top]=e;
return 1;
}
//栈顶元素出栈
Status Pop(SqStack &S,ElemType *e)
{
if(S.top==-1)
return 0;
*e=S.elem[S.top--];
return 1;
}
//返回顶点v在图顶点向量中的位置
int LocateVex(ALGraph G,char v)
{
int i;
for(int i=0;v!=G.vertices[i].data&&i<G.vexnum;++i);
if(i>=G.vexnum)
return -1;
return i;
}
//建立邻接表
void creatDN(ALGraph &G)
{
int i,j;
char v1,v2;
ArcNode *s;
printf("输入有向图的顶点数:");
scanf("%d",&G.vexnum);
printf("输入有向图的边数:");
scanf("%d",&G.arcnum);
for(i=0;i<G.vexnum;i++)
{
printf("输入第%d的顶点的信息:",i+1);
scanf("%s",&G.vertices[i].data);
G.vertices[i].firstarc=NULL;
}
for(int i1=0;i1<G.arcnum;i1++)//该弧所指的顶点的位置
{
printf("输入第%d条边的弧尾顶点:",i1+1);
scanf("%s",&v1);
printf("输入第%d条边的弧头顶点:",i1+1);
scanf("%s",&v2);
i=LocateVex(G,v1);
j=LocateVex(G,v2);
s=(ArcNode *)malloc(sizeof(ArcNode));
s->adjvex=j;//弧所指的顶点的位置为j
s->nextarc=G.vertices[i].firstarc;
G.vertices[i].firstarc=s;
}
}
//输出邻接表
void printAdjList(ALGraph G)
{
int i;
ArcNode *p;
printf("%4s%6s%12s\n","编号","顶点","相邻边编号");
for(i=0;i<G.vexnum;i++)
{
printf("%4d%5c",i,G.vertices[i].data);
for(p=G.vertices[i].firstarc;p;p=p->nextarc)
printf("%3d",p->adjvex);//弧所指的顶点的位置
printf("\n");
}
}
//对顶点求入度,需要遍历邻接矩阵
void FindInDegree(ALGraph G,int *indegree)
{
ArcNode *s;
for(int i=0;i<G.vexnum;i++)
{
s=G.vertices[i].firstarc;
while(s)
{
indegree[s->adjvex]++;
s=s->nextarc;
}
}
}
//拓扑排序
int TopologicalSort(ALGraph G)
{
SqStack S;
int i,k,count,*indegree;
ArcNode *P;
indegree=(int *)malloc(G.vexnum*sizeof(int));
for(i=0;i<G.vexnum;i++)
indegree[i]=0;
FindInDegree(G,indegree);
InitStack(S);
for(i-0;i<G.vexnum;i++)
if(!indegree[i])Push(S,i);
count=0;
printf("图G的拓扑排序为:\n");
while(!StackEmpty(S))
{
Pop(S,&i);
printf("%5c",G.vertices[i].data);
++count;
ArcNode *p;
for(p=G.vertices[i].firstarc;p;p=p->nextarc)
{
k=p->adjvex;
if(!(--indegree[k]))
Push(S,k);
}
}
printf("\n");
if(count<G.vexnum)
return 0;
else
return 1;
}
int main()
{
ALGraph G;
creatDN(G);
printAdjList(G);
if(TopologicalSort(G));
else
printf("该有向图存在回路!\n");
}