连通图的关节点

全局变量

1 static int count = 0;
2 static int low[MAXVEX] = { 0 };/*存放结点及其子孙的回边指向的最大祖先结点*/
3 static int visited[MAXVEX] = { 0 };

FindArticul函数

 1 /*连通图G以邻接表作存储结构,查找并输出G上全部关节点*/
 2 void FindArticul(AdjList* G)
 3 {
 4     int vex = 0;
 5     ArcNode* P = NULL;
 6 
 7     count = 1;
 8     visited[0] = 1;
 9     P = G->vex[0].head;
10     vex = P->adjvex;
11 
12     DFSArticul(G, vex);
13 
14     if (count < G->vexnum)
15     {
16         printf("%c\n", G->vex[0].vexdata);
17         while (P->next)
18         {
19             P = P->next;
20             vex = P->adjvex;
21             if (visited[vex] == 0)
22             {
23                 DFSArticul(G, vex);
24             }
25         }
26     }
27 }

DFSArticul函数

 1 /*从第vex个顶点出发深度优先遍历图G,查找并输出关节点*/
 2 void DFSArticul(AdjList* G, int vex)
 3 {
 4     int flag = 1;
 5     int min = 0;/*最小祖先结点*/
 6     int adjvex = 0;
 7     ArcNode* P = NULL;
 8 
 9     count++;
10     min = count;
11     visited[vex] = count;
12 
13     for (P = G->vex[vex].head; P; P = P->next)
14     {
15         adjvex = P->adjvex;
16         if (visited[adjvex] == 0)
17         {
18             DFSArticul(G, adjvex);
19             if (low[adjvex] < min)
20             {
21                 min = low[adjvex];
22             }
23             if (low[adjvex] >= visited[vex] && flag)
24             {
25                 printf("%c\n", G->vex[vex].vexdata);
26                 flag = 0;/*避免重复打印关节点*/
27             }
28         }
29         if (visited[adjvex] < min)
30         {
31             min = visited[adjvex];
32         }
33     }
34 
35     low[vex] = min;
36 }

源代码

  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 adjvex;
  9     struct ArcNode* next;
 10 }ArcNode;
 11 
 12 typedef struct VexNode
 13 {
 14     char vexdata;
 15     ArcNode* head;
 16 }VexNode;
 17 
 18 typedef struct
 19 {
 20     int vexnum;
 21     int arcnum;
 22     VexNode vex[MAXVEX];
 23 }AdjList;
 24 
 25 static int count = 0;
 26 static int low[MAXVEX] = { 0 };/*存放结点及其子孙的回边指向的最大祖先结点*/
 27 static int visited[MAXVEX] = { 0 };
 28 
 29 /*从第vex个顶点出发深度优先遍历图G,查找并输出关节点*/
 30 void DFSArticul(AdjList* G, int vex)
 31 {
 32     int flag = 1;
 33     int min = 0;/*最小祖先结点*/
 34     int adjvex = 0;
 35     ArcNode* P = NULL;
 36 
 37     count++;
 38     min = count;
 39     visited[vex] = count;
 40 
 41     for (P = G->vex[vex].head; P; P = P->next)
 42     {
 43         adjvex = P->adjvex;
 44         if (visited[adjvex] == 0)
 45         {
 46             DFSArticul(G, adjvex);
 47             if (low[adjvex] < min)
 48             {
 49                 min = low[adjvex];
 50             }
 51             if (low[adjvex] >= visited[vex] && flag)
 52             {
 53                 printf("%c\n", G->vex[vex].vexdata);
 54                 flag = 0;/*避免重复打印关节点*/
 55             }
 56         }
 57         if (visited[adjvex] < min)
 58         {
 59             min = visited[adjvex];
 60         }
 61     }
 62 
 63     low[vex] = min;
 64 }
 65 
 66 /*连通图G以邻接表作存储结构,查找并输出G上全部关节点*/
 67 void FindArticul(AdjList* G)
 68 {
 69     int vex = 0;
 70     ArcNode* P = NULL;
 71 
 72     count = 1;
 73     visited[0] = 1;
 74     P = G->vex[0].head;
 75     vex = P->adjvex;
 76 
 77     DFSArticul(G, vex);
 78 
 79     if (count < G->vexnum)
 80     {
 81         printf("%c\n", G->vex[0].vexdata);
 82         while (P->next)
 83         {
 84             P = P->next;
 85             vex = P->adjvex;
 86             if (visited[vex] == 0)
 87             {
 88                 DFSArticul(G, vex);
 89             }
 90         }
 91     }
 92 }
 93 
 94 /*查找并返回顶点vex在邻接表中位置*/
 95 int LocateVex(AdjList G, char vex)
 96 {
 97     int i = 0;
 98     for (i = 0; i < G.vexnum; i++)
 99     {
100         if (G.vex[i].vexdata == vex)
101         {
102             return i;
103         }
104     }
105     return -1;
106 }
107 
108 /*创建邻接表*/
109 void Create(AdjList* G)
110 {
111     int i = 0, j = 0, k = 0;
112     char vex1 = '\0';
113     char vex2 = '\0';
114     ArcNode* P = NULL;
115     ArcNode* Pre = NULL;
116     printf("请输入顶点数和边数(逗号分隔):");
117     scanf("%d%*c%d", &G->vexnum, &G->arcnum);
118     for (i = 0; i < G->vexnum; i++)
119     {
120         printf("请输入第%d个顶点:", i + 1);
121         scanf(" %c", &G->vex[i].vexdata);
122         G->vex[i].head = NULL;
123     }
124     for (k = 0; k < G->arcnum; k++)
125     {
126         printf("请输入第%d条边的两端点(逗号分隔):", k + 1);
127         scanf(" %c%*c%c", &vex1, &vex2);
128         i = LocateVex(*G, vex1);
129         j = LocateVex(*G, vex2);
130         /*把 j 链接到以 i 为弧尾的表中*/
131         P = (ArcNode*)calloc(1, sizeof(ArcNode));
132         P->adjvex = j;
133         if (G->vex[i].head == NULL)
134         {
135             G->vex[i].head = P;
136         }
137         else
138         {
139             Pre = G->vex[i].head;
140             while (Pre->next)
141             {
142                 Pre = Pre->next;
143             }
144             Pre->next = P;
145         }
146         /*把 i 链接到以 j 为弧尾的表中*/
147         P = (ArcNode*)calloc(1, sizeof(ArcNode));
148         P->adjvex = i;
149         if (G->vex[j].head == NULL)
150         {
151             G->vex[j].head = P;
152         }
153         else
154         {
155             Pre = G->vex[j].head;
156             while (Pre->next)
157             {
158                 Pre = Pre->next;
159             }
160             Pre->next = P;
161         }
162     }
163 }
164 
165 int main(void)
166 {
167     AdjList G;
168     Create(&G);
169     FindArticul(&G);
170     system("pause");
171     return 0;
172 }
源代码

 

posted @ 2022-01-27 10:05  吕辉  阅读(85)  评论(0)    收藏  举报