邻接表形式
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stack>
using namespace std;
#define MAXN 1000
typedef struct ArcNode
{
int adjvex; //adjvex是整型,不是地址。也就是说邻接点域是元素
struct ArcNode *nextarc;
int info; //这个在本题中没用
}ArcNode;
typedef struct VertexNode
{
int Data; //这存起来的数据只有输出时才有用,不然也就存存,因为可用数组映射找表头结点
ArcNode* firstarc;
}VertexNode;
typedef struct
{
VertexNode vertex[MAXN]; //数组
int vexnum, arcnum;
}AdjList;
int InDegree[MAXN];
void CreateAdjList(AdjList* L,int vex,int arc)
{
(*L).vexnum = vex;
(*L).arcnum = arc;
int v1, v2, i;
for(i=1;i<= vex;i++)
{
(*L).vertex[i].Data=i;
(*L).vertex[i].firstarc = NULL;//一开始让每个结点链域都为空
}
for(i=1;i<=arc;i++)
{
scanf("%d%d",&v1,&v2);
ArcNode* q = (ArcNode*)malloc(sizeof(ArcNode));
q->adjvex = v2;
q->nextarc =(*L).vertex[v1].firstarc;//这就是头插法啊,所以书上才会从大到小排列
(*L).vertex[v1].firstarc = q; //这是以每个表头结点建立的n个结点的n条链//头插法从大到小,尾插法从小到大。
//如果拓扑排序的结果是小数优先,则用尾插法
//如果拓扑排序的结果是小数优先,则用头插法
}
}
void FindID(AdjList L)
{
int i;
ArcNode* p;
for(i=1;i<=L.vexnum;i++)
InDegree[i]=0;
for(i=1;i<=L.vexnum;i++)
{
p=L.vertex[i].firstarc;
while(p!=NULL)
{
InDegree[p->adjvex]++;
p=p->nextarc;
}
}
return;
}
void TopoSort(AdjList L)
{
stack<int> si;
int i,cnt,k;
ArcNode* p;
FindID(L);
for(i=1;i<=L.vexnum;i++)
{
if(InDegree[i]==0)
si.push(i);
}
cnt=0;
while(!si.empty())
{
printf("%d ",L.vertex[si.top()].Data);
p=L.vertex[si.top()].firstarc;
si.pop();
cnt++;
while(p!=NULL)
{
k=p->adjvex;
InDegree[k]--;
if(InDegree[k]==0)
si.push(k);
p=p->nextarc;
}
}
if(cnt<L.vexnum)
{
printf("有回路\n");
return ;
}
else
return;
}
int main()
{
AdjList L;
int n,m;
memset(InDegree,0,sizeof(InDegree));
scanf("%d%d",&n,&m);
CreateAdjList(&L,n,m);
TopoSort(L);
return 0;
}
邻接矩阵优化
#define MAXN 510
int Graph[MAXN][MAXN];
int InDegree[MAXN];
void FindID(int m)
{
int i;
for(i=1;i<=m;i++)
{
int u,v;
scanf("%d%d",&u,&v);
if(!Graph[u][v]) //????感觉是题目问题。。。
{
Graph[u][v]=1;
InDegree[v]++; //v的入度++
}
}
}
void TopoSort(int n) //n是顶点个数
{
int i;
int cnt=0;
priority_queue<int,vector<int>,greater<int> > si; //这样每次就自动从小到大排列了。
for(i=1;i<=n;i++)
if(InDegree[i]==0)
si.push(i);
int flag=1;
while(!si.empty())
{
int cur=si.top();
si.pop();
if(flag)
{
cout<<cur;
cnt++;
flag=0;
}
else
{
cout<<" "<<cur;
cnt++;
}
for(i=1;i<=n;i++)
{
if(Graph[cur][i]==1)
{
InDegree[i]--;//相连的点的入度减1
Graph[cur][i]=0;
if(InDegree[i]==0)//如果入度为0,加入队列
si.push(i);
}
}
}
printf("\n");
if(cnt<n)
printf("存在回路\n");
return ;
}