遍历图的基本搜索方法有两种:
深度优先搜索DFS(Depth First Search)和广度优先搜索BFS(Broad First Search)。这两种方法都适用于有向图和无向图。
深度优先搜索的的基本思想:
(1)访问顶点 v ;
(2)从 v 的未被访问的邻接点中选取一个顶点 w ,从 w 出发进行深度优先遍历。若 v 的邻接点都被访问过则回溯;
(3)重复(1)(2)两步,直至图中所有和 v 有路径相通的顶点都被访问到。
基于邻接矩阵的DFS:
int visited[MAX];//访问标志数组
void DFS(MGraph G,int i)
{
visited[i] = 1;
printf("%c ",G.vertex[i]);
for (int j = 0; j < G.vertexNum; j++)
if (G.arc[i][j] == 1 && !visited[j])
DFS(G,j);//对访问的邻接定点递归调用
}
//操作,连通图和非连通图都适用
void DFSHandle(MGraph G)
{
int i;
for (i = 0; i < G.vertexNum; i++)
visited[i] = 0;//初始化所有顶点都未被访问
for (i = 0; i < G.vertexNum; i++)
if (!visited[i])//若是连通图只执行一次
DFS(G,i);
}
基于邻接表的DFS:
int visited[MAX];//访问标志数组
void DFS(GraphAdjList GL,int i)
{
EdgeNode * p;
visited[i] = 1;
printf("%c ",GL->adjList[i].data);
p = GL->adjList[i].firstedge;
while (p)
{
if (!visited[p->adjvex])
DFS(GL,p->adjvex);
p = p->next;
}
}
//操作,连通图和非连通图都适用
void DFSHandle(GraphAdjList GL)
{
int i;
for (i = 0; i < GL->vertexNum; i++)
visited[i] = 0;//初始化所有顶点都未被访问
for (i = 0; i < GL->vertexNum; i++)
if (!visited[i])//若是连通图只执行一次
DFS(GL,i);
}
广度优先搜索的基本思想:
(1)访问顶点 v ;
(2)依次访问 v 的各个未被访问的邻接点v1、v2、v3....vk;
(3)分别从 v1,v2,...,vk 出发依次访问它们未被访问的邻接点,并使“先被访问顶点的邻接点”先于“后被顶点访问的邻接点”被访问。直至途中所有与顶点 v 有路径相通的顶点都被访问到。
基于邻接矩阵的BFS:
int visited[MAX];//访问标志数组
void BFSHandle(MGraph G)
{
int i,j;
Queue Q;
for (i = 0; i < G.vertexNum; i++)
visited[i] = 0;//初始化所有顶点都未被访问
InitQueue(&Q);//初始化一辅助用的队列
for (i = 0; i < G.vertexNum; i++)//对每一个顶点做循环
{
if (!visited[i])
{
visited[i] = 1;
printf("%c ",G.vertex[i]);
EnQueue(&Q,i);//将此顶点入队列
while (!QueueEmpty(Q))//若当前队列不为空
{
DeQueue(&Q,&i);//将队列中元素出队列,赋值给i
for (j = 0; j < G.vertexNum; j++)
if (G.arc[i][j] == 1 && !visited[j])
{
visited[j] = 1;
printf("%c ",G.vertex[j]);
EnQueue(&Q,j);
}
}
}
}
}
基于邻接表的BFS:
int visited[MAX];//访问标志数组
void BFSHandle(GraphAdjList GL)
{
int i;
EdgeNode *p;
Queue Q;
for (i = 0; i < GL->vertexNum; i++)
visited[i] = 0;//初始化所有顶点都未被访问
InitQueue(&Q);//初始化一辅助用的队列
for (i = 0; i < GL->vertexNum; i++)//对每一个顶点做循环
{
if (!visited[i])
{
visited[i] = 1;
printf("%c ",GL->adjList[i].data);
EnQueue(&Q,i);//将此顶点入队列
while (!QueueEmpty(Q))//若当前队列不为空
{
DeQueue(&Q,&i);//将队列中元素出队列,赋值给i
p = GL->adjList[i].firstedge;
while (p)
{
if (!visited[p->adjvex])
{
visited[p->adjvex] = 1;
printf("%c ",GL->adjList[p->adjvex].data);
Enqueue(&Q,p->adjvex);
}
p = p->next;//指向下一个邻接点
}
}
}
}
}