#include "stdafx.h"
#include <iostream.h>
#include <malloc.h>
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
int const vnum=6;
//单链表定义
typedef struct arcnode
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
int adjvex; //与其相连的下个结点的编号
struct arcnode * nextarc; //指向下一个结点的指针
}ArcNodeTp;
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
//顶点定义
typedef struct vexnode
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
int vertex; //顶点的值
int in; //入度数量
ArcNodeTp * firstarc; //指向的出度的单链表
}AdjList[vnum];
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
//图的定义
typedef struct graph
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
AdjList adjlist;
int vexnum,arcnum;
}GraphTp;
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
//建立一个新的结点
ArcNodeTp * CreateNewNode(int adjvex)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
ArcNodeTp * node=(ArcNodeTp *)malloc(sizeof(ArcNodeTp));
node->adjvex=adjvex;
node->nextarc=NULL;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
return node;
}
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
//建立P122的图5-17(a)
void CreateGraph(GraphTp & graph)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
graph.arcnum=7;
graph.vexnum=vnum;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
ArcNodeTp * p=NULL;
int index=0;
//建立结点
index=0;
graph.adjlist[index].vertex=index;
p=CreateNewNode(1);
//修改头结点
graph.adjlist[index].firstarc=p;
//指向下一个结点
p->nextarc=CreateNewNode(2);
graph.adjlist[index].in=0;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
index=1;
graph.adjlist[index].vertex=index;
p=CreateNewNode(5);
graph.adjlist[index].firstarc=p;
graph.adjlist[index].in=1;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
index=2;
graph.adjlist[index].vertex=index;
p=CreateNewNode(5);
graph.adjlist[index].firstarc=p;
graph.adjlist[index].in=2;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
index=3;
graph.adjlist[index].vertex=index;
p=CreateNewNode(2);
graph.adjlist[index].firstarc=p;
p->nextarc=CreateNewNode(4);
graph.adjlist[index].in=0;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
index=4;
graph.adjlist[index].vertex=index;
p=CreateNewNode(5);
graph.adjlist[index].firstarc=p;
graph.adjlist[index].in=1;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
index=5;
graph.adjlist[index].vertex=index;
graph.adjlist[index].firstarc=NULL;
graph.adjlist[index].in=3;
}
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
void Top_Sort(GraphTp g)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
//用数组和一个变量模拟栈
int stack[vnum];
int top=0;
int i=0;
for(i=0;i<g.vexnum;i++)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (g.adjlist[i].in==0)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
stack[++top]=i;
}
}
int count=0;
while(top!=0)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
int v=stack[top--];
count++;
cout<<"输出顶点:"<<g.adjlist[v].vertex<<endl;
ArcNodeTp * p=g.adjlist[v].firstarc;
//此循环目的是去掉此弧尾对应的顶点的边,实现的方法并非删除,则是将出度的对应的顶点的In-1
while(p!=NULL)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
//将弧头的入度数减一后,判断是否入度为0,如果为0则入栈
if (--g.adjlist[p->adjvex].in==0)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
stack[++top]=p->adjvex;
}
p=p->nextarc;
}
}
if (count<g.vexnum)
cout<<"图中存在环"<<endl;
else
cout<<"拓扑排序完成"<<endl;
}
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
int main(int argc, char* argv[])
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
GraphTp g;
CreateGraph(g);
Top_Sort(g);
return 0;
}
另外,书在首次将入度为0的顶点编号入栈的地方没有写"{",这样的结果是错误的,估计是排版的人弄错的.可以参考我的代码,填上相应的"{}"
一点说明:为什么在标题中要嵌入英文?原因是为了能够让国外的网友能查询到这篇文章。平常在Google上查资料的时候,经常参考国外网友的博客,帮助我解决了很多问题,所以我也想让他们能够参考我写的内容。当然文中我不可能全部译为英文,所以我尽量把代码粘全,靠代码说话吧。