加载笔记内容...
加载笔记内容...
DFS(Depth-First Search) 的本质是栈结构的极致运用,其递归实现隐式利用了系统调用栈。当处理树形结构时,其遍历顺序遵循:
1A → B → D → H → I → E → C → F → G
但真实的工程实现中,我们更推荐显式栈的迭代实现以避免栈溢出风险:
1def dfs_iterative(root):
2 stack = [root]
3 while stack:
4 node = stack.pop()
5 process(node)
6 # 注意压栈顺序的逆向处理
7 for child in reversed(node.children):
8 stack.append(child)
空间复杂度 O(h)(h为树高)的特性使其在解决某些特定问题时极具优势,例如:
但需要注意的致命缺陷是可能陷入无限循环,这在处理图结构时必须通过visited集合来规避。
BFS(Breadth-First Search) 的队列实现是其核心特征,保证了层次遍历的严格顺序:
1A → B → C → D → E → F → G → H → I
其典型实现模板:
1from collections import deque
2
3def bfs(root):
4 queue = deque([root])
5 visited = set()
6 while queue:
7 node = queue.popleft()
8 process(node)
9 for neighbor in node.neighbors:
10 if neighbor not in visited:
11 visited.add(neighbor)
12 queue.append(neighbor)
空间复杂度 O(w)(w为最大层宽度)的特性使其在求解最短路径(无权图)等问题中不可替代。但需注意以下工程陷阱:
常见误区认为BFS不适用于带权图,实际上:
以LeetCode 127单词接龙为例,BFS求最短转换路径的标准解法:
1def ladderLength(beginWord, endWord, wordList):
2 wordSet = set(wordList)
3 queue = deque([(beginWord, 1)])
4 while queue:
5 word, length = queue.popleft()
6 if word == endWord:
7 return length
8 for i in range(len(word)):
9 for c in 'abcdefghijklmnopqrstuvwxyz':
10 next_word = word[:i] + c + word[i+1:]
11 if next_word in wordSet:
12 wordSet.remove(next_word)
13 queue.append((next_word, length+1))
14 return 0
在八皇后问题中,DFS的回溯特性展现得淋漓尽致:
1def solveNQueens(n):
2 def backtrack(row, cols, diag1, diag2):
3 if row == n:
4 res.append(["".join(r) for r in board])
5 return
6 for col in range(n):
7 d1 = row - col
8 d2 = row + col
9 if col in cols or d1 in diag1 or d2 in diag2:
10 continue
11 board[row][col] = 'Q'
12 backtrack(row+1, cols|{col}, diag1|{d1}, diag2|{d2})
13 board[row][col] = '.'
14
15 res = []
16 board = [['.']*n for _ in range(n)]
17 backtrack(0, set(), set(), set())
18 return res
这里利用位运算优化冲突检测的变种,展示了DFS在状态空间搜索中的强大能力。
React 16之前的Stack Reconciler采用深度优先递归遍历,存在致命缺陷:
Fiber架构的创新在于将虚拟DOM节点抽象为Fiber节点,构建链表树结构:
1App Fiber
2├── child: Header Fiber
3│ └── child: Logo Fiber
4│ └── sibling: Nav Fiber
5├── sibling: Main Fiber
6└── return: Root Fiber
每个Fiber节点包含:
child
: 第一个子节点sibling
: 右兄弟节点return
: 父节点alternate
: workInProgress节点effectTag
: 副作用标记Fiber实现时间切片的核心在于将整个渲染过程分解为多个工作单元。工作循环伪代码:
1function workLoop(deadline) {
2 while (nextUnitOfWork && deadline.timeRemaining() > 0) {
3 nextUnitOfWork = performUnitOfWork(nextUnitOfWork);
4 }
5 if (!nextUnitOfWork) {
6 commitRoot();
7 } else {
8 requestIdleCallback(workLoop);
9 }
10}
这种增量渲染机制使得React可以:
在大型表单应用中,Fiber架构的优化效果显著:
但需要注意的内存开销问题:
场景 | 推荐算法 | 时间复杂度 | 空间复杂度 | 典型案例 |
---|---|---|---|---|
无权图最短路径 | BFS | O(V+E) | O(V) | 社交网络关系分析 |
存在性判断 | DFS | O(V+E) | O(h) | 迷宫求解 |
拓扑排序 | DFS | O(V+E) | O(V) | 任务调度系统 |
连通分量 | Union-Find | O(Eα(V)) | O(V) | 电路板检测 |
最小生成树 | Prim | O(E log V) | O(V) | 通信网络布线 |
栈溢出问题:
重复访问问题:
当处理千万级节点时:
React Fiber的设计哲学与图遍历算法殊途同归:
这种算法思想在操作系统调度、数据库事务处理等领域都有深远影响,体现了计算机科学中时空转换的核心哲学。