图的遍历
1.什么是图的遍历
是指从图中的某个顶点出发,按照某种搜索方式沿着图中的边对图中的所有顶点访问依次,且仅访问一次
2.两种遍历算法
2.1广度优先搜索
基本思想:首先访问起始顶点v,接着由v出发,依次访问v的各个未访问过的邻接顶点w1,w2,……,wi,然后依次访问w1,w2,……,wi的所有未被访问过的邻接顶点,在从这些访问过的顶点出发,访问他们所有未被访问过的邻接顶点,直至图中所有的顶点都被访问过为止。
bool visited[MAX_VERTEX_NUM];//标记访问数组
void BFSTraverse(Graph G){//对图G进行广度优先遍历
for(int i=0;i<=G.vexnum;i++){
visited[i]=false;//访问标记数组初始化
}
InitQueue(Q);//初始化一个辅助队列Q
for(int i=0;i<G.vexnum;i++){//从0号顶点开始遍历
if(!visited[i]){//对每个连通分量调用一次BFS()
BFS(G,i);//若vi未被访问过,从vi开始调用BFS()
}
}
}
2.1.1邻接表实现
void BFS(ALGraph G,int i){
visit(i);//访问初始顶点i
visited[i]=true;//对i做已访问标记
EnQueue(Q,i);//i入队
while(!IsEmpty(Q)){//队列不空
DeQueue(Q,v);//队头元素出队
for(p=G.vertics[v].firstarc;p;p=p->nextarc){//检测v的所有邻接点
w=p-adjvex;
if(visited[w]==false){//w为v未被访问的邻接点,访问w
visit(w);
visited[w]=true;
EnQueue(Q,w);
}
}
}
}
2.1.2邻接矩阵实现
void BFS(ALGraph G,int i){
visit(i);//访问初始顶点i
visited[i]=true;//对i做已访问标记
EnQueue(Q,i);//i入队
while(!IsEmpty(Q)){//队列不空
DeQueue(Q,v);//队头元素出队
for(w=0;w<G.vexnum;w++){//检测v的所有邻接点
if(visited[w]==false&&G.edge[v[w]==1]){//w为v未被访问的邻接点,访问w
visit(w);
visited[w]=true;
EnQueue(Q,w);
}
}
}
}
辅助数组visited[]标志顶点是否被访问过,其初始态为FALSE,在图的遍历过程中,一旦某个顶点i被访问过,就立即置visited[i]=true,防止它多次被访问。
2.1.3性能分析
无论是邻接表还是邻接矩阵的存储方式,BFS都需要借助一个辅助队列Q,n个顶点都需要入队一次,最坏时,空间复杂度为O(|V|)。
时间复杂度:邻接表——O(|V|+|E|),邻接矩阵——O(|V|*|V|)
3.1深度优先搜索
算法思想:首先访问图中的某一个 顶点v,然后由v出发,访问与v邻接且未被访问过的任意一个顶点w1,再访问与w1邻接且未被访问过的任意一个顶点w2……重复上述过程。当不能再继续向下访问时,依次退回到最近且被访问过的顶点,若它还有邻接点未被访问过,则从该点开始继续上述过程,直至图中所有顶点均被访问过为止。
bool visited[MAX_VERTEX_NUM];//标记访问数组
void DFSTraverse(Graph G){//对图G进行深度优先遍历
for(int i=0;i<=G.vexnum;i++){
visited[i]=false;//访问标记数组初始化
}
for(int i=0;i<G.vexnum;i++){//从0号顶点开始遍历
if(!visited[i]){//对每个连通分量调用一次DFS()
DFS(G,i);//若vi未被访问过,从vi开始调用DFS()
}
}
}
3.1.1邻接表实现
void DFS(ALGraph G,int i){
visit(i);//访问初始顶点i
visited[i]=true;//对i做已访问标记
for(p=G.vertics[v].firstarc;p;p=p->nextarc){//检测v的所有邻接点
j=p-adjvex;
if(visited[j]==false){//j为v未被访问的邻接点,访问j
DFS(G,j);
}
}
}
3.1.2邻接矩阵实现
void DFS(ALGraph G,int i){
visit(i);//访问初始顶点i
visited[i]=true;//对i做已访问标记
for(j=0;j<G.vexnum;j++){//检测v的所有邻接点
if(visited[j]==false&&G.edge[i][j]==1]){//j为j未被访问的邻接点,访问j
DFS(G,j);
}
}
}
3.1.3性能分析
DFS是一个递归算法,需要借助一个递归工作栈,所以空间复杂度为O(|V|)。
时间复杂度:邻接表——O(|V|+|E|),邻接矩阵——O(|V|*|V|)