DOM树的深度与广度优先遍历

问题描述

给定一个DOM节点的根元素,请分别实现它的深度优先遍历(DFS)和广度优先遍历(BFS),并返回所有节点名称的数组。

前端意义:这是理解虚拟DOM实现、DOM Diff算法以及任何需要递归操作DOM结构(如UI框架、爬虫、自动化测试)的基础。

解题思路

  1. 深度优先遍历 (DFS)

    • 从根节点开始,尽可能深地访问每个分支。

    • 通常采用递归栈(Stack) 的思想实现。

    • 顺序:A -> B -> D -> E -> C -> F

      text

      复制下载

      css 复制代码
          A
         / \
        B   C
       / \   \
      D   E   F
  2. 广度优先遍历 (BFS)

    • 从根节点开始,一层一层地访问。
    • 通常采用队列(Queue) 的思想实现。
    • 顺序:A -> B -> C -> D -> E -> F

代码实现

scss 复制代码
// 假设我们有一个DOM节点,它有一个`children`属性,包含其所有子元素。

/**
 * 深度优先遍历 - 递归版 (最简洁)
 */
function dfsTraversalRecursive(node) {
  const result = [];
  
  function traverse(node) {
    if (!node) return;
    result.push(node.nodeName); // 访问节点
    // 遍历所有子节点
    for (const child of node.children) {
      traverse(child); // 递归遍历子树
    }
  }
  
  traverse(node);
  return result;
}

/**
 * 深度优先遍历 - 迭代版 (利用栈)
 * 更接近计算机底层实现,避免递归栈溢出风险
 */
function dfsTraversalIterative(root) {
  const result = [];
  const stack = [root]; // 初始化栈,放入根节点

  while (stack.length > 0) {
    const currentNode = stack.pop(); // 弹出栈顶节点
    result.push(currentNode.nodeName); // 访问它

    // 注意:由于栈是"后进先出",我们需要将子节点**逆序**入栈
    // 这样才能保证下一个要处理的是第一个子节点,而不是最后一个
    for (let i = currentNode.children.length - 1; i >= 0; i--) {
      stack.push(currentNode.children[i]);
    }
  }

  return result;
}

/**
 * 广度优先遍历 - 迭代版 (利用队列)
 */
function bfsTraversal(root) {
  const result = [];
  const queue = [root]; // 初始化队列,放入根节点

  while (queue.length > 0) {
    const currentNode = queue.shift(); // 从队列头部取出节点
    result.push(currentNode.nodeName); // 访问它

    // 将当前节点的所有子节点**按顺序**加入队列尾部
    for (const child of currentNode.children) {
      queue.push(child);
    }
  }

  return result;
}

// 示例用法
// const rootElement = document.getElementById('root');
// console.log('DFS Recursive:', dfsTraversalRecursive(rootElement));
// console.log('DFS Iterative:', dfsTraversalIterative(rootElement));
// console.log('BFS:', bfsTraversal(rootElement));

复杂度分析

  • 时间复杂度:O(n)。所有算法都恰好访问每个节点一次。
  • 空间复杂度:O(n)。在最坏情况下(树退化为链表),递归DFS和栈迭代DFS的空间复杂度为O(n)。BFS的空间复杂度取决于每一层的宽度,在最坏情况下(平衡二叉树)也是O(n)。
相关推荐
qq74223498436 分钟前
APS系统与OR-Tools完全指南:智能排产与优化算法实战解析
人工智能·算法·工业·aps·排程
A尘埃1 小时前
超市购物篮关联分析与货架优化(Apriori算法)
算法
.小墨迹1 小时前
apollo学习之借道超车的速度规划
linux·c++·学习·算法·ubuntu
不穿格子的程序员1 小时前
从零开始刷算法——贪心篇1:跳跃游戏1 + 跳跃游戏2
算法·游戏·贪心
大江东去浪淘尽千古风流人物1 小时前
【SLAM新范式】几何主导=》几何+学习+语义+高效表示的融合
深度学习·算法·slam
重生之我是Java开发战士2 小时前
【优选算法】模拟算法:替换所有的问号,提莫攻击,N字形变换,外观数列,数青蛙
算法
仟濹2 小时前
算法打卡 day1 (2026-02-06 周四) | 算法: DFS | 1_卡码网98 可达路径 | 2_力扣797_所有可能的路径
算法·leetcode·深度优先
yang)2 小时前
欠采样时的相位倒置问题
算法
历程里程碑2 小时前
Linux20 : IO
linux·c语言·开发语言·数据结构·c++·算法
A尘埃2 小时前
物流公司配送路径动态优化(Q-Learning算法)
算法