拓扑排序(TopologicalSort)算法

拓扑排序算法应用:

  有些事情做都需要按照流程的去做,比如你准备约你小女友去影院看速度与激情7大片,首先你想的是我怎么到达影院,然后达到影院,你可以先买票,或者等小女友来了一起买票,然后一起进电影大厅.....然后说说甜言蜜语时机成熟了有可以做下一步了;作为顶点:自己的位置,影院位置,小女友到达影院,买票,进大厅,作为顶点,比如都到达了影院买好票才可以一起进入,就是当一个顶点都被满足时才可以该顶点才可以做动作执行下一步。这是我自己的理解方式,你要还不理的话可能是我说的不够好!

  1 /*
  2     拓扑排序基本思想:
  3         1.查找原始图中入度为0的顶点都入栈。
  4         2.所有顶点都入栈后,在一个顶点一个顶点的出栈。
  5         3.出栈一个顶点若是有邻接表的话,该邻接表的顶点入度-1 = 0的话,
  6         该邻接表的顶点入栈,然后一直循环。。。
  7 */
  8
  9 #include <stdio.h>
 10 #include <malloc.h>
 11 #include <stdlib.h>
 12
 13 #define MAXVEX 14//最大顶点数
 14 #define MAXEDGE 20//最大边数
 15
 16 /*    邻接矩阵结构    */
 17 typedef struct
 18 {
 19     int vexs[MAXVEX];//顶点下标
 20     int arc[MAXVEX][MAXVEX];//矩阵
 21     int numVertexes, numEdges;//当前图中的顶点数和边数
 22
 23 }MGraph;
 24
 25 /*    邻接表结构    */
 26 typedef struct EdgeNode
 27 {//边表结点
 28     int adjlist;//邻接点域,存储该顶点下标
 29     int weigth;//用于存储权值,对于无网图可以忽略
 30     struct EdgeNode *next;//链域,指向下一个邻接点域
 31
 32 }EdgeNode;
 33
 34 typedef struct
 35 {//顶点表结点
 36     int in;//顶点入度
 37     int data;//顶点域,存储顶点信息
 38     EdgeNode *firstedge;//边表头指针
 39
 40 }VertexNode, AdjList[MAXVEX];
 41
 42 typedef struct
 43 {
 44     AdjList adjlist;//顶点向量
 45     int numVertexes, numEdges;//当前图中顶点数和边数
 46
 47 }graphAdjList,*GraphAdjList;
 48
 49 /**********************************************************/
 50
 51 /*    构件图    */
 52 void CreateMGraph(MGraph *G)
 53 {
 54     int i, j;
 55
 56 //    printf("请输入顶点数和边数:\n");
 57     G->numVertexes = MAXVEX;
 58     G->numEdges    = MAXEDGE;
 59
 60     //初始化顶点下标
 61     for(i=0; i<G->numVertexes; i++)
 62         G->vexs[i] = i;
 63
 64     //初始化矩阵
 65     for(i=0; i<G->numVertexes; i++)
 66         for(j=0; j<G->numVertexes; j++)
 67             G->arc[i][j] = 0;
 68
 69     //内置输入
 70     G->arc[0][4]  = 1;
 71     G->arc[0][5]  = 1;
 72     G->arc[0][11] = 1;
 73     G->arc[1][2]  = 1;
 74     G->arc[1][4]  = 1;
 75     G->arc[1][8]  = 1;
 76     G->arc[2][5]  = 1;
 77     G->arc[2][6]  = 1;
 78     G->arc[2][9]  = 1;
 79     G->arc[3][2]  = 1;
 80     G->arc[3][13] = 1;
 81     G->arc[4][7]  = 1;
 82     G->arc[5][8]  = 1;
 83     G->arc[5][12] = 1;
 84     G->arc[6][5]  = 1;
 85     G->arc[8][7]  = 1;
 86     G->arc[9][10] = 1;
 87     G->arc[9][11] = 1;
 88     G->arc[10][13]= 1;
 89     G->arc[12][9] = 1;
 90
 91     return ;
 92 }
 93
 94 /*    采用矩阵-构建邻接表    */
 95 void CreateALGraph(MGraph G, GraphAdjList *GL)
 96 {
 97     int i, j;
 98     EdgeNode *e;
 99
100     *GL = (GraphAdjList)malloc(sizeof(graphAdjList));
101     (*GL)->numVertexes = G.numVertexes;
102     (*GL)->numEdges = G.numEdges;
103
104     for(i=0; i<G.numVertexes; i++)
105     {//初始化邻接表
106         (*GL)->adjlist[i].in = 0;
107         (*GL)->adjlist[i].data = G.vexs[i];
108         (*GL)->adjlist[i].firstedge = NULL;
109     }
110
111     //建立邻接表
112     for(i=0; i<G.numVertexes; i++)
113         for(j=0; j<G.numVertexes; j++)
114             if(G.arc[i][j] == 1)
115             {//若存在关系
116                 e = (EdgeNode *)malloc(sizeof(EdgeNode));
117                 e->adjlist = j;
118                 e->next = (*GL)->adjlist[i].firstedge;
119                 (*GL)->adjlist[i].firstedge = e;//头插法
120                 (*GL)->adjlist[j].in ++;//该顶点入度+1
121             }
122
123     return ;
124 }
125
126 int TopologicalSort(GraphAdjList GL)
127 {/*    拓扑排序    */
128     EdgeNode *e;
129     int i, k, gettop;
130     int top = 0;//指向栈顶
131     int count = 0;//记数
132     int *stack;//建立一个栈
133     stack = (int *)malloc(GL->numVertexes * sizeof(int));
134
135     //把没有入度的顶点入栈
136     for(i=0; i<GL->numVertexes; i++)
137         if(0 == GL->adjlist[i].in)
138             stack[++top] = i;
139
140     while(top != 0)
141     {//若栈中有元素存在
142         gettop = stack[top--];//栈顶顶点的下表给gettop,然后top-1
143         printf("%d->", GL->adjlist[gettop].data);//打印出栈顶点信息
144         count++;
145
146         for(e=GL->adjlist[gettop].firstedge; e; e=e->next)
147         {//判断出栈的顶点是否有出度
148             k = e->adjlist;//有则邻接点域顶点下标赋值K
149             if(!(--GL->adjlist[k].in))//该邻接点域的顶点入度-1(因为出栈的顶点已经指向该顶点,所以-1)后没有入度为0的话
150                 stack[++top] = k;//则该顶点入栈
151         }
152     }
153     printf("\n");
154     if(count < GL->numVertexes)
155         exit(-1);//若小于顶点数,证明存在环
156     else
157         return 0;
158 }
159
160 int main(void)
161 {
162     MGraph G;
163     GraphAdjList GL;
164     CreateMGraph(&G);//构件图
165     CreateALGraph(G, &GL);//构建邻接表
166     TopologicalSort(GL);//拓扑排序
167     system("PAUSE");
168
169     return 0;
170 }
171
172 /*
173     在vc++6.0运行结果:
174     3->1->2->6->0->4->5->8->7->12->9->10->13->11->
175     请按任意键继续. . .
176 */
时间: 2024-09-30 09:02:51

