拓扑排序(Kahn实现)

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <string.h>
  4 #include <stdbool.h>
  5 
  6 #define MaxVertexNodeNumSize 1000
  7 #define MaxVertexNodeNameSize 100
  8 
  9 struct VertexBodyNode
 10 {
 11     char VertexName[MaxVertexNodeNameSize];
 12     int ArcWeight;
 13     int VertexIndex;
 14     struct VertexBodyNode *Next;
 15 };
 16 
 17 struct VertexHeadNode
 18 {
 19     char VertexName[MaxVertexNodeNameSize];
 20     int VertexWeight;
 21     struct VertexBodyNode *Next;
 22 };
 23 
 24 struct _Graph
 25 {
 26     struct VertexHeadNode VertexHeadNodeList[MaxVertexNodeNumSize];
 27     int ArcNum,VertexNum;
 28 };
 29 
 30 typedef int ElementType;
 31 
 32 struct StackNode
 33 {
 34     ElementType Element;
 35     struct StackNode *Next;
 36 };
 37 
 38 int StackIsEmpty(struct StackNode *StackTop)
 39 {
 40     return (StackTop -> Next == NULL);
 41 }
 42 
 43 int StackPush(ElementType ToBePush,struct StackNode *StackTop)
 44 {
 45     struct StackNode *TmpCell;
 46 
 47     TmpCell = malloc(sizeof(struct StackNode));
 48     if(TmpCell == NULL)
 49     {
 50         return 1;
 51     }
 52     else
 53     {
 54         TmpCell -> Element = ToBePush;
 55         TmpCell -> Next = StackTop -> Next;
 56         StackTop -> Next = TmpCell;
 57     }
 58     return 0;
 59 }
 60 
 61 ElementType StackGetTop(struct StackNode *StackTop)
 62 {
 63     if(!StackIsEmpty(StackTop))
 64     {
 65         return StackTop -> Next -> Element;
 66     }
 67 }
 68 
 69 int StackPop(struct StackNode *StackTop)
 70 {
 71     struct StackNode *FirstCell;
 72 
 73     if(StackIsEmpty(StackTop))
 74     {
 75         return 1;
 76     }
 77     else
 78     {
 79         FirstCell = StackTop -> Next;
 80         StackTop -> Next = StackTop -> Next -> Next;
 81         free(FirstCell);
 82     }
 83     return 0;
 84 }
 85 
 86 int MakeStackEmpty(struct StackNode *StackTop)
 87 {
 88     if(StackTop == NULL)
 89     {
 90         return 1;
 91     }
 92     else
 93     {
 94         while( !StackIsEmpty(StackTop) )
 95         {
 96             StackPop(StackTop);
 97         }
 98     }
 99     return 0;
100 }
101 
102 struct StackNode *StackInit()
103 {
104     struct StackNode *StackTop;
105 
106     StackTop = malloc(sizeof(struct StackNode));
107     if(StackTop == NULL)
108     {
109         return NULL;
110     }
111 
112     StackTop -> Next = NULL;
113     MakeStackEmpty(StackTop);
114     return StackTop;
115 }
116 
117 int StackDelete(struct StackNode *StackTop)
118 {
119     if(StackTop == NULL)
120     {
121         return 1;
122     }
123     else
124     {
125         MakeStackEmpty(StackTop);
126         free(StackTop);
127     }
128     return 0;
129 }
130 
131 int VertexName2Index(struct _Graph *DirectedGraph,char *VName)
132 {
133     int i;
134     for(i = 0; i < DirectedGraph -> VertexNum; i ++)
135     {
136         if(strcmp(DirectedGraph -> VertexHeadNodeList[i].VertexName,VName)==0)
137         {
138             return i;
139         }
140     }
141     return -1;
142 }
143 
144 void AddOneArc(struct _Graph *DirectedGraph,int ArcIndex_1,int ArcIndex_2,int AWeight)
145 {
146     struct VertexBodyNode *BNode = malloc(sizeof(struct VertexBodyNode));
147 
148     strcpy(BNode -> VertexName,DirectedGraph -> VertexHeadNodeList[ArcIndex_2].VertexName);
149 
150     BNode -> ArcWeight = AWeight;
151     BNode -> VertexIndex = ArcIndex_2;
152     BNode -> Next = NULL;
153 
154     struct VertexBodyNode *TmpPointer;
155     TmpPointer = DirectedGraph -> VertexHeadNodeList[ArcIndex_1].Next;
156     while(TmpPointer != NULL && TmpPointer -> Next != NULL)
157     {
158         TmpPointer = TmpPointer -> Next;
159     }
160     if(TmpPointer==NULL)
161     {
162         DirectedGraph -> VertexHeadNodeList[ArcIndex_1].Next = BNode;
163     }
164     else
165     {
166         TmpPointer -> Next = BNode;
167     }
168 }
169 
170 struct _Graph *UGCreat(int ArcSum,int VertexSum)
171 {
172     int i,j;
173     struct _Graph *DirectedGraph = malloc(sizeof(struct _Graph));
174     DirectedGraph -> ArcNum = ArcSum;
175     DirectedGraph -> VertexNum = VertexSum;
176 
177     for(i = 0; i < VertexSum; i ++)
178     {
179         scanf("%s %d",DirectedGraph -> VertexHeadNodeList[i].VertexName,&DirectedGraph -> VertexHeadNodeList[i].VertexWeight);
180     }
181 
182     for(i = 0; i < VertexSum; i ++)
183     {
184         DirectedGraph -> VertexHeadNodeList[i].Next = NULL;
185     }
186 
187     for(i = 0; i < ArcSum; i ++)
188     {
189         char Arc_1[MaxVertexNodeNameSize];
190         char Arc_2[MaxVertexNodeNameSize];
191         int ArcIndex_1;
192         int ArcIndex_2;
193         int ArcWeight;
194 
195         scanf("%s %s %d",Arc_1,Arc_2,&ArcWeight);
196 
197         ArcIndex_1 = VertexName2Index(DirectedGraph,Arc_1);
198         ArcIndex_2 = VertexName2Index(DirectedGraph,Arc_2);
199 
200         AddOneArc(DirectedGraph,ArcIndex_1,ArcIndex_2,ArcWeight);
201     }
202     return DirectedGraph;
203 }
204 
205 void Travel(struct _Graph *DirectedGraph)
206 {
207     char StartingPoint[MaxVertexNodeNameSize];
208     char OverPoint[MaxVertexNodeNameSize];
209 
210     printf("Input start and over\n");
211     scanf("%s %s",StartingPoint,OverPoint);
212 
213     int StartIndex = VertexName2Index(DirectedGraph,StartingPoint);
214     int OverIndex = VertexName2Index(DirectedGraph,OverPoint);
215 
216     struct VertexBodyNode *TmpPointer;
217     TmpPointer = DirectedGraph -> VertexHeadNodeList[StartIndex].Next;
218     while(TmpPointer != NULL)
219     {
220         if(OverIndex==TmpPointer -> VertexIndex)
221         {
222             printf("Distance:%d GetVertexPointSum:%d",TmpPointer->ArcWeight
223                    ,DirectedGraph -> VertexHeadNodeList[StartIndex].VertexWeight+DirectedGraph -> VertexHeadNodeList[OverIndex].VertexWeight);
224             break;
225         }
226         else
227         {
228             TmpPointer = TmpPointer -> Next;
229         }
230     }
231 }
232 
233 bool KahnTopologicalSort(struct _Graph *DirectedGraph)
234 {
235     int InDgree[DirectedGraph->VertexNum];
236     memset(InDgree,0,sizeof(InDgree));
237 
238 
239     // count every vertex's indgree and store in array InDgree
240     int i;
241     struct VertexBodyNode *TmpPointer;
242     for(i = 0; i < DirectedGraph->VertexNum; i ++)
243     {
244         TmpPointer = DirectedGraph->VertexHeadNodeList[i].Next;
245         while(TmpPointer != NULL)
246         {
247             InDgree[TmpPointer->VertexIndex] ++;
248             TmpPointer = TmpPointer -> Next;
249         }
250     }
251     
252     //put Vertex whose Indgree is zero into stack
253     struct StackNode *StackTop;
254     StackTop = StackInit();
255     for(i = 0; i < DirectedGraph->VertexNum; i ++)
256     {
257         if(!InDgree[i])
258         {
259             StackPush(i,StackTop);
260         }
261     }
262     
263     int Index;
264     while(!StackIsEmpty(StackTop))
265     {
266         Index = StackGetTop(StackTop);
267         StackPop(StackTop);
268         printf("%s ",DirectedGraph -> VertexHeadNodeList[Index].VertexName);
269         
270         TmpPointer = DirectedGraph->VertexHeadNodeList[Index].Next;
271         while(TmpPointer != NULL)
272         {
273             InDgree[TmpPointer->VertexIndex] --;
274             if(! InDgree[TmpPointer->VertexIndex])
275             {
276                 StackPush(TmpPointer->VertexIndex,StackTop);
277             }
278             TmpPointer = TmpPointer -> Next;
279         }
280     }
281 }
282 
283 int main()
284 {
285     struct _Graph *G = UGCreat(8,5);
286 
287 //    Travel(G);
288     KahnTopologicalSort(G);
289     return 0;
290 }
291 
292 /*
293         beijing 18
294         zhengzhou 10
295         hefei 9
296         nanjing 12
297         guangzhou 14
298         beijing zhengzhou 7
299         beijing hefei 9
300         beijing nanjing 8
301         zhengzhou hefei 5
302         hefei nanjing 3
303         zhengzhou guangzhou 7
304         hefei guangzhou 8
305         nanjing guangzhou 6
306         
307 */

 

转载于:https://www.cnblogs.com/Asurudo/p/9427491.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值