深度优先遍历不断深入图中并在栈中保存了所有分叉的顶点;广度优先遍历则像扇面一般扫描图,用一个队列保存访问过的最前端的顶点。深度遍历的方式是寻找离起点更远的顶点,只在碰到死胡同时才访问进出的顶点,广度遍历则会首先覆盖起点附近的顶点,只在临近的顶点都被访问完后,才去访问更远的顶点。
const data = [
{
name: 'a',
children: [
{ name: 'b', children: [{ name: 'e' }] },
{ name: 'c', children: [{ name: 'f' }] },
{ name: 'd', children: [{ name: 'g' }] },
],
},
{
name: 'a2',
children: [
{ name: 'b2', children: [{ name: 'e2' }] },
{ name: 'c2', children: [{ name: 'f2' }] },
{ name: 'd2', children: [{ name: 'g2' }] },
],
}
]
// 深度遍历, 使用递归
// "a,b,e,c,f,d,g,a2,b2,e2,c2,f2,d2,g2"
function getName(data) {
const result = [];
data.forEach(item => {
const map = data => {
result.push(data.name);
data.children && data.children.forEach(child => map(child));
}
map(item);
});
return result.join(',');
}
// 广度遍历, 创建一个执行队列,当队列为空的时候则结束
function getNameBreadth(data) {
let result = [];
let queue = data;
while(queue.length > 0) {
[...queue].forEach(child => {
queue.shift();
result.push(child.name);
child.children && (queue.push(...child.children));
})
}
return result.join(',');
}
getNameBreadth(data);
// 深度优先搜索就是自上而下的遍历搜索
// 广度优先则是逐层遍历
// 深度优先不需要记住所有的节点,所以占用空间小,而广度优先需要记录所有的节点,占用空间大
// 深度优先有回溯的操作(没有路走路了需要回头), 所以相对时间长一点
// 深度优先采用的是堆栈的形式,即先进后出
// 广度优先则采用队列的形式,即先进先出
深度优先遍历常用目录文件的遍历
虚拟DOM说到底只是一颗树形结构,对于树的遍历我们知道有深度遍历和广度遍历
深度遍历需要栈结构,可以通过递归(内核维护调用栈)的方式实现,也可以采用人为构造栈,然后循环栈完成深度遍历。通常深度优先搜索法不全部保留结点,扩展完的结点从栈中弹出删去,这样,在栈中存储的结点数就是深度值,因此它占用空间较少。
广度遍历则采用队列的方式实现,由于广度优先是按照树的层级来遍历的,在遍历某层的时候需要将下一层的数据推进队列里面,所以队列的长度通常会比树的宽度还要宽。
参考文章:
js实现深度优先遍历和广度优先遍历
图(一):无向图的深度优先遍历、广度优先遍历及连通分量
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。