简介
~~在学习广度优先搜索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')