算法之深度优先搜索和广度优先搜索

215 阅读1分钟

又要到一年一度的金三银四面试季节了,在这家公司待了快2年的时间了,有点跳槽的冲动。我相信很多小伙伴也有着和我一样的心态,今天就总结一篇关于前端面试可能会遇到的算法。 如果有不对的地方希望大佬们见谅并指正,谢谢。

下图中左边是深度优先搜索和右边广度优先搜索的特点

16c08ea871f0739f_tplv-t2oaga2asx-watermark.webp

1.创建一个二叉树的数据结构,代码如下:

const tree = {
    val: 'a',
    children: [
        {
            val: 'b',
            children: [
                {
                    val: 'd',
                    children: [
                        {
                            val: 'h',
                            children: []
                        }    
                    ]
                },
                {
                    val: 'e',
                    children: [
                        {
                            val: 'i',
                            children: []
                        }    
                    ]
                },
            ]
        },
        {
            val: 'c',
            children: [
                {
                    val: 'f',
                    children: [
                        {
                            val: 'j',
                            children: []
                        }    
                    ]
                },
                {
                    val: 'g',
                    children: [
                        {
                            val: 'k',
                            children: []
                        }
                    ]
                },
            ]
        }
    ]
}

下面分别用深度优先搜索(depth first search)和广度优先搜索(breadth first search)的算法来输出最后的结果:

1.深度优先搜索(depth first search)的思路:

  • 从树的根节点出发,尽可能深的搜索树的节点
  • 第一种:采用了递归的方法
function depthFirstSearch(data) {
    const result = [];
    const dfs = item => {
        result.push(item.val);
        if(item.children && item.children.length) {
           item.children.forEach(dfs);
        }
    }
    dfs(data);
    return result;
}

第二种:采用栈(后进先出的规律)数据结构

function depthFirstSearch(data) {
    const result = [];
    const stack = [JSON.parse(JSON.stringify(data))];
    while(stack.length) {
        const item = stack.shift();
        result.push(item.val);
        if(item.children && item.children) {
            let len = item.children.length;
            for (let i = len - 1; i >= 0; i -= 1) { 
                stack.unshift(item.children[i]); 
            }
        }
    }
    return result;
}

输出结果为: 'a,b,d,h,e,i,c,f,j,g,k'

2.广度优先搜索(breadth first search)思路:

  • 采用队列的方法(先进先出)
function breadthFirstSearch(data) {
    const result = [],
          arr = [data];
    while(arr.length) {
        const item = arr.shift();
        result.push(item.val);
        if(item.children && item.children.length) {
            item.children.forEach(o => {
                arr.push(o);
            })
        }
    } 
    return result;
}

输出结果为 'a,b,c,d,e,f,g,h,i,j,k'