BFS与DFS模板总结

1.常规BFS模板

最典型的BFS场景之一为二叉树的层次遍历。如果我们不需要得到当前层数,可以采用如下模板样式。

while queue not empty
	cur = queue.pop()
	visit cur
	for node in cur.neighbors
		if node valid and not visit
			queue.push(node)

2.需要确定层数的BFS模板

有的时候我们需要获取当前遍历层数,此时需要增加level变量表示当前遍历到那一层,比如二叉树的层次遍历。如果是一个图中,亦可以表示已经遍历走了多少步。

level = 0 # 当前层数
while queue not empty
	size = queue.size  # 表示当前层的元素个数
	while (size--) # size为0表示当前层已经遍历完毕
		cur = queue.pop
		for node in cur.neighbors:
			if node valid and not visit
				queue.push(node)
	level++

3.DFS模板

def backtrack(需要搜索的集合,递归层数,状态变量1,状态变量2,...,结果集):
	if 递归终止条件:
		结果集加入当前状态
		return
	for 可以执行的分支路径:
		if 递归层数,状态变量1,状态变量2,... 符合剪枝条件:
			continue 
		对状态变量状态变量 1, 状态变量 2 的操作
		backtrack(需要搜索的集合,递归层数,状态变量1,状态变量2,...,结果集)
		对状态变量状态变量 1, 状态变量 2 的操作(即重置状态变量)
		

模板中所谓的backtrack即回溯,从上面的框架不难看出,回溯主要包括三部分:DFS即深度优先遍历,状态变量,剪枝。

当某个结点有多个路径可以走的时候,一般使用循环结构。当程序递归到底返回到原来执行的结点时,“状态”以及与“状态”相关的变量需要“重置”成第 1 次走到这个结点的状态,这个操作有个形象的名字,叫“回溯”,“回溯”有“恢复现场”的意思:意即“回到当时的场景,已经走过了一条路,尝试走下一条路”。
状态通常是一个列表结构,因为一层一层递归下去,需要在列表的末尾追加,而返回到上一层递归结构,需要“状态重置”,因此要把列表的末尾的元素移除,符合这个性质的列表结构就是“栈”(只在一头操作)。

当我们明确知道一条路走不通的时候,例如通过一些逻辑计算可以推测某一个分支不能搜索到符合题意的结果,可以在循环中 continue 掉,这一步操作叫“剪枝”。“剪枝”的意义在于让程序尽量不要执行到更深的递归结构中,而又不遗漏符合题意的解。因为搜索的时间复杂度很高,“剪枝”操作得好的话,能大大提高程序的执行效率。

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值