JavaScript 层级数组常用工具方法(二)—— 层级数组遍历技巧

上一篇 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) 的区别

  1. 遍历策略:DFS 沿着深度方向遍历,优先访问子节点;而BFS 沿着广度方向遍历,优先访问相邻节点。

  2. 实现方式:DFS 可以使用递归或显式栈来实现,而 BFS 使用队列来实现。

  3. 内存消耗:DFS 内存消耗较小,因为只需要维护一个栈;而 BFS 内存消耗较大,因为需要维护一个队列。

  4. 最短路径:DFS 无法保证找到最短路径,而 BFS 可以保证找到最短路径,因为它按照层级逐层遍历。

  5. 应用场景:DFS 适用于深度优先搜索、拓扑排序、连通性检测、路径搜索等;BFS 适用于最短路径搜索、连通性检测、图的最小生成树、社交网络分析等。

结论

深度优先遍历(DFS)和广度优先搜索(BFS)是两种常用的树和图遍历算法,分别采用不同的遍历策略和实现方式。DFS 沿着深度方向遍历,优先访问子节点,可以使用递归或显式栈来实现,内存消耗较小;而 BFS 沿着广度方向遍历,优先访问相邻节点,使用队列来实现,内存消耗较大。DFS 适用于深度优

-结束

相关文章

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

顺芯技术猿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值