数据结构——图的遍历

此生再无相见时 提交于 2019-12-18 20:43:43

从已给的连通图中某一顶点出发,沿着一些边访遍图中所有的顶点,且使每个顶点仅被访问一次,就叫做图的遍历,它是图的基本运算。其本质为

● 深度优先遍历

从图中某顶点 v 出发;访问它的任一邻接顶点 w1;再从 w1 出发,访问与 w1邻接但还未被访问过的顶点 w2;然后再从 w2 出发,进行类似的访问……直至到达所有的邻接顶点都被访问过的顶点 u 为止。
退回一步,退到前一次刚访问过的顶点,看是否还有其它没有被访问的邻接顶点。如果有,则访问此顶点,之后再从此顶点出发,进行与前述类似的访问;如果没有,就再退回一步进行搜索。
重复上述过程,直到连通图中所有顶点都被访问过为止

bool visited[MVNum];

图G为邻接矩阵类型

void DFS(AMGraph G, int v){  
  cout<<v;  
  visited[v] = true;   //访问第v个顶点

  //依次检查邻接矩阵v所在的行  
  for(w =0;w<G.vexnum;w++)
  	if((G.arcs[v][w]!=0)&& (!visited[w]))  
        DFS(G, w); 
   //w是v的邻接点,如果w未访问,则递归调用DFS 
} 
//时间复杂度为O(n^2)

图G为邻接表类型

void DFS(ALGraph G, int v){        	
	cout<<v;  
	visited[v] = true;   //访问第v个顶点
 
 	p= G.vertices[v].firstarc;     
 	//p指向v的边链表的第一个边结点 
    while(p!=NULL){	//边结点非空 
       w=p->adjvex; 	
       //表示w是v的邻接点 
  		if(!visited[w]) 
  			DFS(G, w);
  		 	//如果w未访问,则递归调用DFS 
       p=p->nextarc; 	//p指向下一个边结点 
 } 
} 
//时间复杂度为O(n+e)

若遍历非连通图

void DFSTraverse(Graph G)
{
	for(v = 0; v < G.vexnum; ++v)
		visited[v] = false;
	for(v = 0; v < G.vexnum; ++v)
		if(!visited[v])
			DFS(G,v);
}

● 广度优先遍历

从图中某顶点 v 出发:
访问顶点 v;
依次访问 v 的各个未被访问的邻接点 v1,v2,…,vk;
分别从 v1,v2,…,vk 出发, 依次访问其未被访问的邻接点,并使 “先被访问顶点的邻接点” 先于 “后被访问顶点的邻接点” 被访问。直至图中所有与 v 有路径相通的顶点都被访问到。

1)从图中某个顶点v出发,访问v,并置visited[v]的值为 true,然后将v进队。
2)只要队列不空,则重复下述处理。
① 队头顶点u出队。
② 依次检查u的所有邻接点w,如果visited[w]的值为false,则访问w,并置visited[w]的值为true,然后将w进队。

   void BFS (Graph G, int v){ 
    //按广度优先非递归遍历连通图G 
    cout<<v; 
    visited[v] = true;     	//访问第v个顶点
    InitQueue(Q);    //辅助队列Q初始化,置空         
    EnQueue(Q, v);     //v进队 
    while(!QueueEmpty(Q)){   	//队列非空 
       DeQueue(Q, u);        
       //队头元素出队并置为u 
       for(w = FirstAdjVex(G, u); w>=0; w = NextAdjVex(G, u, w)) 
       if(!visited[w]){	//w为u的尚未访问的邻接顶点 
             cout<<w; 
             visited[w] = true;	
             EnQueue(Q, w);     //w进队 
          }    
    }
}//BFS 

邻接矩阵时间复杂度为O(n^2),邻接表时间复杂度为O(n+e)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!