概述
- 广度优先遍历:层级上由浅入深对路径进行遍历;
- 深度优先遍历:从最外层开始,依次对每个文件夹进行纵深遍历直到不再有子文件夹(完成第一个的纵深遍历,再来第二个);
- 广度遍历可以使用队列实现;
- 深度遍历可以使用栈实现,也可以使用递归实现;
- collections.deque是一个可以从头部和尾部两个方向进行弹出的容器,我们使用它来模拟队列和栈;(列表也是可以的)
广度遍历-队列实现
# 广度优先遍历
# dirPath 要遍历的文件夹
def traverseVast(dirPath):
# 创建一个队列容器
dirs = collections.deque()
# 将根路径丢入队列
dirs.append(dirPath)
# 从队列头部依次取出路径,直到取尽
while len(dirs) > 0:
# 弹出队列头部的目录
path = dirs.popleft()
# 罗列所有子路径
sPaths = [path + p for p in os.listdir(path)]
# 遍历子路径,如果是文件夹就继续追加到队列的尾部
for p in sPaths:
# 打印当前路径(这里根据深度插入若干制表符凸出层次效果)
print("\t" * (p.count("/") - 3), p)
# 将文件夹追加到队列尾部
if os.path.isdir(p):
dirs.append(p + "/")
traverseVast(filedialog.askdirectory() + "/")
实现效果
深度遍历-栈实现
- 其实只需要在广度遍历的基础上,修改为每次从deque尾部进行弹出即可
# 深度遍历-栈实现
def traverseDirDeep(dirPath):
# 将根路径丢入栈顶
pStack = collections.deque()
pStack.append(dirPath)
# 只要栈不为空
while len(pStack) > 0:
# 从栈顶弹出一个路径
path = pStack.pop()
print("\t" * (path.count("/") - 3) + path)
if os.path.isdir(path):
# 将当前路径的文件夹孩子逆序地丢入栈中
filenames = os.listdir(path)
for name in reversed(filenames):
name = path + "/" + name
pStack.append(name)
traverseDeepStack(filedialog.askdirectory() + "/")
深度遍历-递归实现
# 深度优先遍历-递归实现
# dirPath 要遍历的文件夹
def traverseDeepRecursive(dirPath):
# 遍历根目录的子路径
for path in [dirPath+p for p in os.listdir(dirPath)]:
# 层次化的打印路径
print("\t" * (path.count("/") - 3), path)
# 对子文件夹进行递归遍历
if os.path.isdir(path):
# 调用自身对子文件夹进行递归遍历
traverseDeepRecursive(path + "/")
traverseDeepRecursive(filedialog.askdirectory() + "/")