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)。
相关推荐
共享家952711 小时前
LeetCode热题100(1-7)
算法·leetcode·职场和发展
新学笺11 小时前
数据结构与算法 —— Java单链表从“0”到“1”
算法
同元软控11 小时前
首批CCF教学案例大赛资源上线:涵盖控制仿真、算法与机器人等9大方向
算法·机器人·工业软件·mworks
yiqiqukanhaiba12 小时前
Linux编程笔记2-控制&数组&指针&函数&动态内存&构造类型&Makefile
数据结构·算法·排序算法
PKNLP12 小时前
逻辑回归(Logistic Regression)
算法·机器学习·逻辑回归
可触的未来,发芽的智生13 小时前
新奇特:神经网络的自洁之道,学会出淤泥而不染
人工智能·python·神经网络·算法·架构
放羊郎13 小时前
SLAM算法分类对比
人工智能·算法·分类·数据挖掘·slam·视觉·激光
Juan_201213 小时前
P1447题解
c++·数学·算法·题解
ai智能获客_狐狐13 小时前
智能外呼产品架构组成
人工智能·算法·自然语言处理·架构·语音识别
Algo-hx14 小时前
数据结构入门 (五):约束即是力量 —— 深入理解栈
数据结构·算法