有向图G:
1.选用何种结构存储有向图?
选用十字链表的结构来存储图
2.选用何种遍历方式?
选用深度优先搜索
3.思路
3.1 首先从图G上某个顶点出发沿以该顶点为尾的弧深度优先搜索,在顶点深度优先搜索结束之时把该顶点存放到辅助数组finished中(程序中实际存放的是该顶点在图中的位置,当然顶点的位置是人为定的,a的位置是0,b的位置是1,c的位置是2,d的位置是3,顶点在图的结构体中用数组存起来)。
解释:假如从a顶点开始深度遍历,过程是a->c->d,那么finished数组的值是 {3,2,0},深度遍历完后,a顶点的访问才结束,所以a最后退出这次遍历,a存放到finished数组最后。
3.2 然后从最后搜索完成的顶点(即finished数组中最后一个元素)出发,沿着以该顶点为头的弧作逆向的深度优先搜索遍历,若以该顶点的这次深度遍历不能访问到图中所有的顶点,就从数组finished中最后完成搜索的顶点(还未被访问的)再次深度优先搜索遍历,以此类推,直到图中所有的顶点都被访问过。
解释:假如finished数组中的值是{1,3,2,0},从0开始逆向的深度优先搜索,能访问到2,3,但是1访问不到,假如1前面还有4,5顶点({4,5,1}),因为数组finished是按退出深度优先搜索的顺序存进去的,所以1就是当前最后完成深度优先搜索的顶点(相比4,5顶点),因此再从1顶点开始逆向深度优先遍历,以此类推,直到所有顶点都访问到。
3.3 打印出来的结果就是各强连通分量的顶点集。
4.原理
强连通分量的意思是 有向图G=(V,{A}),(V代表顶点集,A代表弧),如果对于每一对vi,vj属于V,vi不等于vj,从vi到vj和从vj到vi都存储路径,称G是强连通图,而有向图中的极大连通子图叫有向图的强连通分量(如vi到vj有路径,vj到vi也要有路径,才叫强连通)。根据图,从a顶点根据以弧尾是a的弧能访问到d,那么从a顶点根据以弧头是a的弧也能访问到d,说明a到d有路径,d到a也有路径,即是通的。
------------------------------------------------------------------------------------------------------------
源码地址:git@github.com:hglspace/OlGraph.git
-------------------------------------------------------------------------------------------------------------
myhead.c
#define MAX_VERTEX_NUM 4//人为设置顶点数为4
typedef int Bool;//自定义布尔型变量
#define True 1//以访问状态
#define False 0//未访问状态
//十字链表存储有向图
struct ArcBox{ //弧结点
int tailvex;//尾结点在图中的位置
int headvex;//头结点在图中的位置
struct ArcBox * hlink;//弧头相同的下一条弧
struct ArcBox * tlink;//弧尾相同的下一条弧
Bool mark;//访问的标志 True代表访问过,False代表没有访问过
};
struct VexNode{ //顶点结点
char data;//顶点信息
struct ArcBox * firstin;//以该顶点为弧头的第一条弧
struct ArcBox * firstout;//以该顶点为弧尾的第一条弧
};
struct OlGraph{
struct VexNode xlist[MAX_VERTEX_NUM];//顶点结点数组
int vexnum;//当前顶点数量
int arcnum;//当前弧的数量
};
//自定义头文件
-----------------------------------------------------------operateGraph.c
#include <stdio.h>
#include "myhead.h"
#include <stdlib.h>
Bool visits[MAX_VERTEX_NUM];//定义顶点辅助数组,记录顶点是否访问过
int count=0;//定义全局变量,辅助数组finished使用
struct ArcBox * edg[MAX_VERTEX_NUM];//定义全局弧指针数组,记录弧地址,方便把弧的是否访问过的状态重置
/*