首页 > 其他分享 >【数据结构】图的遍历

【数据结构】图的遍历

时间:2024-09-25 16:23:23浏览次数:9  
标签:遍历 int srci DFS vis 顶点 数据结构



快乐的流畅:个人主页


个人专栏:《C游记》《进击的C++》《Linux迷航》

远方有一堆篝火,在为久候之人燃烧!

文章目录

引言

前置知识:【数据结构】图的概念和存储结构

一、深度优先遍历

1.1 定义

深度优先遍历(Depth First Search,DFS),是一种从某个顶点开始,沿着一条路径不断深入到未访问的顶点,直到没有新的顶点可以访问为止。然后回溯到前一个顶点,再继续访问其他未被访问的顶点,直到所有顶点都被访问到。

1.2 实现

思路:

  1. 创建vis数组,用于标记已遍历过的顶点,初始为false。
  2. 由于DFS需要递归展开,所以分出一个子函数_DFS。
  3. 进入子函数代表已到达src,所以将vis[srci]标记为true。
  4. 随后for循环查找与当前点相连且没被遍历过的点,再次以新点作为当前点进入子函数,构成重复子问题。
  5. _DFS调用完后,再检查vis数组是否还有未被遍历的点。若有,则再次以此点进行_DFS,防止不连通的区域未被遍历
void _DFS(int srci, vector<bool>& vis)
{
	vis[srci] = true;
	cout << "[" << srci << "]" << ":" << _vertexs[srci] << endl;

	for (int i = 0; i < _vertexs.size(); ++i)
	{
		if (_edges[srci][i] != W_MAX && !vis[i])
		{
			_DFS(i, vis);
		}
	}
}

void DFS(const V& src)
{
	int n = _vertexs.size();
	vector<bool> vis(n, false);

	int srci = GetIndex(src);
	_DFS(srci, vis);

	//防止不连通的区域未被遍历
	for (int i = 0; i < n; ++i)
	{
		if (!vis[i])
		{
			_DFS(i, vis);
		}
	}
}

细节:vis数组的作用,是为了保证遍历的过程中,不遍历相同的点,防止算法时间复杂度大大增加,导致冗余计算。利用vis数组不去遍历相同的点,这个过程又称为剪枝

二、广度优先遍历

2.1 定义

广度优先遍历(Breadth First Search, BFS),是一种从某个顶点开始,先访问当前顶点的所有邻接顶点,然后再依次访问这些邻接顶点的邻接顶点。BFS 是逐层遍历的过程,优先访问离起点较近的顶点。

2.2 实现

思路:

  1. 创建vis数组,用于标记已遍历过的顶点,初始为false。
  2. 创建队列,用于存储待访问的顶点下标。
  3. 初始化,将源点下标存入队列,vis中标记为true。
  4. while循环中,每次取出队头数据并弹出,随后for循环查找与当前点相连且没被遍历过的点,将其存入队列,并且vis中标记为true,构成重复子问题。
void BFS(const V& src)
{
	int n = _edges.size();
	vector<bool> vis(n, false);
	queue<int> q;

	int srci = GetIndex(src);
	q.push(srci);
	vis[srci] = true;

	int levelSize = 1;
	while (!q.empty())
	{
		//每层分行打印
		for (int i = 0; i < levelSize; ++i)
		{
			int front = q.front();
			q.pop();
			cout << "[" << front << "]" << ":" << _vertexs[front] << " ";

			for (int j = 0; j < n; ++j)
			{
				if (_edges[front][j] != W_MAX && !vis[j])
				{
					q.push(j);
					vis[j] = true;
				}
			}
		}
		cout << endl;

		levelSize = q.size();
	}
}

细节:levelSize的设置,是为了按源点的度从小到大分层打印。每次while循环里用for循环控制打印换行,随后更新levelSize。看似增加一套循环,实际并没有增加时间复杂度。

三、DFS与BFS的对比

以下是 深度优先遍历(DFS)广度优先遍历(BFS) 的对比表格:

特性深度优先遍历(DFS)广度优先遍历(BFS)
使用的数据结构栈(隐式或显式)队列
遍历顺序深入某一条路径,直至没有未访问顶点再回溯按层遍历,从起点逐层向外扩展
适用场景连通分量、拓扑排序、路径搜索最短路径、层次遍历、二分图判定
实现难度简单(递归实现)需要队列,稍复杂
空间复杂度O(V)(递归栈)O(V)(队列)
时间复杂度O(V + E)O(V + E)
  • V 是图中的顶点数,E 是图中的边数。

