#include <iostream> #include <stack> using namespace std; #define MAX 100 typedef char VertexType; typedef struct ArcNode { int adjvex; //邻接点域,存储该弧指向顶点的下标 (终点) struct ArcNode *next; //指向下一条弧的指针 int weight; //权重 }ArcNode; //边结构 typedef struct VertexNode { VertexType data; //数据域 ArcNode *firstArc; //指向第一条依附该顶点的弧的指针 }VertexNode,AdjVerList[MAX]; typedef struct { AdjVerList vertices; //顶点集 int vexnum,arcnum; //图的顶点数和弧数 }ALGraph; //图结构 int indegree[MAX]; //每个顶点对应的入度数组 void CreateALGraph(ALGraph *G); void Display(ALGraph *G); int TopoSort(ALGraph *G); //a b c d e f g h i /* a c 0 a h 0 b c 0 b d 0 b e 0 c d 0 d f 0 d g 0 e f 0 h i 0 i g 0 */ int main() { ALGraph G; CreateALGraph(&G); //Display(&G); TopoSort(&G); return 0; } //求顶点位置函数 int LocateVex(ALGraph *G,VertexType v) { int i; for(i=0;i<G->vexnum;i++) { if(G->vertices[i].data == v) return i; } return -1; } //有向无环图 void CreateALGraph(ALGraph *G) { VertexType v1,v2; int w; ArcNode *Arc; cout<<"请输入顶点数和边数:"; cin>>G->vexnum>>G->arcnum; cout<<"请输入各顶点的数据:"; for(int i=0;i<G->vexnum;i++){ cin>>G->vertices[i].data; G->vertices[i].firstArc = NULL; //顶点的边表设为空 } cout<<"请依次输入"<<G->arcnum<<"组边对应的两个顶点以及权值,以空格分割:"<<endl; for(int k=0;k<G->arcnum;k++) { cin>>v1>>v2>>w; int i = LocateVex(G,v1); int j = LocateVex(G,v2); Arc = new ArcNode; //新建边 Arc->adjvex = j; Arc->weight = w; Arc->next = G->vertices[i].firstArc; G->vertices[i].firstArc = Arc; } } void Display(ALGraph *G) { ArcNode *p; cout<<"编号, 顶点, 相邻边的顶点\n"; for(int i=0;i<G->vexnum;i++) { cout<<i<<"\t"<<G->vertices[i].data; for(p=G->vertices[i].firstArc;p!=NULL;p=p->next) cout<<"\t"<<p->adjvex; cout<<endl; } } //求各顶点的入度(遍历整个邻接表) void FindIndegree(ALGraph *G) { int i; ArcNode *p; //初始化每个顶点的入度为0 for(i=0;i<G->vexnum;i++) indegree[i] = 0; for(i=0;i<G->vexnum;i++) { p = G->vertices[i].firstArc; while(p) { //将每一个临接到的点(终点)自增 indegree[p->adjvex]++; p = p->next; } //cout<<i<<"元素的入度为:"<<indegree[i]<<endl; } } //返回值的失败与否代表该有向图是否存在回路 //拓扑排序 int TopoSort(ALGraph *G) { cout<<"该有向图的一种拓扑排序结果为:"<<endl; stack<int> s; //设置辅助栈,避免重复检测入度为0的顶点 ArcNode *p; int i,k; FindIndegree(G); for(i=0;i<G->vexnum;i++) { //将入度为0的顶点入栈 if(indegree[i]==0) s.push(i); } int count = 0; while(!s.empty()) { i = s.top(); s.pop(); cout<<G->vertices[i].data<<" "; //将栈顶出栈并打印 count++; //统计已输出的顶点数 p = G->vertices[i].firstArc; while(p!=NULL) { k = p->adjvex; indegree[k]--; //i号顶点已出栈,所以将i号顶点的每个邻接点的入度自减 if(indegree[k]==0) s.push(k); //如果入度减为0,则入栈 p = p->next; } } if(count<G->vexnum) return -1; //存在回路 else return 0; }
原文:http://blog.csdn.net/huolang_vip/article/details/46552375