Java教程

拓扑排序(有向图)

本文主要是介绍拓扑排序(有向图),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

     

拓扑排序步骤:

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 }
源代码

 

这篇关于拓扑排序(有向图)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!