一文搞懂BFS与DFS

在上一篇中我们学习了数据结构中的图,以及对图进行的动态操作,本章我们将会介绍图非常重要的算法BFS与DFS
对于图的遍历,结果相同,区别在于遍历的策略(节点的访问顺序)

广度优先搜索(BFS):策略:越早被访问的节点,其邻居越早被选用。

简单来说,就是一个节点被访问后,会优先遍历这个节点的邻居。
直观点,就是围绕初节点,一层一层的遍历,和二叉树中的层次遍历也是BFS。
时间复杂度:首先对所有节点和边复位需要O(n+e),枚举每个节点需要O(n),所以,最终时间复杂度需要O(n+e)。
应用场景:考虑全局的节点,比如最短路径。
由于迭代先进先出的顺序非常适合BFS,所以这里我们使用队列来暂时保存节点。
在这里插入图片描述
图片来自数据结构(C++语言版)邓俊辉编著
代码如下:

template<typename Tv, typename Te>
void bfs(int start){
	reset();  // 重置图
	int v = start; int clock = 0;
	do{
		if(UNDISCOVERED == status(v)){
			BFS(v, clock);
		}
	}while(s != (v = (++v % n)));
}
template<typename Tv, template Te>
void BFS(int v, int clock){
	Queue<int> Q;
	status(v) = DISCOVERED;
	Q.enqueue(v);  // 最初节点入列
	while(!Q.empty()){
		v = Q.dequeue; dTime(v) = ++clock;
		int u = firstNbr(v);
		while(u > -1){
			Q.enqueue(u);  // 将与v相连的节点入列,并更新节点的状态信息
			status(u) = DISCOVERED;
			partent(u) = v; 
			u = nextNbr(v, u);  // 更新相连节点
		}
	}
}

对于clock的解释,我们会在后面统一解释

DFS:深度优先搜索:策略:以一个节点开始,沿一条线深入遍历,当到终点时,回到上一个节点,遍历其他兄弟节点,很像二叉树的后序遍历。

举个例子:一个人走迷宫,从起点开始,随便选一条路深入,在每个岔路口都随机选一条路深入,当遇到死胡同时,向后退,到上一个岔路口,选下一条路。
例子:求二叉树的深度,对每一个节点,可使用DFS思想。
实现:以迭代的形式实现,引入一个辅助栈。
在这里插入图片描述
代码如下:与上面的BFS十分相似

template<typename Tv, typename Te>
void dfs(int start){
	reset();
	int v = start;
	int clock = 0;
	do{
	if(UNDISCOVERED == status(v))
		DFS(v, clock);
	}while(s != (v = (++v % n)))
}

template<typename Tv, typename Te>
void DFS(int v, int clock){
	Stack<int> S;
	status(v) = DISCOVERED;
	S.push(v);
	while(!S.empty()){
		v = S.pop();
		for(int u = firstNbr(v); u > -1; u = nextNbr(v, u)){
			status(u) = DISCOVERED; dTime(u) = clock++;
			S.push(u); partent(u) = v;
		}
	}
}

比较下,DFS与BFS实现是相同的,只不过一个用的是栈,一个用的是队列。
在本章中,对于参数,只修改了状态,至于边,可自行实现下。

到这里,相信各位小伙伴对于,DFS和BFS算法都有了一定的了解,这里希望各位小伙伴可以自行由策略自行实现下。
这里补充下,clock的作用:clock主要是用来表现这个节点的生命周期,比如叶子节点,它的生命周期只有1,而它的父节点则是2。这个的主要作用是在边的状态的确定上。对此想要深入了解的,可去看邓公的数据结构课程。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值