一、深度优先搜索遍历(DFS)
1、基本思想(类似于树的先序遍历):
①首先访问出发点v,并将其标记为已访问过;
②选取与v邻接的未被访问的任意一个顶点w,访问w;
③选取与w邻接的未被访问的任一顶点访问;
④以此重复进行。
当一个顶点所有的邻接顶点都被访问过时,则依次退回到最近被访问过的顶点。
若该顶点还有其他邻接顶点未被访问,则从这些未被访问过的顶点选取一个重复上述访问过程,直至途中所有顶点都被访问过为止。
2、以邻接表为存储结构的图的广度优先搜索遍历代码
//邻接表存储的定义表示
typedef struct ArcNode //边表结点定义
{
int adjvex; //该边所指向的结点的位置
ArcNode *nextarc; //指向下一条边的指针
int info; //该边的相关信息(如权值),这一句用的不多,可不写
}ArcNode;
typedef struct //顶点表结点定义
{
char data; //顶点信息
ArcNode *firstarc; //指向第一条边的指针
}VNode;
typedef struct //邻接表结构体定义
{
VNode adjlist[maxSize]; //邻接表
int n,e; //顶点数和边数
}AGraph; //图的邻接表类型
int visit[maxSize]; //数组visit作为顶点的访问标记,初始时所有元素均为0,表示所有顶点均为被访问
//邻接表存储的图的深度优先搜索遍历
void DFS(AGraph *G, int v){
ArcNode *p;
visit[i]=1; //标记已访问
Visit(v); //访问顶点v
p=G.adjlist[v]->firstarc; //p指向顶点v的第一条边
while(p!=NULL){
if(visit[p->adjvex]==0){
DFS(G,p->adjvex); //若该顶点未被访问,则递归访问它
p=p->nextarc; //完事儿之后p再指向顶点v的下一条边的终点
}
}
}
3、以邻接矩阵为存储结构的图的广度优先搜索遍历代码
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
#define MAX_VERTEX_NUM 20
#define INFINITY 32768
int visited[MAX_VERTEX_NUM]; //访问标志数组
typedef struct
{
int arcs[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
int vexnum;
}Graph;
void CreateMatrix(Graph *G){
cout<<"请输入顶点数:";
cin>>G->vexnum;
cout<<"请输入矩阵:"<<endl;
for(int i=0; i<G->vexnum; ++i){
for(int j=0;j<G->vexnum;++j){
cin>>G->arcs[i][j];
}
}
}
void DFS(Graph G,int v){
cout<<"访问"<<v+1<<endl;
visited[v]=1;
for(int w=0;w<G.vexnum;++w){
if(!visited[w]&&G.arcs[v][w]==1){ //w跟v相连,且w未被访问过
DFS(G,w);
}
}
}
void TraverseGraph(Graph G){
for(int i=0;i<G.vexnum;++i){
visited[i]=0;
}
for(int i=0;i<G.vexnum;++i){
if(!visited[i]){
DFS(G,i);
cout<<endl;
}
}
}
int main(){
Graph G;
CreateMatrix(&G);
TraverseGraph(G);
}
二、广度优先搜索遍历(BFS)
1、基本思想(类似于树的层次遍历):
首先访问起始顶点v,然后选取与v邻接的全部顶点w1,w2,...,wn进行访问。再依次访问与w1,w2,...,wn邻接的全部顶点(已经访问过的除外)。以此类推,知道所有顶点都被访问过为止。
BFS中需要用到一个队列(二叉树的层次遍历也要用到队列),算法执行过程简单概括如下:
①任取图中一个顶点访问,入队,并将这个顶点标记为已访问;
②当队列不为空时,循环执行。出队,依次检查出队顶点的所有邻接顶点,访问没有被访问过的邻接顶点并将其入队;
③当队列为空时,跳出循环,BFS完成。
2、以邻接表为存储结构的图的广度优先搜索遍历
void BFS(AGraph *G, int v, int visit[maxSize]){
//visit[]数组被初始化为全为0
ArcNode *p;
int que[maxSize]; //初始化一个队列
int front=0,rear=0;
int j;
Visit(v); //访问v顶点
visit[v]=1; //标记为已访问
rear=(rear+1)%maxSize; //顶点v入队
que[rear]=v;
p=G->adjlist[v]
while(front!=rear){ //当队不为空时,继续遍历。队为空时,遍历结束
front=(front+1)%maxSize; //顶点出队
j=que[front];
p=G->adjlist[j].firstarc; //P指向出队顶点j的第一条边
while(p!=NULL){
if(visit[p->adjvex==0]){ //当前邻接顶点未被访问,则进队
Visit(p->adjvex);
visit[p->adjvex]=1;
rear=(rear+1)%maxSize;
que[rear]=p->adjvex;
}
p=p->nextarc; //p指向j的下一条边
}
}
}