上一篇 JavaScript 层级数组常用工具方法(一)—— 数组结构转换
概述
层级数组(也称为嵌套数组、多维数组、树状数组等)是指包含多层嵌套的数组结构,层级数组遍历技巧是在处理多层嵌套的数组结构时,通过一些特定的方法和技巧来遍历数组中的元素。这些技巧包括使深度优先遍历(DFS)和广度优先搜索(BFS)等方式。
文章目录
// 测试数据
const hierarchyData = [
{
id: 1,
name: "Node 1",
children: [
{ id: 2, name: "Node 1-1", children: [
{ id: 4, name: "Node 1-1-1", children: [] },
{ id: 5, name: "Node 1-1-2", children: [] }
] },
{ id: 3, name: "Node 1-2", children: [] }
]
}
];
深度优先遍历(DFS)
深度优先遍历(Depth-First Search,简称 DFS)是一种递归或栈实现的遍历算法,从根节点开始,先访问一个节点的所有子节点,再回溯访问其他兄弟节点。具体而言,DFS 的遍历策略是从根节点开始,沿着深度方向一直遍历到树的最底层,再从底层回溯到上层,直到遍历完整棵树。
DFS 的特点
- 深度优先:DFS 沿着深度方向遍历,优先访问子节点。
- 递归或栈实现:DFS 可以使用递归或显式栈来实现。
- 内存消耗较小:DFS 在遍历过程中只需要维护一个栈来存储节点,内存消耗较小。
- 不保证最短路径:DFS 无法保证找到最短路径,因为它可能陷入无限深度的分支中。
DFS 经常被使用的场景
- 深度优先搜索算法
- 拓扑排序
- 连通性检测
- 路径搜索等
DFS 示例
/**
* 深度优先遍历(DFS)
* @param arr 层级数据
*/
function dfsTraverseArray(arr, callback) {
for (let i = 0; i < arr.length; i++) {
callback(arr[i]);// 先处理当前节点
if (arr[i].children && arr[i].children.length > 0) {
traverseArray(arr[i].children, callback); // 递归遍历子数组
}
}
}
// 使用示例
dfsTraverseArray(hierarchyData, node => {
console.log(node); // 处理节点的逻辑
});
/* 输出:
{id: 1, name: 'Node 1', children: Array(2)}
{id: 2, name: 'Node 1-1', children: Array(2)}
{id: 4, name: 'Node 1-1-1', children: Array(0)}
{id: 5, name: 'Node 1-1-2', children: Array(0)}
{id: 3, name: 'Node 1-2', children: Array(0)}
*/
广度优先搜索(BFS)
广度优先搜索(BFS)是一种遍历层级数据结构的方法,它从根节点开始,逐层地遍历子节点,直到遍历到最底层的叶子节点。
BFS 的特点
- 广度优先:BFS 沿着广度方向遍历,先访问当前节点的相邻节点。
- 队列实现:BFS 使用队列来实现,保证了遍历顺序的广度性。
- 内存消耗较大:BFS 需要维护一个队列来存储节点,因此内存消耗较大。
- 保证最短路径:BFS 可以保证找到最短路径,因为它按照层级逐层遍历。
BFS 经常被使用的场景
- 最短路径搜索算法,如迷宫问题、网络路由等
- 连通性检测
- 图的最小生成树
- 社交网络分析等
BFS 示例
/**
* 广度优先搜索(BFS)
* @param arr 层级数据
*/
function bfsTraverseArray(arr, callback) {
let queue = [...arr]; // 使用队列保存待访问元素
while (queue.length > 0) {
let item = queue.shift(); // 取出队列中的第一个元素
callback(item); // 处理当前节点
// 如果元素是数组,则将其元素加入队列
if (item.children && item.children.length > 0) {
queue.push(...item.children );
}
}
}
// 使用示例
bfsTraverseArray(hierarchyData, node => {
console.log(node); // 处理节点的逻辑
});
/* 输出:
{id: 1, name: 'Node 1', children: Array(2)}
{id: 2, name: 'Node 1-1', children: Array(2)}
{id: 3, name: 'Node 1-2', children: Array(0)}
{id: 4, name: 'Node 1-1-1', children: Array(0)}
{id: 5, name: 'Node 1-1-2', children: Array(0)}
*/
深度优先遍历(DFS)和 广度优先搜索(BFS) 的区别
遍历策略:DFS 沿着深度方向遍历,优先访问子节点;而BFS 沿着广度方向遍历,优先访问相邻节点。
实现方式:DFS 可以使用递归或显式栈来实现,而 BFS 使用队列来实现。
内存消耗:DFS 内存消耗较小,因为只需要维护一个栈;而 BFS 内存消耗较大,因为需要维护一个队列。
最短路径:DFS 无法保证找到最短路径,而 BFS 可以保证找到最短路径,因为它按照层级逐层遍历。
应用场景:DFS 适用于深度优先搜索、拓扑排序、连通性检测、路径搜索等;BFS 适用于最短路径搜索、连通性检测、图的最小生成树、社交网络分析等。
结论
深度优先遍历(DFS)和广度优先搜索(BFS)是两种常用的树和图遍历算法,分别采用不同的遍历策略和实现方式。DFS 沿着深度方向遍历,优先访问子节点,可以使用递归或显式栈来实现,内存消耗较小;而 BFS 沿着广度方向遍历,优先访问相邻节点,使用队列来实现,内存消耗较大。DFS 适用于深度优
-结束
相关文章
- JavaScript 层级数组常用工具方法(一)—— 数组结构转换
- JavaScript 层级数组常用工具方法(二)—— 层级数组遍历技巧(正在浏览)
- JavaScript 层级数组常用工具方法(三)—— 节点查找技巧