LeetCode | 深度优先搜索(递归和非递归)

简介

~~在学习广度优先搜索BFS之前,我觉得深度优先搜索DFS写起来非常简单:递归递归递归。
然而只有七秒钟记忆的我,在学习了广度优先搜索,最关键是学会了BFS的模板(python | 广度优先搜索模板)后,竟然忘了深度优先是怎么做的了~
此篇博客做一个系统的不尽详细的总结~

深度有限搜索DFS

1. 递归结构

什么是递归?
简单来说,就在一个函数中调用自己。

DFS算法实现最常用的就是递归,导致我之前一直不知道还可以用非递归来实现。

2. 非递归结构

DFS的非递归结构可以 借助来编写。
栈:后进先出

比如下面一个二叉树,深度有限搜索应该是:A-BC-DE-HI-FG-JK 这样一个过程。
在这里插入图片描述
用栈来编写DFS的过程为:

先把A压栈进去;
在A出栈的同时把B C压栈进去;
B出栈的同时把DE压栈(C留着先不处理);
同理,在D出栈的时候,H I压栈;
最后再从上往下取出栈内还未出栈的元素,即达到深度优先遍历。

DFS非递归结构和BFS的区别

BFS的模板(python | 广度优先搜索模板):

while queue 不空:
    cur = queue.pop()
    for 节点 in cur的所有相邻节点:
        if 该节点有效且未访问过:
            queue.push(该节点)

从中可以看出BFS是用队列来实现的。
队列:先进先出

DFS非递归结构是用来实现的。
栈:后进先出

对比一下同一个问题下DFS和BFS编写的不同:

import os
import collections

def getAllDirDP(path):
	stack = []
	stack.append(path) 	# 压栈操作,相当于图中的A压入

	# 处理栈,当栈为空的时候结束循环
	while len(stack) != 0:
		dirPath = stack.pop()#从栈里取数据,相当于取出A,取出A的同时把BC压入
		firstList = os.listdir(dirPath) # 找出跟目录下的所有的子目录信息,或者是根目录下的文件信息
		
		#判断:是目录压栈,把该目录地址压栈,不是目录即是普通文件,打印
		for filename in firstList:
			fileAbsPath=os.path.join(dirPath,filename) # 绝对路径
			
			if os.path.isdir(fileAbsPath):
				#是目录就压栈
				print("目录:",filename)
				stack.append(fileAbsPath)
			else:
				#是普通文件就打印即可,不压栈
				print("普通文件:",filename)
				
def getAllDirIT(path):

	queue=collections.deque()
	queue.append(path) 	#进队
	
	#循环,当队列为空,停止循环
	while len(queue) != 0:
		dirPath = queue.popleft() #出队数据 这里相当于找到A元素的绝对路径
		dirList = os.listdir(dirPath) # 找出跟目录下的所有的子目录信息,或者是根目录下的文件信息
		
		#遍历该文件夹下的其他信息
		for filename in dirList:
			dirAbsPath = os.path.join(dirPath,filename) # 绝对路径
			
			# 判断:如果是目录dir入队操作,如果不是dir打印出即可
			if os.path.isdir(dirAbsPath):
				print("目录:"+filename)
				queue.append(dirAbsPath)
			else:
				print("普通文件:"+filename)

# DFS:栈,后进先出
getAllDirDP(r'E:\[AAA](千)全栈学习python\18-10-21\day7\temp\dir')
# BFS:队列,先进先出
getAllDirIT(r'E:\[AAA](千)全栈学习python\18-10-21\day7\temp\dir')

参考网址:python 递归深度优先搜索与广度优先搜索算法模拟实现

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值