树是前端工程师最经常打交道的一个数据结构,比如说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 Search
const bfs = (root) => {
//根节点入队
let q = [root];
//如果队列里还有节点,就一直循环
while(q.length) {
//取出队头并访问
let t = q.shift();
console.log(t.val);
//将队头的子节点入队
t.children.forEach(child => q.push(child));
}
}
深度优先遍历与广度优先遍历在日常使用中比较频繁,在面试中也比较常问