拓扑排序(TopologicalSort)算法的相关文章

拓扑排序(算法竞赛入门经典)

拓扑排序的定义: 把每个变量看成一个点,”小于“或者”先后“关系看成有向边,则我们得到一个有向图.这样我们的任务实际上是把一个图的所有节点排序,使每一条有向边的(u,v)对应的u都排在v之前,在图论中,我们称之为拓扑排序.不难发现,如果一个有向图里存在回路,则不存在拓扑排序(如果设置一个标志数组,我们可以发现回路中的点一直处于正在被访问状态,这可以作为拓扑排序的结束条件). 我们先看一个样例: 下面我们用邻接矩阵存储这张图:   0 1 2 3 0 0 1 1 1 1 0 0 1 1 2 0 0

拓扑排序的算法

package ToPu; public class Graph { private final int MAX_VERTS = 20; private Vertex vertexList[]; private int adjMat[][]; private int nVerts; private char sortedArray[]; public Graph(){ vertexList = new Vertex[MAX_VERTS]; adjMat = new int [MAX_VERTS]

图的拓扑排序——卡恩算法

拓扑排序 有向图的拓扑排序是其顶点的线性排序,使得对于从顶点u 到顶点v 的每个有向边uv ,u 在排序中都在v 之前. 在图论中,由一个有向无环图的顶点组成的序列,当且仅当满足下列条件时,称为该图的一个拓扑排序(Topological sorting). 每个顶点出现且只出现一次: 若A在序列中排在B的前面,则在图中不存在从B到A的路径. //#include<Windows.h> #include<iostream> #include<cstring> #inclu

图基本算法 拓扑排序(基于dfs)

拓扑排序,是对有向无回路图进行排序,以期找到一个线性序列,这个线性序列在生活正可以表示某些事情完成的相应顺序.如果说所求的图有回路的话,则不可能找到这个序列. 在大学数据结构课上,我们知道求拓扑排序的一种方法.首先用一个入度数组保存每个顶点的入度.在进行拓扑排序时,我们需要找到入度为0的点,将其存入线性序列中,再将其从图中删除(与它相关的边都删除,相邻的顶点的入度均减1),再重复上面的操作,直至所有的顶点都被找到为止.如果不对每次找入度为0的顶点的方法进行处理,而直接去遍历入度数组,则该算法的时

拓扑排序之变量序列算法分析

拓扑排序之变量序列 巧若拙(欢迎转载,但请注明出处:http://blog.csdn.net/qiaoruozhuo) 题目描述: 假设有n个变量(1<=n<=26,变量名用单个小写字母表示),还有m个二元组(u,v),分别表示变量u小于v.那么,所有变量从小到大排列起来应该是什么样子的呢? 例如有4个变量a,b,c,d,若以知a<b,c<b,d<c,则这4个变量的排序可能是a<d<c<b.尽管还有可能其他的可能,你只需找出其中的一个即可. 输入: 输入为一

HDU 5638 拓扑排序+优先队列

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5638 题意: 给你一个DAG图,删除k条边,使得能个得到字典序尽可能小的拓扑排序 题解: 把拓扑排序的算法稍微改一下,如果某个顶点的入度小于k也把它加到优先队列里面去. k减小后队列里面会有些点不满足<=k,直接踢出来就好了. 代码: #include<iostream> #include<cstring> #include<cstdio> #include<

图算法之拓扑排序

拓扑排序是对有向无圈图的顶点的一种排序,它使得如果存在一条从vi到vj的路径,那么在排序中Vj出现在Vi后面.一个简单的求拓扑排序的算法是先找出任意一个没有入边的顶点,然后我们显示该顶点,并将它和它的边一起从图中删除.然后为们对图的其余部分应用同样的方法处理.但是这个方法有一点不好,就是每次都要找入度为0的顶点,这种顶点一般很少,如果图很大的话,每次都遍历一遍就浪费很多时间.升级版是先计算每一个顶点的入度,然后将入度为0的顶点存入队列,操作完之后再更新入度.这样就不用遍历整个图而只需要从出队列操

拓扑排序介绍

拓扑排序介绍 拓扑排序(Topological Order)是指,将一个有向无环图(Directed Acyclic Graph简称DAG)进行排序进而得到一个有序的线性序列. 这样说,可能理解起来比较抽象.下面通过简单的例子进行说明! 例如,一个项目包括A.B.C.D四个子部分来完成,并且A依赖于B和D,C依赖于D.现在要制定一个计划,写出A.B.C.D的执行顺序.这时,就可以利用到拓扑排序,它就是用来确定事物发生的顺序的. 在拓扑排序中,如果存在一条从顶点A到顶点B的路径,那么在排序结果中B

转:【拓扑排序详解】+【模板】

转自:http://www.cnblogs.com/skywang12345/p/3711489.html 拓扑排序介绍 拓扑排序(Topological Order)是指,将一个有向无环图(Directed Acyclic Graph简称DAG)进行排序进而得到一个有序的线性序列. 这样说,可能理解起来比较抽象.下面通过简单的例子进行说明! 例如,一个项目包括A.B.C.D四个子部分来完成,并且A依赖于B和D,C依赖于D.现在要制定一个计划,写出A.B.C.D的执行顺序.这时,就可以利用到拓扑