JS深度优先遍历和广度优先遍历

1,884 阅读3分钟

深度优先遍历(DFS)和广度优先遍历(BFS)是两种最常见的遍历方法。虽然它们都是用来探索和访问所有顶点,但它们在实现和应用上有着显著的不同。本文将深入探讨这两种遍历方法的基本概念、优势对比以及它们在实际应用中的使用场景。

基本概念

深度优先遍历(是指自上而下的遍历

深度优先遍历采取自上而下的策略,层层深入,直到到达树的底层,然后回溯至上一个分叉点继续遍历。这种方法不需要存储整个搜索路径,因此占用的空间较小。在实现上,深度优先搜索通常使用递归进行,这种方法通过递归调用栈来实现回溯。

广度优先遍历(是指逐层遍历

广度优先遍历则采取逐层推进的策略,先访问起始顶点的所有邻接顶点,然后再对这些邻接顶点进行相同的操作,直到所有顶点都被访问。这种方法需要存储整个搜索路径,因此占用的空间较大。在实现上,广度优先搜索通常使用队列进行,这种方法确保了每个顶点按照被发现的时间顺序被访问。

优势对比

1、理念对比

深度优先搜索由于不存储整个搜索路径,所以占用空间较小。它在搜索过程中会进行回溯(走到最底层,再从第一层开始)操作,这可能会导致搜索时间相对较长。

广度优先搜索需要存储整个搜索路径,占用空间较大。由于它按照层级顺序访问顶点,通常在树形结构中能更快地找到叶子节点。

深度优先采用的是 堆栈 的形式, 即先进后出

广度优先则采用的是 队列 的形式, 即先进先出

2、事例对比

下面我们通过下面这个数据结构,具体对比下两者的区别:

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' }] },
        ],
    }
]

在实际应用中,深度优先搜索多用于递归处理树形或图形数据结构,如Vue中的组件渲染。

// 深度遍历, 多采用递归
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(',');
}

广度优先搜索则常用于需要按顺序处理所有顶点的情况(采用队列实现),例如在React等前端框架中处理组件树的更新。

// 广度遍历, 创建一个执行队列, 当队列为空的时候则结束
function getName2(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(',');
}

应用

在Vue中,深度优先遍历因其递归特性,能够很好地处理组件树的渲染和更新,确保组件的状态和属性正确传递。

在React中,广度优先遍历有助于实现虚拟DOM的批量更新,通过队列管理变更,提高了性能。

结语

通过对深度优先遍历(DFS)和广度优先遍历(BFS)的比较,DFS适用于需要递归处理树形或图形数据结构的情况,如 Vue 中的组件渲染,而BFS则适用于需要按顺序处理所有顶点的情况,如 React 等前端框架中处理组件树的更新。

希望本文能为您提供有所帮助的信息,欢迎在评论区一起讨论研究!