#include<stdio.h>
#include<stdlib.h>
#define MAXVEX 100 //最大顶点数
typedef char VertexType; //顶点
typedef int EdgeType; //权值
#define UNVISITED -1 //标记未访问
#define VISITED 1 //标记未访问
#define OK 1
#define ERROR 0
typedef int Status;
typedef struct EdgeNode
{
int adjvex; //该顶点对应的下标
EdgeType weight; //权重
struct EdgeNode * next;
}EdgeNode;
typedef struct //顶点结构
{
int in; //记录入度
VertexType data;
EdgeNode * firstedge;
}VertexNode,AdjList[MAXVEX];
typedef struct
{
AdjList adjList;
int numVertexes;
int numEdges;
int Mark[MAXVEX]; //标记是否被访问过
}GraphAdjList; //图结构
//初始化邻接表
void InitGraphAdjList(GraphAdjList * G,int numVer,int numEd) //传入顶点数和边数
{
G->numVertexes=numVer;
G->numEdges=numEd;
for(int i=0;i<G->numVertexes;i++)
{
G->Mark[i]=UNVISITED;
G->adjList[i].in=0;
G->adjList[i].firstedge=NULL; //将边表置空表
}
}
//创建一条边(有向图)
void Creat_Edge(GraphAdjList * G,int from,int to,int weight)
{
EdgeNode * temp= G->adjList[from].firstedge;
if(temp==NULL)
{
EdgeNode * NewEdgeNode=(EdgeNode *)malloc(sizeof(EdgeNode));
NewEdgeNode->adjvex=to;
NewEdgeNode->weight=weight;
NewEdgeNode->next=NULL;
G->adjList[from].firstedge=NewEdgeNode;
G->adjList[to].in++;
}
else
{
while(temp->next!=NULL)
{
temp=temp->next;
}
EdgeNode * NewEdgeNode=(EdgeNode *)malloc(sizeof(EdgeNode));
NewEdgeNode->adjvex=to;
NewEdgeNode->weight=weight;
NewEdgeNode->next=NULL;
temp->next=NewEdgeNode;
G->adjList[to].in++;
}
}
/*建立图的邻接表结构(有向图)*/
void GreateALGraph(GraphAdjList * G)
{
int i,j,k,w;
printf("请输入%d个元素:\n",G->numVertexes);
for(i=0;i<G->numVertexes;i++) /*读入顶点信息,建立顶点表*/
{
scanf(" %c",&G->adjList[i].data); /*输入顶点信息*/
G->adjList[i].firstedge=NULL; /*将边表置空表*/
}
for(k=0;k<G->numEdges;k++) /*建立边表*/
{
printf("输入边(Vi,Vj)上的顶点序号和权重:\n");
scanf("%d%d%d",&i,&j,&w); /*输入(Vi,Vj)上的顶点序号*/
Creat_Edge(G,i,j,w);
}
}
//拓扑排序算法
Status ToPologicalSort(GraphAdjList * G)
{
EdgeNode * e;
int i,k,gettop;
int top=0; //用于栈指针下标
int count=0; //统计输出的顶点个数
int * stack; //建栈存储顶点个数
stack=(int *)malloc(G->numVertexes * sizeof(int));
for(i=0;i<G->numVertexes;i++)
{
if(G->adjList[i].in==0) //将入度为0的顶点元素的下标入栈
{
stack[++top]=i;
}
}
while(top!=0) //栈不为空
{
gettop=stack[top--];
printf("%c ",G->adjList[gettop].data);
count++; //记录输出的顶点个数
for(e=G->adjList[gettop].firstedge;e;e=e->next)
{
k=e->adjvex; //记录当前邻接点
if(!(--G->adjList[k].in)) //将k的顶点邻接点的入度减1,查看入度是否为0;如果为0,则入栈
{
stack[++top]=k;
}
}
}
if(count<G->numVertexes) //输出的顶点个数小于顶点个数,说明有环
{
printf("此图有环!\n");
return ERROR;
}
else
{
return OK;
}
}
int main()
{
GraphAdjList G;
int numVer,numEd;
int start;
int choose;
printf("请输入顶点元素个数和边数:\n");
scanf("%d%d",&numVer,&numEd);
InitGraphAdjList(&G,numVer,numEd);
GreateALGraph(&G);
ToPologicalSort(&G);
printf("\n");
return 0;
}