图相关算法c/c++

  1 typedef char InfoType;
  2 //图的邻接矩阵储存方法 
  3 
  4 //图的邻接矩阵表示是唯一的
  5 //邻接矩阵适合储存边的数目比较多的稠密图
  6 //无向图的邻接矩阵是一个对称矩阵
  7 //对于无向图,第i行或者第i列非0,非INF元素的个数正好是顶点i的度
  8 //对于有向图,第i行或者第i列非0,非INF元素的个数正好是顶点i的出度或者入度
  9 //判断两个结点之间是否有边或者求两个结点之间的权的复杂度为O(1) 
 10 typedef struct{
 11     int no;
 12     InfoType info;
 13 }VertexType;
 14 
 15 typedef struct{
 16     int edges[MAXV][MAXV];
 17     int n,e;
 18     VertexType vexs[MAXV];
 19 }MatGraph;
 20 
 21 //图的邻接表储存方法
 22 
 23 //邻接表的表示不唯一 
 24 //对于无向图,邻接表有n个头节点和2e个边节点
 25 //对于有向图,邻接表有n个头节点和e个边节点
 26 //对于边数比较少的稀疏表,邻接表比邻接矩阵更节省储存空间
 27 //对于无向图,邻接表中顶点i对应的第i个单链表的边节点的数目就是顶点i的度
 28 //对于有向图,邻接表中顶点i对应的第i个单链表的边节点的数目仅仅是顶点i的出度
 29 //                      顶点i的入度为邻接表中所有adjvex值为i的边节点的数目
 30 //邻接表中查找顶点i关联的所有边非常快速,在需要提取某个节点的所有邻接点的算法中通常采用邻接表储存结构 
 31 //边节点
 32 typedef struct Anode{
 33     int adjvex;                //邻接点的编号
 34     struct Anode *nextarc;  //指向下一条边的指针
 35     int weight;                //该边的权重 
 36 }ArcNode;
 37 //头节点
 38 typedef struct Vnode{
 39     InfoType info;
 40     ArcNode *firstarc;
 41 }VNode;
 42 //完整的邻接表 
 43 typedef struct{
 44     VNode adjlist[MAXV];
 45     int n,e;
 46 }AdjGraph; 
 47 
 48 //用图的邻接矩阵创建图的邻接表
 49 void CreateAdj(AdjGraph *&G,int A[MAXV][MAXV],int n,int e)
 50 {
 51     ArcNode *p;
 52     G = (AdjGraph *)malloc(sizeof(AdjGraph));
 53     for(int i = 0;i < n;i++)
 54         G->adjlist[i].firstarc = NULL;
 55     G->n = n;G->e = e;
 56     for(int i = 0;i < n;i++)
 57         for(int j  = n-1;j >= 0;j--)
 58         {
 59             if(A[i][j] != 0 && A[i][j] != INF)
 60             {
 61                 p = (ArcNode *)malloc(sizeof(ArcNode));
 62                 p->adjvex = j;p->weight = A[i][j];
 63                 p->nextarc = G->adjlist[i].firstarc;
 64                 G->adjlist[i].firstarc = p;
 65             }
 66         }
 67 }
 68 //输出图(邻接表储存结构)
 69 void DispGraph(AdjGraph *G)
 70 {
 71     ArcNode *p;
 72     for(int i = 0;i < G->n;i++)
 73     {
 74         p = G->adjlist[i].firstarc;
 75         printf("%3d:",i);
 76         while(p != NULL)
 77         {
 78             printf("%3d[%3d]->",p->adjvex,p->weight);
 79             p = p->nextarc;
 80         } 
 81         printf("#\n");
 82     }    
 83 } 
 84 //销毁图(邻接表储存结构) 
 85 void  DestroyGrapgh(AdjGraph *G)
 86 { 
 87     ArcNode *pre,*p;
 88     for(int i = 0;i < G->n;i++)
 89     {
 90         pre = G->adjlist[i].firstarc;
 91         if(pre != NULL)
 92         {
 93             p = pre->nextarc;
 94             while(p != NULL)
 95             {
 96                 free(pre);
 97                 pre = p;
 98                 p = p->nextarc;
 99             }
100             free(pre);
101         }
102     }
103     free(G);
104 } 
105 //将邻接矩阵转换为邻接表
106 void MatToList(MatGraph g,AdjGraph *&G)
107 {
108     ArcNode *p;
109     G = (AdjGraph *)malloc(sizeof(AdjGraph));    
110     G->n = g.n; G->e = g.e;
111     for(int i=0; i < g.n;i++)
112         for(int j = g.n-1;j >= 0;j--)
113         {
114             if(g.edges[i][j]!=0 && g.edges[i][j]!=INF)
115             {
116                 p = (ArcNode *)malloc(sizeof(ArcNode));
117                 p->adjvex = j; p->weight = g.edges[i][j];
118                 p->nextarc = G->adjlist[i].firstarc;
119                 G->adjlist[i].firstarc = p; 
120             }
121         } 
122 } 
123 
124 //将邻接表转换为邻接矩阵 
125  
126 void ListToMat(AdjGraph *G,MatGraph g)
127 {
128     ArcNode *p;
129     for(int i = 0;i < G->n;i++)
130     {
131         p = G->adjlist[i].firstarc;
132         while(p != NULL)
133         {
134             g.edges[i][p->adjvex] = p->weight;
135             p = p->nextarc;
136         }
137     }
138     g.n = G->n;
139     g.e = G->e;
140 }
  1 //深度优先遍历
  2 int visited[MAXV] = {0};
  3 void DFS(AdjGraph *G,int v)
  4 {
  5     ArcNode *p;
  6     visited[v] = 1;
  7     printf("%d ",v);
  8     p = G->adjlist[v].firstarc;
  9     while(p!=NULL) 
 10     {
 11         if(visited[p->adjvex] == 0)
 12             DFS(G,p->adjvex);
 13         p=p->nextarc;
 14     }
 15 } 
 16 //广度优先遍历
 17 const int MaxSize = 100;
 18 typedef struct{
 19     int data[MaxSize];
 20     int front;
 21     int rear;
 22 }SqQueue; 
 23 
 24 void InitQueue(SqQueue *&qu)
 25 {
 26     qu = (SqQueue*)malloc(sizeof(SqQueue));
 27     qu->front = -1;
 28     qu->rear = -1;
 29 }
 30 
 31 bool enQueue(SqQueue *&qu,int b)
 32 {
 33     if((qu->rear + 1) % MaxSize == qu->front)
 34         return false;
 35     qu->rear = (qu->rear + 1) % MaxSize;
 36     qu->data[qu->rear] = b;
 37     return true;
 38 }
 39 
 40 bool deQueue(SqQueue *&qu,int &b)
 41 {
 42     if(qu->front == qu->rear)
 43         return false;
 44     qu->front = (qu->front + 1) % MaxSize;
 45     b = qu->data[qu->front];
 46 }
 47 
 48 bool QueueEmpty(SqQueue *&qu)
 49 {
 50     return qu->front == qu->rear;
 51 }
 52 
 53 void BFS(AdjGraph *G,int v)
 54 {
 55     int w,i;ArcNode *p;
 56     SqQueue *qu;
 57     InitQueue(qu);
 58     int visited[MAXV];
 59     for (int i = 0; i < G->n; ++i)
 60         visited[i] = 0;
 61     printf("%2d\n", v);
 62     enQueue(qu,v);
 63     while(!QueueEmpty(qu))
 64     {
 65         deQueue(qu,w);
 66         p = G->adjlist[w].firstarc;
 67         while(p!=NULL)
 68         {
 69             if(visited[p->adjvex] == 0)
 70             {
 71                 printf("%2d\n", p->adjvex);
 72                 visited[p->adjvex] = 1;
 73                 enQueue(qu,p->adjvex);
 74             }
 75             p = p->nextarc;
 76         }
 77     }
 78     printf("\n");
 79 } 
 80 void InDegree(MatGraph g)
 81 {
 82     int i,j,n;
 83     cout<<"?????????????????"<<endl;
 84     for(j=0;j<g.n;j++)
 85     {
 86         n = 0;
 87         for(i = 0;i < g.n;i++)
 88             if(g.edges[i][j]!=0)
 89                 n++;
 90         cout<<"?????"<<i<<":"<<n<<endl;
 91     } 
 92 }
 93 
 94 void OutDegree(MatGraph g)
 95 {
 96     int i,j,n;
 97     cout<<"?????????3??????"<<endl;
 98     for(i=0;i<g.n;i++)
 99     {
100         n = 0;
101         for(j = 0;j < g.n;j++)
102             if(g.edges[i][j]!=0)
103                 n++;
104         cout<<"?????"<<i<<":"<<n<<endl;
105     } 
106 }
107 
108 void ZeroDegree(MatGraph g)
109 {
110     int i,j,n;
111     cout<<"3?????a0?????????"<<endl;
112     for(i = 0;i<g.n;i++)
113     {
114         n = 0;
115         for(j = 0;j<g.n;j++)
116             if(g.edges[i][j]!=0)
117                 n++;
118         if(n == 0)
119             cout<<i<<endl;
120     }
121 }
122 
123 void InDegree1(AdjGraph *G)
124 {
125     ArcNode *p;
126     int A[MAXV],i;
127     for(i = 0;i<G->n;i++)
128         A[i] = 0;
129     for(i = 0;i<G->n;i++)
130     {
131         p = G->adjlist[i].firstarc;
132         while(p!=NULL)
133         {
134             A[p->adjvex]++;
135             p = p->nextarc;
136         }
137     }
138     cout<<"?????????????:"<<endl;
139     for(i = 0; i < G->n ;i++)
140         cout<<"?????"<<i<<":"<<A[i]<<endl; 
141 }
142 
143 void OutDegree2(AdjGraph *G)
144 {
145     ArcNode *p;
146     int A[MAXV],i;
147     for(i = 0;i<G->n;i++)
148         A[i] = 0;
149     for(i = 0;i<G->n;i++)
150     {
151         p = G->adjlist[i].firstarc;
152         while(p!=NULL)
153         {
154             A[i]++;
155             p = p->nextarc;
156         }
157     }
158     cout<<"???????3????:"<<endl;
159     for(i = 0; i < G->n ;i++)
160         cout<<"?????"<<i<<":"<<A[i]<<endl; 
161 }
162 
163 void ZeroDegree2(AdjGraph *G)
164 {
165     ArcNode *p;
166     cout<<"3?????a0???????:"<<endl;
167     for(int i=0;i<G->n;i++)
168     {
169         p = G->adjlist[i].firstarc;
170         if(p == NULL)
171             cout<<i<<endl;
172     }
173 }
174 
175 
176 void findPath(AdjGraph *G,int u,int v,int path[],int d,int length)
177 {
178     int w,i;
179     ArcNode *p;
180     path[d] = u; d++;
181     visited[u] = 1;
182     if(u == v && d > 0)
183     {
184         cout<<"the length of path:"<<length<<"\n"<<endl;
185         for(i = 0;i<d;i++)
186             cout<<path[i]<<" ";
187         cout<<endl; 
188     }
189     p = G->adjlist[u].firstarc;
190     while(p!=NULL)
191     {
192         w = p->adjvex;
193         if(visited[w] == 0)
194             findPath(G,w,v,path,d,p->weight+length);
195         p = p->nextarc;
196     }
197     visited[u] = 0;
198 }
199 
200 //examine if there is a simple path form v to w
201 bool existPath(AdjGraph *G,int v,int w)
202 {
203     ArcNode *p;
204     visited[v] = 1;
205     if(v == w)
206         return true;
207     else
208     {
209         p = G->adjlist[v].firstarc;
210         while(p != NULL)
211         {
212             if(visited[p->adjvex] == 0)
213                 return existPath(G,p->adjvex,w);
214             p = p->nextarc;
215         }
216     }
217     return false;
218 }
219 //output one simple path from v to w
220 void findAPath(AdjGraph *G,int v,int w, int path[],int length)
221 {
222     ArcNode *p;
223     visited[v] = 1;
224     path[length++] = v;
225     if(v == w && length > 1)
226      {
227          for (int i = 0; i < length; ++i)
228         {
229             printf("%2d", path[i]);
230         }
231         printf("\n");
232         return;
233     }
234     p = G->adjlist[v].firstarc;
235     while(p!=NULL)
236     {
237         if (visited[p->adjvex] == 0)
238         {
239             findAPath(G,p->adjvex,w,path,length);
240         }
241         p = p->nextarc;
242     }
243 }
244 
245 //output all simple paths from v to w
246 void findAllPath(AdjGraph *G,int v,int w,int path[],int length)
247 {
248     ArcNode *p;
249     visited[v] = 1;
250     //printf("visited: %d\n", v );
251     path[length++] = v;
252     if (v == w && length > 1)
253     {
254         for (int i = 0; i < length; ++i)
255         {
256             printf("%2d", path[i]);
257         }
258         printf("\n");
259     }
260     else
261     {
262         p = G->adjlist[v].firstarc;
263         while(p!=NULL)
264         {
265             if (visited[p->adjvex] == 0)
266             {
267                 findAllPath(G,p->adjvex,w,path,length);
268             }
269             else if(p->adjvex == w)
270             {
271                 path[length++] = w;
272                 for (int i = 0; i < length; ++i)
273                 {
274                     printf("%2d", path[i]);
275                 }
276                 printf("\n");
277             }
278             p = p->nextarc;
279         }
280     }
281     visited[v] = 0;
282 }
283 
284 //output all paths from v to w which length is l
285 void findAllPathLengthL(AdjGraph *G,int v,int w,int path[],int length,int l)
286 {
287     ArcNode *p;
288     visited[v] = 1;
289     //printf("visited: %d\n", v );
290     path[length++] = v;
291     if (v == w && length == l)
292     {
293         for (int i = 0; i < length; ++i)
294         {
295             printf("%2d", path[i]);
296         }
297         printf("\n");
298     }
299     p = G->adjlist[v].firstarc;
300     while(p!=NULL)
301     {
302         if (visited[p->adjvex] == 0)
303         {
304             findAllPathLengthL(G,p->adjvex,w,path,length,l);
305         }
306         p = p->nextarc;
307     }
308     visited[v] = 0;
309 }
310 
311 typedef struct
312 {
313     int data;
314     int parent;
315 }QueueNode;
316 //output the shorest path from v to w
317 void findShorstPathNonePri(AdjGraph *G,int v,int w)
318 {
319     QueueNode path[MAXV];int rear = -1,front = -1;
320     QueueNode node;
321     ArcNode *p;
322 
323     visited[v] = 1;
324     node.data = v;node.parent = -1;
325     path[++rear] = node;
326     while(rear != front)
327     {
328         node = path[++front];
329         if (node.data == w)
330         {
331             while(node.parent != -1)
332             {
333                 printf("%2d", node.data);
334                 node = path[node.parent];
335             }
336             printf("%2d\n", node.data);
337             printf("\n");
338             return;
339         }
340         p = G->adjlist[node.data].firstarc;
341         while(p != NULL)
342         {
343             if(visited[p->adjvex] == 0)
344             {
345                 visited[p->adjvex] = 1;
346                 node.data = p->adjvex;
347                 node.parent = front;
348                 path[++rear] = node;
349             }
350             p = p->nextarc;
351         }
352     }
353 }
354 
355 //Prim
356 void Prim(MatGraph g,int v)
357 {
358     int lowcost[MAXV];
359     int MIN;
360     int closest[MAXV];
361     int k;
362     for (int i = 0; i < g.n; ++i)
363     {
364         lowcost[i] = g.edges[v][i];
365         closest[i] = v;
366     }
367     for (int i = 0; i < g.n; ++i)
368     {
369         MIN = INF;
370         for (int j = 0; j < g.n; ++j)
371             if (lowcost[j] != 0 && lowcost[j] < MIN)
372             {
373                 MIN = lowcost[j];
374                 k = j;
375             }    
376         printf("边(%d,%d)权为:%d\n", closest[k],k,MIN);
377         lowcost[k] = 0;
378         for (int j = 0; j < g.n; ++j)
379             if (lowcost[j] != 0 && g.edges[k][j] < lowcost[j])
380             {
381                 lowcost[j] = g.edges[k][j];
382                 closest[j] = k;
383             }
384     }
385 }
386 
387 //克鲁斯卡尔算法
388 
389 typedef struct
390 {
391     int u;
392     int v;
393     int w;
394 }Edge;
395 
396 void swap(Edge &E1,Edge &E2)
397 {
398     Edge temp;
399     temp = E1;
400     E1 = E2;
401     E2 = temp;
402 }
403 
404 void InsertSort(Edge *E, int n)
405 {
406     if(n == 1)
407         return;
408     InsertSort(E,n-1);
409     for (int i = 0; i < n-1; ++i)
410         if (E[i].w > E[n-1].w)
411         {
412             for (int j = n-1; j > i; j--)
413                 swap(E[j],E[j-1]);
414             break;
415         }
416 }
417 
418 void Kruskal(MatGraph g)
419 {
420     int u1,v1,sn1,sn2,j;
421     int vset[MAXV];
422     Edge E[MaxSize];
423     int k = 0;
424     for (int i = 0; i < g.n; ++i)
425         for (int j = 0; j <= i; ++j)
426         {    
427             if (g.edges[i][j] != 0 && g.edges[i][j] != INF)
428             {
429                 E[k].u = i; E[k].v = j; E[k].w = g.edges[i][j];
430                 k++;
431             }
432         }
433     InsertSort(E,g.e);
434     for (int i = 0; i < g.n; ++i)
435         vset[i] = i;    
436     k = 1;
437     j = 0;
438     while(k < g.n)
439     {
440         u1 = E[j].u; v1 = E[j].v;
441         sn1 = vset[u1];
442         sn2 = vset[v1];
443         if (sn1 != sn2)
444         {
445             printf("(%d,%d):%d\n", u1, v1, E[j].w);
446             k++;
447             for (int i = 0; i < g.n; ++i)
448                 if (vset[i] == sn2)
449                     vset[i] = sn1;
450         }    
451         j++;
452     }
453 }
454 
455 //改进的克鲁斯卡尔算法
456 
457 void Kruskal_pro(MatGraph g)
458 {
459     //省略哈哈哈哈哈哈哈哈
460     //思路:把插入排序改为堆排序
461     //      用并查集实现判断是否环路
462 }
463 
464 //狄克斯特拉算法
465 
466 void Dispath(MatGraph g,int dist[], int path[], int S[], int v)
467 {
468     int apath[MAXV],d;
469     int k;
470     for(int i=0; i<g.n; i++)
471         if (S[i] == 1 & i!= v)
472         {
473             printf("从顶点%d到顶点%d的路径长度为%d\n", v, i, dist[i]);
474             d = 0; apath[d] = i;
475             k = path[i];
476             if(k == -1)
477                 printf("无路径\n");
478             else
479             {
480                 while(k != v)
481                 {
482                     d++; apath[d] = k;
483                     k = path[k];
484                 }
485                 d++;apath[d] = k;
486                 printf("%d", apath[d]);
487                 for(int j = d-1; j>=0; j--)
488                     printf(",%d", apath[j]);
489                 printf("\n");
490             }
491         }
492 }
493 
494 void Dijkstra(MatGraph g,int v)
495 {
496     int dist[MAXV],path [MAXV];
497     int S[MAXV];
498     int MINdis;
499     int u;
500     for (int i = 0; i < g.n; ++i)
501     {
502         dist[i] = g.edges[v][i];
503         S[i] = 0;
504         if (g.edges[v][i] < INF)
505             path[i] = v;
506         else
507             path[i] = -1;
508     }
509     S[v] = 1; path[v] = 0;
510     for (int i = 0; i < g.n-1;++i)
511     {    
512         MINdis = INF;
513         for (int j = 0; j < g.n; ++j)
514             if (S[j] == 0 && dist[j] < MINdis)
515             {
516                 u = j;
517                 MINdis = dist[j];
518             }
519         S[u] = 1;
520         for (int j = 0; j < g.n; ++j)
521             if(S[j] == 0)
522                 if(g.edges[u][j]<INF && dist[u] + g.edges[u][j]<dist[j])
523                 {
524                     dist[j] = dist[u] + g.edges[u][j];
525                     path[j] = u;
526                 }
527     }
528     Dispath(g,dist,path,S,v);
529 }
530 
531 //弗洛伊德算法
532 
533 void Dispath1(MatGraph g, int A[][MAXV], int path[][MAXV])
534 {
535     int apath[MAXV],d,k;
536     for (int i = 0; i < g.n; ++i)
537     {
538         for (int j = 0; j < g.n; ++j)
539         {
540             if (A[i][j] != INF && i != j)
541             {
542                 printf("从顶点%d到顶点%d的路径为:\n", i, j);
543                 k = path[i][j];
544                 d = 0; apath[d] = j;
545                 while(k != -1 && k!= i)
546                 {
547                     d++; apath[d] = k;
548                     k = path[i][k];
549                 }
550                 d++;apath[d] = i;
551                 printf("%d", apath[d]);
552                 for (int s = d-1; s >= 0; s--)
553                 {
554                     printf(",%d", apath[s]);
555                 }
556                 printf("路径长度为:%d\n", A[i][j]);
557             }
558         }
559     }
560 }
561 
562 void Floyd(MatGraph g)
563 {
564     int A[MAXV][MAXV],path[MAXV][MAXV];
565     for (int i = 0; i < g.n; ++i)
566         for (int j = 0; j < g.n; ++j)
567         {
568             A[i][j] = g.edges[i][j];
569             if (i != j && g.edges[i][j] < INF)
570                 path[i][j] = i;
571             else
572                 path[i][j] = -1;
573         }
574     for (int k = 0; k < g.n; ++k)
575         for (int i = 0; i < g.n; ++i)
576             for (int j = 0; j < g.n; ++j)
577                 if (A[i][j] > A[i][k]+A[k][j])
578                 {
579                     A[i][j] = A[i][k]+A[k][j];
580                     path[i][j] = path[k][j];
581                 }
582     Dispath1(g,A,path);
583 }
584 
585 //拓扑排序
586 // typedef struct 
587 // {
588 //     VertexType data;
589 //     int count;
590 //     ArcNode *firstarc;
591 // }VNode;
592 
593 void TopSort(AdjGraph *G)
594 {
595     int St[MAXV],top = -1;
596     ArcNode *p;
597     for (int i = 0; i < G->n; ++i)
598         G->adjlist[i].count = 0;
599     for (int i = 0; i < G->n; ++i)
600     {
601         p = G->adjlist[i].firstarc;
602         while(p != NULL)
603         {
604             G->adjlist[p->adjvex].count++;
605             p = p->nextarc;
606         }
607     }
608     for (int i = 0; i < G->n; ++i)
609         if (G->adjlist[i].count == 0)
610             St[++top] = i;
611     while(top != -1)
612     {
613         int i = St[top--];
614         printf("%d", i);
615         p = G->adjlist[i].firstarc;
616         while(p != NULL)
617         {
618             int j = p->adjvex;
619             G->adjlist[j].count--;
620             if(G->adjlist[j].count == 0)
621                 St[++top] = j;
622             p = p->nextarc;
623         }
624     }
625 }
posted @ 2020-04-24 17:18  whxway  阅读(324)  评论(0编辑  收藏  举报