顺序
November 22, 2024About 2 min
顺序
这四种顺序是针对值传递而言的,因为每一种顺序都是传递一个具体值的
第一对顺序
- 先序
- 后序
第二对顺序
- 访问
- 邻接
先序/后序
从出发点考虑:即已有一个拓扑排序,是从已知到未知还是从未知到已知
先序
定义:已知点到未知点,即出发点和边界点相同
方式:DFS、BFS、FOR
实现:(对于DFS,通过参数列表)
后序
定义:未知点到已知点,即出发点和边界点相反
方式:DFS
实现:(对于DFS,通过返回值传递)
邻接/访问
通过临界还是访问去构建一个拓扑排序
邻接顺序
定义:一个点相邻,他的值传递(依赖于它临界节点的值)
实现:局部变量,参数 + 返回值(参数:父传子,返回值:子传父)
如:dp[i]=dp[i-1]+dp[i-2]
访问顺序
定义:状态节点的访问,指DFS运行时栈和BFS的等待队列中节点的访问
实现:全局变量
如:index
, dfn
(或时间戳,二叉树里面一个节点唯一标识(根据访问的先后顺序递增))
顺序组合
四种组合
DFS四种顺序的组合在同一个代码块里面都可以出现,所以代码复杂性可能会很高
邻接 + 先序
实现:DFS,方式:
参数列表:
void dfs(TreeNode root, int depth) { if (root == null) return; dfs(root.left, depth + 1); dfs(root.right, depth + 1); }
简单变量可以父子传递,基本数据类型可以这样写,比较简单
全局变量:回溯
int depth = 0; void dfs(TreeNode root) { if (root == null) return; depth++; dfs(root.left); dfs(root.right); depth--; }
这样写可以节省开销
访问 + 先序
实现:DFS,通过:全局变量
int prev = 0;
void dfs(TreeNode root) {
if (root == null) return;
// 先序
prev++;
dfs(root.left);
dfs(root.right);
}
邻接 + 后序
实现:DFS,通过:返回值传递
int dfs(TreeNode root) {
if (root == null) return 0;
return 1 + Math.max(dfs(root.left), dfs(root.right));
}
访问 + 后序
实现:DFS,通过:全局变量
int post = 0;
void dfs(TreeNode root) {
if (root == null) return;
dfs(root.left);
dfs(root.right);
// 后序
post++;
}
四种混合
// 先序时间戳,后序时间戳,可以用来快速判断两个点直接的父子关系
int prev, post = 0;
int dfs(TreeNode root, List<TreeNode> path) {
if (root == null) return 0;
// 先序访问
prev++;
// 先序邻接
path.add(root);
dfs(root.left, path);
dfs(root.right, path);
path.remove(path.length - 1);
// 后序访问
post = prev;
// 后序邻接
return 1 + Math.max(dfs(root.left), dfs(root.right));
}
dfs和bfs搜索稠密图的区别(比如说矩阵)