树是一种分层数据的抽象数据模型。 现实生活中最常见的树的例子是家谱,或是公司的组织架构图,如下图所示。
在前端的数据结构中,我们最常见到的树的结构就是DOM树、级联选择、树形选择。
例如:
const tree = [
{
val: 'a',
children: [
{
val: 'b',
children: [
{
val: 'c'
},
{
val: 'd'
}
]
},
{
val: 'e',
children: [
{
val: 'f'
},
{
val: 'g'
}
]
}
]
}
]
对于这种树形结构的数据,我们的常用操作有深度优先遍历和广度优先遍历。
深度优先遍历
所谓的深度优先遍历,就是先往深度的数据去解析。 例如,上述数据的读取顺序为 a => b => c => d => e => f => g
深度优先遍历思路
①遍历树节点
②如果树节点存在children,遍历children节点
③重复①②
代码实现
function dfs(treeNodes) {
treeNodes.forEach(item => {
console.log(item.val);
if (item.children){
dfs(item.children);
}
})
}
广度优先遍历
所谓的广度优先遍历,就是尽可能的先遍历外部的节点。等到外部的节点遍历完成后,再去遍历内部节点。例如,我们的遍历顺序应该为 a => b => e => c => d => e => f => g
广度优先遍历思路
因为遍历的同时,要遵循一定的顺序,同时,顺序为先进先出。 所以可以考虑使用队列这个数据结构为我们完成这个事。
①新建一个队列。
②将节点入队。
③节点出队,遍历节点,同时,将节点的children入队。
④重复②③
代码实现
function bfs (treeNodes){
const queue = [...treeNodes];
while(queue.length) {
const item = queue.shift();
console.log(item.val);
if (item.children){
queue.push(...item.children);
}
}
}