数据结构21————图的深度优先遍历(DFS)&广度优先遍历(BFS)

数据结构21————图的深度优先遍历(DFS)&广度优先遍历(BFS)

一. 目录

二. 深度优先遍历(DFS)

1.DFS递归定义

假设给定图的所有状态都是未曾访问过.在G中任选一个点V作为初始点。则深度优先遍历的定义如下:

首先访问出发点V,并将其标记为已访问过。然后依次从v出发搜索v的每个邻接点w。若w未曾访问过,则以w为新的处发点继续进行深度优先遍历,直至图中所有和源点v路径相通的顶点均被访问。若此时图中仍有未访问的顶点,则另选一个尚未访问的顶点作为新的源点重复上述过程,直至图中所有顶点均已被访问为止。

图的深度优先遍历类似于图的前序遍历。采用搜索方法的特点是尽可能对纵深方向进行搜索。这种搜索方法被称为深度优先搜索(Depth-First Search)

2.遍历思路

  • 访问顶点v;
  • 从v的未被访问的邻接点中选取一个顶点w,从w出发进行深度优先遍历;
  • 重复上述两步,直至图中所有和v有路径相通的顶点都被访问到。

3.伪代码

递归实现

1)访问顶点v;visited[v]=1//算法执行前visited[n]=02)w=顶点v的第一个邻接点;

(3while(w存在){

           if(w未被访问)

                   从顶点w出发递归执行该算法; 
           w=顶点v的下一个邻接点;
}
 

非递归实现

(1) 栈S的初始化:visited[n=0]

(2) 访问顶点v;visited[v]=1;顶点v入栈s

(3) while(栈S非空){
    x=栈S的顶元素(不出栈)if(存在并找到未曾访问的x邻接点w){
        访问w;visited[w]=1;
        w入栈;
    }else{
        x出栈;
    }
    
}

4.对邻接矩阵存储无向图的进行DFS

完整代码在下文链接中,下同

int visited[MAXVEX]; 
void DFS(AdjMatrix *G,int i){ //i为出发点 
	int j;
	visited[i]=1;
	printf("%c",G->Vex[i]);
	for(j=0;j<G->vexnum	;j++){
		if(G->acre[i][j]==1&&!visited[j]){
			DFS(G,j);
		}
	}	 
}
void DFSTraveres(AdjMatrix *G){
	int i;
	for(i=0;i<G->vexnum;i++){
		if(!visited[i]){ //对未访问的点,进行DFS,如果是联通图,只会执行一次 
			DFS(G,i);
		}		
	}	
}

这里写图片描述

5.对邻接表存储的无向图进行DFS

int visited[MAXVEX];
void DFS(AdjList *GL,int i){
	ArcNode *p;
	visited[i]=1;
	printf("%c",GL->vertex[i].vexdata);
	p=GL->vertex[i].head;
	while(p){
		if(!visited[p->adhVex]){
			DFS(GL,p->adhVex);
		}
		p=p->next;
	}	
}
void DFSTraverse(AdjList *GL){
	int i;
	for(i=0;i<GL->vexnum;i++){
		if(!visited[i]){
			DFS(GL,i);	
		}
	}
}

这里写图片描述

三. 广度优先遍历(BFS)

1.BFS的定义

图的广度优先遍历BFS算法是一个分层搜索的过程,和树的层序遍历算法类同,它也需要一个队列以保持遍历过的顶点顺序,以便按出队的顺序再去访问这些顶点的邻接顶点。

2.遍历思路

  • 从图中某个顶点V0出发,并访问此顶点;
  • 从V0出发,访问V0的各个未曾访问的邻接点W1,W2,…,Wk;然后,依次从W1,W2,…,Wk出发访问各自未被访问的邻接点;
  • 重复步骤2,直到全部顶点都被访问为止。

3.伪代码

(1) 初始化对列Q;visited[n]=0

(2) 访问顶点v;visited[v]=1;顶点v入队列Q;

(3)while(队列Q非空){
    v = 队列的队首元素出队;
    w = 顶点v的第一个邻接点;
    while(w存在){
        如果w为访问,则访问顶点w;
        visited[w]=1;
        顶点w入队列Q;
        w=顶点v的下一个邻接点.
    }
}

4.对邻接矩阵存储无向图的进行BFS

int visited[MAXSIZE]; 

void BFSTraveres(AdjMatrix *G){
	int i,j;
	CSeQeue *Q;//队
	Q=InitSeQueue();
	 
	for(i=0;i<G->vexnum;i++){
		if(!visited[i]){ //对未访问的点,进行DFS,如果是联通图,只会执行一次 
			visited[i]=1;
			printf("%c",G->Vex[i]);
	 		InSeQueue(Q,i);//入队
			  
	 		while(!EmptySeQueue(Q)){  //如果当前队不为空 
	 		
		 		QutSeQueue(Q,&i);//出队
				for(j=0;j<G->vexnum;j++){
					
					if(G->acre[i][j]==1&&visited[j]==0){//如果邻接点存在并未访问过
						visited[j]=1;
						printf("%c",G->Vex[j]);
						InSeQueue(Q,j);//入队  
					} 
				}  
		 	}
	 		
		}		
	}	
}

这里写图片描述

5.对邻接表存储的无向图进行BFS

int visited[MAXSIZE];
void BFSTraverse(AdjList *GL){
	int i;
	CSeQeue *Q;//队
	Q=InitSeQueue();
	ArcNode *p; 
	for(i=0;i<GL->vexnum;i++){
		if(!visited[i]){
			visited[i]=1;
			printf("%c",GL->vertex[i].vexdata);
			InitSeQueue(Q,i);//入队 
			while(!EmptySeQueue(Q)){
				QutSeQueue(Q,&i);//出队
				p=GL->vertex[i].head;
				while(p){
					if(!visited[p->adhVex]){//节点未被访问 
						visited[p->adhVex]=1;
						printf("%c",GL->vertex[p->adhVex].vexdata);
						InitSeQueue(Q,p->adhVex);//入队 
					}
					p=p->next; 
				} 
				 
			}	
		}
	}
}

这里写图片描述

四. 源代码地址

点此查看源码

五. 参考资料

《大话数据结构》
《数据结构与算法》
华山大师兄博客

发布了120 篇原创文章 · 获赞 478 · 访问量 16万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 编程工作室 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览