图的任意顶点都有可能和其他顶点相邻接,因此在访问某个顶点之后可能沿着某条路径又回到了该顶点上。为了避免对于一个顶点重复访问,可以设置一个辅助数组visited[n],用于标记访问过的顶点。
1.1深度优先遍历
假设初始状态图中的所有顶点都未被访问,步骤如下:
1.选取图中某一顶点vi为出发点,访问并标记该顶点。
2.以vi为当前顶点,依次搜索vi的每个邻接点vj。若vj已被访问过,则搜索vi的下一个邻接点,否则访问和标记邻接点vj。
3…以vj为当前顶点,重复步骤2,直到图中的所有顶点都被访问了。
4.若图中尚有未被访问的定点则可以任取图中的一个未被访问的顶点作为出发点,重复上述过程,直至图中所有的顶点都被访问。
DFSA算法(以邻接矩阵为存储结构的深度优先遍历):
int visited[n];
void DFSA(graph G, int i)//遍历邻接矩阵
{
int j;
printf("node:%c \n",G.vexs[i]);
visited[i]=1;
for(j=0;j<n;j++)
{
if((G.arcs[i][j]==1)&&(visited[j]==0))
{
DFSA(G,j);
}
}
}
上述算法的复杂度为O(n2).
DFSL算法(以邻接表为存储结构的深度优先遍历):
void DFSL(vexnode Ga[],int i)
{
edgenode *p;
printf("node:%c\n",Ga[i].vertex);
visited[i]=1;
p=Ga[i].link;
while(p!=NULL)
{
if(visited[p->adjvex]==0)
{
DFSL(Ga,p->adjvex);
p=p->next;
}
}
}
1.2广度优先遍历
假设初始状态图中的所有顶点都未被访问,步骤如下:
1.从图中某一顶点vi出发,先访问vi,然后访问vi的所有邻接点vj;当所有的vj都被访问后,再访问vj的邻接点vk。
2.重复上述步骤,直到图中所有已被访问的顶点的邻接点也被访问。
3.若图为非连通图,则可以任取图中的一个未被访问的顶点作为出发点,重复上述过程,直至图中所有的顶点都被访问。
此种方法的特点为:“先被访问顶点的邻接点”先于“后被访问的顶点的邻接点”
BFSA算法如下:
void BFSA(graph G,int i)
{
int i,j;
SeqQueue *Q;
InitQueue(Q);
printf("%c\n",G.vexs[k]);
visited[k]=1;
ENQUEUE(Q,k);
while(!EMPTY(Q))
{
i=DEQUEUE(Q);
for(j=0;j<n;j++)
{
if((G.arcs[i][j]==1)&&(visited[j]!=1))
{
printf("%c\n",G.vexs[j]);
visited[j]=1;
ENQUEUE(Q,j);
}
}
}
}