JS实现图的深度优先搜索和广度优先搜索

640 阅读2分钟

JS实现图的深度优先搜索和广度优先搜索

这是我参与更文挑战的第21天,活动详情查看: 更文挑战

前面我们讲了二叉树的搜索,二叉树的搜索可以有很多扩展,可以扩展成树的搜索,图的搜索,图的搜索可以扩展成爬虫的逻辑。今天我们就了解一下图的搜索。

批注 2021-06-21 000824.png 搜索分为两种,一种是深度优先搜索,一种是广度优先搜索。
深度优先搜索是沿着节点的一条边,一路走到黑,然后返回到出发节点,再继续下一条边,如果找到目标节点,则返回,如果找不到,就会遍历完全部节点。
而广度优先搜索则是一层一层去寻找。如上图,用广度优先搜索是先从A开始,如果没找到就继续从第二层CB找,如果找到目标节点,则返回,如果找不到,就会一层一层遍历全部节点。
深度优先搜索更适合探索未知,因为它是先往远的地方走,能走多远走多远。
广度优先搜索更适合探索局域,例如我知道这里附近有要找的东西,那么我就从这附近一层一层的找。
树的搜索和图的搜索对比,树有一个好处,就是树不会形成环。图会形成环,所以图的搜索比较复杂,我们如果用之前的方法的话可能会出现死循环,所以我们要让它搜索的时候,找过的点不再找了。下面我们就用代码实现一下图的深度优先搜索和广度优先搜索。

代码实现图的深度优先搜索

function Node(value) {
    this.value = value;
    this.neighbor = [];
}

var a = new Node("a");
var b = new Node("b");
var c = new Node("c");
var d = new Node("d");
var e = new Node("e");

a.neighbor.push(b);
a.neighbor.push(c);
b.neighbor.push(a);
b.neighbor.push(c);
b.neighbor.push(d);
c.neighbor.push(a);
c.neighbor.push(b);
c.neighbor.push(d);
d.neighbor.push(b);
d.neighbor.push(c);
d.neighbor.push(e);
e.neighbor.push(d);

function deepSearch(node, target, path) {
    if (node == null) return false;
    if (path.indexOf(node) > -1) return false;//已经找过了就返回false
    if (node.value == target) return true;
    path.push(node);
    var result = false;
    for (var i = 0 ; i < node.neighbor.length ; i ++) {
        result |= deepSearch(node.neighbor[i], target, path);
    }
    return result ? true : false;
}

console.log(deepSearch(b, "e", []));

代码实现图的广度优先搜索

function Node(value) {
    this.value = value;
    this.neighbor = [];
}

var a = new Node("a");
var b = new Node("b");
var c = new Node("c");
var d = new Node("d");
var e = new Node("e");

a.neighbor.push(b);
a.neighbor.push(c);
b.neighbor.push(a);
b.neighbor.push(c);
b.neighbor.push(d);
c.neighbor.push(a);
c.neighbor.push(b);
c.neighbor.push(d);
d.neighbor.push(b);
d.neighbor.push(c);
d.neighbor.push(e);
e.neighbor.push(d);

function bfs(nodes, target, path) {
    if (nodes == null || nodes.length == 0) return false;
    var nextNodes = [];
    for (var i = 0 ; i < nodes.length ; i ++) {
        if (path.indexOf(nodes[i]) > -1) continue;//如果已经找过了就跳过这个数
        path.push(nodes[i]);
        if (nodes[i].value == target) return true;
        else nextNodes = nextNodes.concat(nodes[i].neighbor);
    }
    return bfs(nextNodes, target, path);
}

console.log(bfs([c], "b", []));