拓扑排序算法应用:
有些事情做都需要按照流程的去做,比如你准备约你小女友去影院看速度与激情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