图的遍历涉及到一个遍历数组的定义visited[N],数组元素的初始状态为0,当顶点Vi被访问过之后,就置visited[i]为1。
图的遍历方法通常分为:深度优先搜索法和广度优先搜索法。
深度优先搜索算法:类似于树的前序遍历,是树的先根遍历的推广。
设G=(V,E)为任一无向图,从V(G)中任意一顶点v出发按照深度优先搜索法进行遍历的步骤如下:
(1)设p为搜索指针,使p指向节点p;
(2)访问p节点,然后使p指向与p相邻的且未曾访问的节点。
(3)若p不空,则重复步骤(2),否则执行步骤(4).
(4)沿着刚才访问的次序,反向回溯到一个尚有邻接顶点未曾访问过的节点,并使p指向这个未被访问的节点,然后重复步骤(2),直到所有节点都被访问到。
这个遍历过程是个递归过程,有个辅助全局变量visit[N]为记录各个节点是否有被访问过。
根据不同的存储结构,算法描述也不同。
邻接矩阵的算法描述(深度优先搜索算法):
visited[N];
void DFS(graph *g)
{
int i;
for(i=0;i<g->n;i++)//初始化全局变量数组visited[N]
visited[i]=0; //零代表了第i个节点没有被访问过
for(i=0;i<g->n;i++)//此处起到了(4)的作用
if(!visited[i])
DFSM(g,i);//或者DFSL(g,i);
}
void DFSM( graph *p,int i)//邻接矩阵上进行DFS遍历
{
int j;
printf("深度优先遍历结点:%c ",g->vertex[i]);
visited[i]=1;//假设g->vertex[i]为节点的编号,然后变访问标志为1
for(j=0;j<g->n;j++)
if(g->edges[i][j]==1&&!visited[j])//一个节点连有边时候,且该节点连结的另一个节点没有被访问过时候
DFSM(g,j);//采用递归继续访问
}
void DFSL(graph *g,int i)//邻接表的深度查找算法
{
pointer p;//节点类型
printf("%d ",g->adlist[i].data);//访问出发点,输出顶点数据
visited[i]=1;
for(p=g->adlist[n].first;p!=NULL;p=p->next)
if(!visited[p->vertex])//节点未被访问过时候,就采用递归进行访问
DFSL(g,p->vertex);
}
算法复杂度分析:
一个图有n个节点,e条边;
DFSM的时间复杂度为O(n^2);
DFSL的时间复杂度为O(n+e);