树是前端工程师最经常打交道的一个数据结构,比如说html标签组成的dom树、树形控件等。
在js中没有树这个数据结构,但是可以用Object和Array来构建树:
//val是当前的节点值,children是子节点
const tree = {val: 'A',children: [{val: 'B',children: [{val: 'D',children: []},{val: 'E',children: []}]},{val: 'C',children: [{val: 'F',children: []},{val: 'G',children: []}]}]}
接下来说说深度/广度优先遍历
1.深度优先遍历:尽可能深的搜索树的分支,这个搜索与遍历同个意思
看着图片上的数字,表示访问的顺序
盗用一下别人的图,我感觉这个图看起来更清晰
实现深度优先遍历的算法比较简单,只有两行,通过递归多次调用
1.访问根节点
2.对根节点的children挨个进行深度优先遍历
const dfs = (root) => {//bfs是depth first search的缩写//传入一个根节点,访问根节点console.log(root.val);//利用递归访问子节点//root.children.forEach(child => dsf(child))可以简写为root.children.forEach(dfs)
}
2.广度优先遍历:先访问离根节点最近的节点,就是一层一层的向下查找
广度优先遍历的算法比深度优先遍历复杂一点
1.新建一个队列,把根节点入队
2.把队头出队并访问
3.把队头的children挨个入队
4.重复第二、三步,直到队列为空
//Breath First Searchconst bfs = (root) => {//根节点入队let q = [root];//如果队列里还有节点,就一直循环while(q.length) {//取出队头并访问let t = q.shift();console.log(t.val);//将队头的子节点入队t.children.forEach(child => q.push(child));}
}
深度优先遍历与广度优先遍历在日常使用中比较频繁,在面试中也比较常问