「前端每日一问(58)」请使用深度优先搜索遍历一棵 DOM 树

765 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第23天,点击查看活动详情

本题难度:⭐ ⭐ ⭐

本题类型:算法、手写

阿林最近忙爆了,真的没时间认真写文章了,但是再忙也不能忘了学习,不然就懈怠了,最近多更新点前端面试中出现的高频算法题吧,这个写起来简单。

题目描述

请使用深度优先搜索遍历一棵 Dom 树,最终把每个节点存进一个数组里,返回这个数组。

举个例子,输入的 html 和返回结果如下图:

image.png

题目分析

这题看似很高大上,实际上就是树的前序遍历,套树前序遍历的公式即可。

// 二叉树前序遍历,刷题公式
function preorderTraversal (root) {
  let res = []
  function dfs(root) {
    if (!root) {
      return res
    }
    res.push(root.val)
    dfs(root.left)
    dfs(root.right)
  }
  dfs(root)
  return res
}

需要注意的是 DOM 树每一层有多个节点,不再是二叉树遍历 left 和 right,而是遍历每个节点的 children。

编码实现

随便写一个 html 文件,里面放几个元素

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <div id="app">
    <span></span>
    <span></span>
  </div>
  <div>
    <input type="text">
  </div>
  <script src="./index.js"></script>
</body>
</html>

在 index.js 里实现遍历的逻辑,代码如下:

// index.js
const html = document.documentElement

console.log('html :>> ', html);

function getDomNodes (root) {
  let res = []
  dfs(root, res)
  return res
}

function dfs(root, arr) {
  if (!root) {
    return null
  }
  arr.push(root)
  const children = root.children
  if (children) {
    for (let child of children) {
      dfs(child, arr)
    }
  }
}

console.log(getDomNodes(html))

运行本段代码,最终的效果如下:

image.png

树类型题目,难者不会,会者不难,对初学者来说确实挺难的,因为递归不是很好理解,但刷题刷多了,自然而然就会了。

如果你觉得树类型算法题难倒了你,不要困惑,先把前序中序后序和层序四种遍历方式搞懂,然后像套公式一样地把这些遍历运用到每一题,多刷就完事。

结尾

阿林水平有限,文中如果有错误或表达不当的地方,非常欢迎在评论区指出,感谢~

如果我的文章对你有帮助,你的👍就是对我的最大支持^_^

我是阿林,输出洞见技术,再会!

上一篇:

「前端每日一问(57)」两数之和

下一篇:

「前端每日一问(59)」输出给定一组数字的全排列