一、广度优先搜索(BFS)
1.1 思想
- 类似于二叉树的层序遍历
- 从一个顶点开始找到与其所有相邻顶点。
- 标记被访问过
- 需要 辅助队列
1.2 代码
bool visited[Max_VERTEX_NUM];//访问标记数组
void BFSTraverse(Graph G){ //对图G进行广度优先遍历
for(i = 0;i<G.vexnum;++i)
visited[i] =FALSE; //访问标级数组初始化
InitQueue(Q); //初始化队列Q
for(i = 0;i<G.vexnum;++i) //从0号顶点开始遍历
if(!visited[i]) //对每个分量调用一次BFS
BFS(G,i); //vi未访问过,从vi开始BFS
}
void BFS(Graph G,int v){ //从顶点v出发,广度优先遍历图G
visit[v]; //访问初始顶点v
visited[v] =TRUE; //对v做已访问标级
Enqueue(Q,v); //顶点v入队列Q
while(!isEmpty(Q)){
DeQueue(Q,v); //顶点v出队列
for(w=FirstNeighbor(G,v);W>=0;W=NextNeighbor(G,v,w)){//检测v所有邻接点
if(!visited[w]){ //w为v的尚未访问的邻接顶点
visit(w); //访问顶点w
visited[w] =TRUE;//对w做已经访问标记
EnQueue(Q,w);//顶点w入队列
}//if
}//for
}//while
}//BFS
1.3 性质
- 对无向图,调用BFS函数次数等于连通分量数目
- 邻接矩阵,邻接表广度优先遍历不唯一
- 复杂度
- 邻接矩阵:O(v²)
- 邻接表:O(v+e)
- 应用点:
- 生成树Prim
- 最短路径(Dijkstra)
二、深度优先搜索(DFS)
2.1 思想
- 类似于二叉树的先序遍历
- 从一个顶点开始,找一个与其相邻的一个顶点。
- 标记访问过的结点
- 需要借助栈
2.2 代码
bool visited[Max_VERTEX_NUM];//访问标记数组
void DFSTraverse(Graph G){ //对图G进行广度优先遍历
for(v = 0;v<G.vexnum;++v)
visited[v] = FALSE; //初始化已访问标记数据
for(v = 0;v<G.vexnum;++v) //假设从v=0开始遍历
if(!visited[v])
DFS(G,v);
}
void DFS(Graph G,int v){ //从顶点v出发,深度优先遍历图G
visit(v); //访问顶点v
visited[v] =TRUE; //设已访问标记
for(w=FirstNeighbor(G,v);W>=0;W=NextNeighbor(G,v,w)){//检测v所有邻接点
if(!visited[w]){ //w为u的尚未访问的邻接顶点
DFS(G,w);
}//if
}//for
}
2.3 性质
-
调用的次数与连通分量相同
-
空间复杂度:需要调用栈,最坏O(v),最好O(1)
-
时间复杂度:访问过的邻接点和搜索各边的时间
- 邻接矩阵:O(v²)
- 邻接表:O(v+e)
-
应用点
- 生成树邻接矩阵唯一,邻接表不唯一
三、广度优先与深度优先考点
3.1 选择题考点
- 对于一个有n个顶点、e条边的图采用 邻接表 表示,
- 其深度遍历时间复杂度为O(n+e);空间复杂度为O(n)
- 其广度遍历时间复杂度为O(n+e);空间复杂度为O(n)
- 对于有n个顶点、e条边的图采用 邻接矩阵 表示时,
- 其进行深度遍历时间复杂度为O(n²)
- 其进行广度遍历时间复杂度为O(n²)
3.2 应用题考点
这部分考题主要是手算去理解广度优先和深度优先是怎么算的
一定记住,广度是遍历一个点旁边的所有顶点,深度遍历是遍历一个点旁边的一个顶点