Depth First Search vs Width First Search in Python¶
Keywords: DFS, WFS, 深度优先, 广度优先
深度优先 (DFS) 和 广度优先 (WFS) 是算法中两种常用的搜索算法. 在很多场景都有着广泛应用:
Serialization (序列化):
把一个复杂数据结构序列化, 数据结构的 attribute 有可能是另一个复杂的数据结构. 所以一个序列化算法通常需要用 DFS 搜索到最终叶节点, 从叶节点到根节点一直回溯序列化回来, 才算是完成了一个完整的序列化.
Prefix Tree Search:
给定一个字符串, 从一堆字符串中找到有着最长前缀的字符串. 比如给定一个文件路径和一堆文件夹路径, 这个文件到底是属于哪个文件夹的呢? 这个算法就要用到 WFS 搜索.
DFS, WFS 在 Python 中的主要实现方法是递归.
这里有个 DFS 和 WFS 的简单实现:
# -*- coding: utf-8 -*-
"""
A simple implementation of depth first search / width first search::
t
|--- t1
|--- t11
|--- t12
|--- t2
|--- t21
|--- t22
# depth first search result
t11, t12, t1, t21, t22, t2, t
# width first search result
t, t1, t2, t11, t12, t21, t22
"""
from typing import List
class Node:
def __init__(self, name: str, children: List['Node'] = None):
self.name = name
if children is None:
children = list()
self.children = children
def __repr__(self):
return f"'{self.name}'"
t11 = Node("t11")
t12 = Node("t12")
t21 = Node("t21")
t22 = Node("t22")
t1 = Node("t1", [t11, t12])
t2 = Node("t2", [t21, t22])
t = Node("t", [t1, t2])
def depth_first_search(node: Node):
for n in node.children:
yield from depth_first_search(n)
yield node
def width_first_search(node: Node, _is_root=True):
if _is_root:
yield node
for n in node.children:
yield n
for n in node.children:
yield from width_first_search(n, _is_root=False)
print(list(depth_first_search(t))) # ['t11', 't12', 't1', 't21', 't22', 't2', 't']
print(list(width_first_search(t))) # ['t', 't1', 't2', 't11', 't12', 't21', 't22']