数据结构——图(图的遍历)

图的遍历


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

遍历的实质:找每个顶点的邻接点的过程

图的特点:图中可能存在回路,且图的任一顶点都可能与其他顶点想通,在访问完某个顶点之后可能会沿着某些边又回到了曾经访问过的顶点

怎样避免重复访问?
解决思路:设置辅助数组 v i s i t e d [ n ] visited[n] visited[n],用来标记每个被访问过的顶点

  • 初始状态 v i s i t e d [ i ] visited[i] visited[i] 为0
  • 顶点 i i i 被访问,改 v i s i t e d [ i ] visited[i] visited[i] 为1,防止被多次访问

图常用的遍历:

  • 深度优先搜索(Depth_First Search——DFS
  • 广度优先搜索(Breadth_First Search——BFS

结论:
  稠密图适于在邻接矩阵上进行深度遍历
  稀疏图适于在邻接表上进行深度遍历

深度优先遍历(DFS)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

DFS算法效率分析

  • 用邻接矩阵来表示图,遍历图中每一个顶点都要从头扫描该顶点所在行,时间复杂度为 O ( n 2 ) O(n^2) O(n2)
  • 用邻接表来表示图,虽然有 2 e 2e 2e 个结点,但只需扫描 e e e 个结点即可完成遍历,加上访问 n n n 个头结点的时间,时间复杂度为 O ( n + e ) O(n+e) O(n+e)


深度优先遍历算法的实现


在这里插入图片描述

  • 初始状态 v i s i t e d [ i ] visited[i] visited[i] 为0
  • 顶点i被访问,改 v i s i t e d [ i ] visited[i] visited[i] 为1,防止被多次访问

算法实现:

void DFS(AMGraph G, int v){		//图G为邻接矩阵类型

	cout << v;				//访问第v个顶点
	visited[v] = true;
	
	for(w = 0; w < G.vexnum; w++)		//依次检查邻接矩阵v所在的行
		if((G.arcs[v][w] != 0) && (!visited[w]))		//w是v的邻接点,如果w未访问,则递归调用DFS
			DFS(G, w)
}


广度优先搜索遍历(BFS)

方法:
  从图的某一结点出发,首先依次访问该结点的所有邻接顶点 v i 1 vi_1 vi1 v i 2 vi_2 vi2,… v i n vi_n vin,再按只写顶点被访问的先后次序依次访问与他们相邻接的所有未被访问的顶点;
  重复此过程,直至所有顶点均被访问为止
在这里插入图片描述
在这里插入图片描述
实现过程的讲解:https://www.bilibili.com/video/BV1nJ411V7bd?p=125

算法实现:

//按该广度优先非递归遍历连通图G
void BFS(Graph G, int v){
	cout << v;			
	visited[v] = ture;			//访问第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] = ture;
				Enqueue(Q, w);		//w进队
			}//if
	}//while
}//BFS


BFS算法效率分析

  • 如果使用邻接矩阵,则BFS对于每一个被访问到的顶点,都要循环检测矩阵中的整整一行( n n n个元素),总的时间代价为 O ( n 2 ) O(n^2) O(n2)
  • 用邻接表来表示图,虽然有 2 e 2e 2e 个结点,但只需扫描 e e e个结点即可完成遍历,加上访问n个头结点的时间,时间复杂度为 O ( n + e ) O(n+e) O(n+e)

DFS与BFS算法比较

  • 空间复杂度相同,都是 O ( n ) O(n) O(n)(借用了堆栈或队列)
  • 时间复杂度只与存储结构(邻接矩阵或邻接表)有关,而与搜索路径无关
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值