ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

拓扑排序(有向图)

2022-01-28 04:31:10  阅读:269  来源: 互联网

标签:Pre 有向图 int indegree 拓扑 vertex ++ ArcNode 排序


     

拓扑排序步骤:

1.在有向图中选一个没有前驱的顶点且输出之。

2.从图中删除该顶点和所有以它为尾的弧。

思考:

1.采用图的十字链表存储结构,可以方便的查找结点的出度和入度。

2.拓扑排序不唯一。

实现:

 1 void TopoSort(OLGraph G)
 2 {
 3     int i = 0;
 4     int count = 0;
 5     SeqStack S;
 6     ArcNode* P = NULL;
 7     int indegree[MAXVEX] = { 0 };
 8 
 9     for (i = 0; i < G.vexnum; i++)//求各个顶点入度并存入indegree数组
10     {
11         P = G.vertex[i].head;
12         while (P)
13         {
14             indegree[i]++;
15             P = P->hnext;
16         }
17     }
18 
19     S.top = -1;//初始化栈
20     for (i = 0; i < G.vexnum; i++)
21     {
22         if (indegree[i] == 0)
23         {
24             PushStack(&S, i);
25         }
26     }
27 
28     while (S.top != -1)//非空栈
29     {
30         count++;
31         PopStack(&S, &i);
32         printf("%c", G.vertex[i].vexdata);
33         for (P = G.vertex[i].tail; P; P = P->tnext)//对所有弧尾为i的边,其弧头点入度减1
34         {
35             i = P->headvex;
36             indegree[i]--;
37             if (indegree[i] == 0)
38             {
39                 PushStack(&S, i);
40             }
41         }
42     }
43 
44     if (count < G.vexnum)
45     {
46         printf("该有向网有回路");
47     }
48 }

源代码:

  1 #define _CRT_SECURE_NO_WARNINGS
  2 #include <stdio.h>
  3 #include <stdlib.h>
  4 #define MAXVEX 20
  5 
  6 typedef struct ArcNode
  7 {
  8     int tailvex;
  9     int headvex;
 10     struct ArcNode* tnext;
 11     struct ArcNode* hnext;
 12 }ArcNode;
 13 
 14 typedef struct VexNode
 15 {
 16     char vexdata;
 17     ArcNode* tail;
 18     ArcNode* head;
 19 }VexNode;
 20 
 21 typedef struct
 22 {
 23     int vexnum;
 24     int arcnum;
 25     VexNode vertex[MAXVEX];
 26 }OLGraph;//Orthogonal List Graph
 27 
 28 typedef struct
 29 {
 30     int top;
 31     int elem[MAXVEX];
 32 }SeqStack;//定长顺序栈
 33 
 34 void PushStack(SeqStack* S, int elem)
 35 {
 36     if (S->top == MAXVEX - 1)
 37     {
 38         printf("栈满");
 39         exit(1);
 40     }
 41     else
 42     {
 43         S->top++;
 44         S->elem[S->top] = elem;
 45     }
 46 }
 47 
 48 void PopStack(SeqStack* S, int* elem)
 49 {
 50     if (S->top == -1)
 51     {
 52         printf("栈空");
 53         exit(1);
 54     }
 55     else
 56     {
 57         (*elem) = S->elem[S->top];
 58         S->top--;
 59     }
 60 }
 61 
 62 void TopoSort(OLGraph G)
 63 {
 64     int i = 0;
 65     int count = 0;
 66     SeqStack S;
 67     ArcNode* P = NULL;
 68     int indegree[MAXVEX] = { 0 };
 69 
 70     for (i = 0; i < G.vexnum; i++)//求各个顶点入度并存入indegree数组
 71     {
 72         P = G.vertex[i].head;
 73         while (P)
 74         {
 75             indegree[i]++;
 76             P = P->hnext;
 77         }
 78     }
 79 
 80     S.top = -1;//初始化栈
 81     for (i = 0; i < G.vexnum; i++)
 82     {
 83         if (indegree[i] == 0)
 84         {
 85             PushStack(&S, i);
 86         }
 87     }
 88 
 89     while (S.top != -1)//非空栈
 90     {
 91         count++;
 92         PopStack(&S, &i);
 93         printf("%c", G.vertex[i].vexdata);
 94         for (P = G.vertex[i].tail; P; P = P->tnext)//对所有弧尾为i的边,其弧头点入度减1
 95         {
 96             i = P->headvex;
 97             indegree[i]--;
 98             if (indegree[i] == 0)
 99             {
100                 PushStack(&S, i);
101             }
102         }
103     }
104 
105     if (count < G.vexnum)
106     {
107         printf("该有向网有回路");
108     }
109 }
110 
111 
112 //返回顶点vex在十字链表G中的位置
113 int LocateVex(OLGraph G, char vex)
114 {
115     int i = 0;
116     for (i = 0; i < G.vexnum; i++)
117     {
118         if (G.vertex[i].vexdata == vex)
119         {
120             return i;
121         }
122     }
123     return -1;
124 }
125 
126 void Create(OLGraph* G)
127 {
128     int i = 0, j = 0, k = 0;
129     char tail = '\0';
130     char head = '\0';
131     ArcNode* P = NULL;
132     ArcNode* Pre = NULL;
133 
134     printf("请输入顶点数和边数(逗号分隔):");
135     scanf("%d%*c%d", &G->vexnum, &G->arcnum);
136 
137     for (i = 0; i < G->vexnum; i++)
138     {
139         printf("请输入第%d个顶点:", i + 1);
140         scanf(" %c", &G->vertex[i].vexdata);//%c前有一空格用于吸收空白字符
141         G->vertex[i].tail = NULL;
142         G->vertex[i].head = NULL;
143     }
144 
145     for (k = 0; k < G->arcnum; k++)
146     {
147         printf("请输入第%d条边的两端点(逗号分隔):", k + 1);
148         scanf(" %c%*c%c", &tail, &head);
149         i = LocateVex(*G, tail);
150         j = LocateVex(*G, head);
151         
152         P = (ArcNode*)calloc(1, sizeof(ArcNode));
153         P->tailvex = i;
154         P->headvex = j;
155 
156         if (G->vertex[i].tail == NULL)//链接到相同弧尾域
157         {
158             G->vertex[i].tail = P;
159         }
160         else
161         {
162             Pre = G->vertex[i].tail;
163             while (Pre->tnext)
164             {
165                 Pre = Pre->tnext;
166             }
167             Pre->tnext = P;
168         }
169 
170         if (G->vertex[j].head == NULL)//链接到相同弧头域
171         {
172             G->vertex[j].head = P;
173         }
174         else
175         {
176             Pre = G->vertex[j].head;
177             while (Pre->hnext)
178             {
179                 Pre = Pre->hnext;
180             }
181             Pre->hnext = P;
182         }
183     }
184 }
185 
186 int main(void)
187 {
188     OLGraph G;
189     Create(&G);
190     TopoSort(G);
191     system("pause");
192     return 0;
193 }
源代码

 

标签:Pre,有向图,int,indegree,拓扑,vertex,++,ArcNode,排序
来源: https://www.cnblogs.com/lvhui123/p/15851794.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有