拓扑排序
关于拓扑排序
拓扑排序通俗点来说就是对于一个有向无环图(DAG)来说,不断输出其入度为0的节点直到不存在,每个节点输出一次且仅有一次
拓扑排序用官方的话来说就是:对一个有向无环图(DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边<u,v>∈E(G),则u在线性序列中出现在v之前。通常,这样的线性序列称为满足拓扑次序(Topological Order)的序列,简称拓扑序列。简单的说,由某个集合上的一个偏序得到该集合上的一个全序,这个操作称之为拓扑排序。
执行步骤
拓扑排序主要步骤,也就主要循环两部分到不存在入度为零的顶点为止
- 选择一个入度为零的顶点输出
- 在
AOV
网中删除这个顶点及其出边
输出结束后,除非还有回路,否则其输出的顶点序列就是拓扑排序
AOV网其实就是有向无回路图,就是DAG
图解
对于以下图来说
删除1和2顶点和其对于边后并且输出,并且以此类推
其实对于输出的序列不唯一就看你自己怎么样设计栈的结构
代码实现
这里使用邻接表实现,再利用栈实现入度为零的输出
使用作业的题目,ABCDEF
对应下标从0开始慢慢增大
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
| #include <stdio.h> #include <stdlib.h> #include <stdbool.h> #define MAXVEX 10 typedef char VerType;
struct EdgeNode{ int adjvex; int weight; struct EdgeNode* next; };
struct VertexNode{ int in; VerType data; struct EdgeNode* firstedge; };
struct Graph{ struct VertexNode vers[MAXVEX]; int numVertexes, numEdges; };
int TopologicalSort(struct Graph* G){ struct 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->vers[i].in == 0) stack[++top] = i;
while(top != 0){ gettop = stack[top--]; printf("%c ",G->vers[gettop].data); count++; for(e=G->vers[gettop].firstedge; e; e = e->next){ k = e->adjvex; if(!(--G->vers[k].in)) stack[++top] = k; } } if(count < G->numVertexes) return 0; else return 1; }
void CreateGraph(struct Graph* G){ int i, m, n;
printf("输入顶点数和边数:\n"); scanf("%d %d",&G->numVertexes, &G->numEdges); printf("输入顶点值:\n"); getchar(); for(i=0;i<G->numVertexes;i++){ G->vers[i].data=getchar(); getchar(); } for(i=0;i<G->numVertexes;i++){ G->vers[i].firstedge = NULL; G->vers[i].in = 0; } printf("输入边:\n"); for(i=0;i<G->numEdges;i++){ scanf("%d %d",&m, &n); struct EdgeNode *newNode = (struct EdgeNode*)malloc(sizeof(struct EdgeNode)); newNode->next = G->vers[m].firstedge == NULL ? NULL : G->vers[m].firstedge; newNode->adjvex = n; G->vers[m].firstedge = newNode; G->vers[n].in++; } }
int main(){
struct Graph *G=(struct Graph*)malloc(sizeof(struct Graph)) ; CreateGraph(G); if(TopologicalSort(G)){ printf("拓扑排序完成!\n"); }else{ printf("图存在环"); } return 0; }
|