Status DFSArticul(MGraph graph, int vex_index, int *count, int articulated[MAXVEX + 1], int visited_sequ[MAXVEX], int vex_can_arrived[MAXVEX]) { int nextvex; visited_sequ[vex_index] = *count; ++*count; vex_can_arrived[vex_index] = visited_sequ[vex_index]; //min(自己的序号,儿子能到达的最早序号,自己的祖先边中祖先的序号) for (nextvex = FirstAdjVex(graph, vex_index); nextvex != -1; nextvex = NextAdjVex(graph, vex_index, nextvex)) { if (visited_sequ[nextvex] == -1) { DFSArticul(graph, nextvex, count, articulated, visited_sequ, vex_can_arrived); if (vex_can_arrived[nextvex] < vex_can_arrived[vex_index]) { vex_can_arrived[vex_index] = vex_can_arrived[nextvex]; } if (vex_can_arrived[nextvex] >= visited_sequ[vex_index]) { int i; for (i = 1; i <= articulated[0]; ++i) //如果该点已经添加过了,则不必再添加 if (articulated[i] == graph.vexs[vex_index]) break; if (i == articulated[0] + 1) { ++articulated[0]; articulated[articulated[0]] = graph.vexs[vex_index]; } } } else if (visited_sequ[nextvex] < vex_can_arrived[vex_index]) { vex_can_arrived[vex_index] = visited_sequ[nextvex]; } } return OK; }
void FindArticul(ALGraph G) { /* 连通图G以邻接表作存储结构,查找并输出G上全部关节点。算法7.10 */ /* 全局量count对访问计数。 */ int i,v; ArcNode *p; count=1; low[0]=visited[0]=1; /* 设定邻接表上0号顶点为生成树的根 */ for(i=1;i<G.vexnum;++i) visited[i]=0; /* 其余顶点尚未访问 */ p=G.vertices[0].firstarc; v=p->adjvex; DFSArticul(G,v); /* 从第v顶点出发深度优先查找关节点 */ if(count<G.vexnum) /* 生成树的根有至少两棵子树 */ { printf("%d %s\n",0,G.vertices[0].data); /* 根是关节点,输出 */ while(p->nextarc) { p=p->nextarc; v=p->adjvex; if(visited[v]==0) DFSArticul(G,v); } } }
void DFSArticul(ALGraph G, int v0 ) { // 算法7.11 // 从第v0个顶点出发深度优先遍历图G,查找并输出关节点 int min,w; struct ArcNode *p; visited[v0] = min = ++count; // v0是第count个访问的顶点 for (p=G.vertices[v0].firstarc; p!=NULL; p=p->nextarc) { // 检查v0的每个邻接顶点 w = p->adjvex; // w为v0的邻接顶点 if (visited[w] == 0) { // w未曾被访问,是v0的孩子 DFSArticul(G, w); // 返回前求得low[w] if (low[w] < min) min = low[w]; if (low[w] >= visited[v0]) printf(v0, G.vertices[v0].data); // 输出关节点 } else if (visited[w] < min) min = visited[w]; // w已被访问,w是v0在生成树上的祖先 }//for low[v0] = min; } // DFSArticul
void DFSArticul(ALGraph G,int v0) { /* 从第v0个顶点出发深度优先遍历图G,查找并输出关节点。算法7.11 */ int min,w; ArcNode *p; visited[v0]=min=++count; /* v0是第count个访问的顶点 */ for(p=G.vertices[v0].firstarc;p;p=p->nextarc) /* 对v0的每个邻接顶点检查 */ { w=p->adjvex; /* w为v0的邻接顶点 */ if(visited[w]==0) /* w未曾访问,是v0的孩子 */ { DFSArticul(G,w); /* 返回前求得low[w] */ if(low[w]<min) min=low[w]; if(low[w]>=visited[v0]) printf("%d %s\n",v0,G.vertices[v0].data); /* 关节点 */ } else if(visited[w]<min) min=visited[w]; /* w已访问,w是v0在生成树上的祖先 */ } low[v0]=min; }
Status FindArticul(MGraph graph, int articulated[MAXVEX + 1]) { int visited_sequ[MAXVEX]; //被访问的序列号 int vex_can_arrived[MAXVEX]; //能到达的最早被访问的序列号 int index, i; int count; if (graph.vexnum < 2) return ERROR; if (!articulated) return ERROR; articulated[0] = 0; count = 0; for (i = 0; i < graph.vexnum; ++i) //访问序列初始化 visited_sequ[i] = -1; for (i = 0; i < graph.vexnum; ++i) { if (visited_sequ[i] == -1) { visited_sequ[i] = count; ++count; if ((index = FirstAdjVex(graph, i)) == -1) //不能存在度为0的点(独立构成一个连通分量) return ERROR; // 对根的一棵子树进行遍历,找出关节点 DFSArticul(graph, index, &count, articulated, visited_sequ, vex_can_arrived); // 判断根是否是关节点 for (index = FirstAdjVex(graph, i); index != -1; index = NextAdjVex(graph, i, index)) { if (visited_sequ[index] == -1) { ++articulated[0]; articulated[articulated[0]] = graph.vexs[i]; break; } } } } return OK; }