真诚点赞,手有余香

标签:遍历,int,srci,DFS,vis,顶点,数据结构
From: https://blog.csdn.net/2301_79188764/article/details/142161871

相关文章

  • 架构师日记-从数据库发展历程到数据结构设计探析
    一数据库发展史起初,数据的管理方式是文件系统,数据存储在文件中,数据管理和维护都由程序员完成。后来发展出树形结构和网状结构的数据库,但都存在着难以扩展和维护的问题。直到七十年代,关系数据库理论的提出,以表格形式组织数据,数据之间存在关联关系,具有了良好的结构化和规范......
  • Python不同方式正倒序遍历的时间开销
    fromtimeitimporttimeitli=[iforiinrange(1000000)]deffor_loop(n):#使用for直接遍历ret=0foriinli:ret=li[i]deffor_loop_enumerate(n):#使用enumerate进行遍历ret=0foridx,iinenumerate(li):re......
  • 数据结构:二叉树 (Heap堆篇) 手把手带你入门数据结构~ (简单易懂超详细~)
    文章目录前言一、树的概念1.树的概念与结构2.树的特性3.树的相关术语4.树的表示方法5.树形结构实际场景二、二叉树1.二叉树的概念2.二叉树的结构3.满二叉树3.完全二叉树1.完全二叉树的概念2.完全二叉树的性质3.完全二叉树的结构三、堆1.堆的概念2.堆的......
  • 数据结构:双向链表(Doubly Linked List篇)手把手带你入门数据结构~
    文章目录前言一、双向链表的概念1.结构特点:2.优点:二、双向链表的实现1.双向链表的结构2.双向链表初始化3.双向链表销毁4.双向链表打印5.双向链表尾插6.双向链表头插7.双向链表尾删8.双向链表头删9.双向链表查找10.双向链表指定位置插入11.双向链表指定位置......
  • 16年408-数据结构
    第一题:解析:经过查表可知:a的链接地址是1010H,而1010H正是表中e所在的位置。由题可知f存放的位置是1014H,要将f链接在a和e的中间,则a后面要链接f,f后面要链接e,e的链接地址不变因此答案是1014H,1004H,1010H,答案选D第二题:解析:选D。p->next->prev:p的后一个节点的prev指针......
  • 15年408-数据结构
    第一题解析:栈第一次应该存main的信息。然后进入到main里面,要输出S(1),将S(1)存入栈内,进入到S(1)中,1>0,所以还要调用S(0)S(0)进入栈中,此时栈内从下至上依次是main(),S(1),S(0)答案选A第二题:解析:先序序列个数为0时,二叉树个数是1:先序序列个数为1时,二叉树个数是1:......
  • 数据结构算法题
    目录轮转数组原地移除数组中所有元素val删除有序数组中的重复项合并两个有序数组轮转数组思路1:1.利用循环将最后一位数据放到临时变量(n)中2.利用第二层循环将数据往后移一位3.将变量(n)的数据放到数组第一位时间复杂度:O(N^2)空间复杂度:O(1)思路2:1.创建一个空间......
  • 数据结构:单链表
    单链表单链表概念与结构节点链表的性质单链表的打印实现单链表创建新的节点在末尾插入数据在头部插入数据删除尾部数据删除第一个节点在链表中寻找目标数据在指定位置之前插入数据在指定位置之后插⼊数据删除pos结点删除pos之后的结点销毁链表单链表测试单链表概念与......
  • 代码随想录算法训练营Day13 | 递归遍历、迭代遍历、层序遍历
    目录递归遍历和迭代遍历:144.二叉树的前序遍历94.二叉树的中序遍历145.二叉树的后序遍历层序遍历:102.二叉树的层序遍历107.二叉树的层序遍历Ⅱ199.二叉树的右视图637.二叉树的层平均值429.N叉树的层序遍历515.在每个树行中找最大值116.填充每个节点的下一个右侧......
  • 基础数据结构之链表
    链表1)概述定义在计算机科学中,链表是数据元素的线性集合,其每个元素都指向下一个元素,元素存储上并不连续Incomputerscience,alinkedlistisalinearcollectionofdataelementswhoseorderisnotgivenbytheirphysicalplacementinmemory.Instead,eachelem......