Breadth first search is a graph search algorithm that starts at one node and visits neighboring nodes as widely as possible before going further down any other path. This algorithm requires the use of a queue to keep track of which nodes to visit, so it might be worth your time to brush up on that data structure before watching this lesson.

 
const {createQueue} = require('./queue');

function createNode(key) {
let children = [];
return {
key,
children,
addChild(child) {
children.push(child)
}
}
} function createGraph(directed = false) {
const nodes = [];
const edges = []; return {
nodes,
edges,
directed, addNode(key) {
nodes.push(createNode(key))
}, getNode (key) {
return nodes.find(n => n.key === key)
}, addEdge (node1Key, node2Key) {
const node1 = this.getNode(node1Key);
const node2 = this.getNode(node2Key); node1.addChild(node2); if (!directed) {
node2.addChild(node1);
} edges.push(`${node1Key}${node2Key}`)
}, print() {
return nodes.map(({children, key}) => {
let result = `${key}`; if (children.length) {
result += ` => ${children.map(n => n.key).join(' ')}`
} return result;
}).join('\n')
},
/**
* Breadth First Search
*/
bfs (startNodeKey = "", visitFn = () => {}) {
/**
* Keytake away:
* 1. Using Queue to get next visit node
* 2. Enqueue the node's children for next run
* 3. Hashed visited map for keep tracking visited node
*/
const startNode = this.getNode(startNodeKey);
// create a hashed map to check whether one node has been visited
const visited = this.nodes.reduce((acc, curr) => {
acc[curr.key] = false;
return acc;
}, {}); // Create a queue to put all the nodes to be visited
const queue = createQueue();
queue.enqueue(startNode); // start process
while (!queue.isEmpty()) {
const current = queue.dequeue(); // check wheather the node exists in hashed map
if (!visited[current.key]) {
visitFn(current);
visited[current.key] = true; // process the node's children
current.children.map(n => {
if (!visited[n.key]) {
queue.enqueue(n);
}
});
}
}
}
}
} const graph = createGraph(true) graph.addNode('Kyle')
graph.addNode('Anna')
graph.addNode('Krios')
graph.addNode('Tali') graph.addEdge('Kyle', 'Anna')
graph.addEdge('Anna', 'Kyle')
graph.addEdge('Kyle', 'Krios')
graph.addEdge('Kyle', 'Tali')
graph.addEdge('Anna', 'Krios')
graph.addEdge('Anna', 'Tali')
graph.addEdge('Krios', 'Anna')
graph.addEdge('Tali', 'Kyle') console.log(graph.print()) const nodes = ['a', 'b', 'c', 'd', 'e', 'f']
const edges = [
['a', 'b'],
['a', 'e'],
['a', 'f'],
['b', 'd'],
['b', 'e'],
['c', 'b'],
['d', 'c'],
['d', 'e']
] const graph2 = createGraph(true)
nodes.forEach(node => {
graph2.addNode(node)
}) edges.forEach(nodes => {
graph2.addEdge(...nodes)
}) graph2.bfs('a', node => {
console.log(node.key) //a,b,e,f,d,c
})

A more general function:

        bfs (startNodeKey, predFn = () => {}, cb = () => {}) {
const startNode = this.getNode(startNodeKey);
const visited = createVistedMap(this.nodes);
const queue = createQueue();
startNode.children.forEach((n) => {
queue.enqueue(n);
});
while (!queue.isEmpty()) {
const current = queue.dequeue();
if (!visited[current.key]) {
if (predFn(current)) return cb(current);
else {
visited[current.key] = true;
}
}
}
cb(null)
},
let graph3 = createGraph(true)
const tyler = {key: 'tyler', dog: false};
const henry = {key: 'henry', dog: false};
const john = {key: 'john', dog: false};
const aimee = {key: 'aimee', dog: true};
const peggy = {key: 'peggy', dog: false};
const keli = {key: 'keli', dog: false};
const claire = {key: 'claire', dog: false}; graph3.addNode('tyler', tyler);
graph3.addNode('henry', henry);
graph3.addNode('john', john);
graph3.addNode('claire', claire);
graph3.addNode('aimee', aimee);
graph3.addNode('peggy', peggy)
graph3.addNode('keli', keli); graph3.addEdge('tyler', 'henry')
graph3.addEdge('tyler', 'john')
graph3.addEdge('tyler', 'aimee')
graph3.addEdge('henry', 'keli')
graph3.addEdge('henry', 'peggy')
graph3.addEdge('john', 'john')
graph3.addEdge('keli', 'claire') graph3.bfs2('tyler', (node) => {
return node.dog;
}, (node) => {
if (node) console.log(`${node.key} has a dog`)
else console.log('Tyler friends has no dog')
})

Time Complexity: O(V+E) where V is number of vertices in the graph and E is number of edges in the graph.

[Algorithm] Breadth First JavaScript Search Algorithm for Graphs的更多相关文章

  1. [Algorithm] Beating the Binary Search algorithm – Interpolation Search, Galloping Search

    From: http://blog.jobbole.com/73517/ 二分检索是查找有序数组最简单然而最有效的算法之一.现在的问题是,更复杂的算法能不能做的更好?我们先看一下其他方法. 有些情况下 ...

  2. [Algorithm] Write a Depth First Search Algorithm for Graphs in JavaScript

    Depth first search is a graph search algorithm that starts at one node and uses recursion to travel ...

  3. [Algorithms] Binary Search Algorithm using TypeScript

    (binary search trees) which form the basis of modern databases and immutable data structures. Binary ...

  4. [Algorithm] A* Search Algorithm Basic

    A* is a best-first search, meaning that it solves problems by searching amoung all possible paths to ...

  5. TSearch & TFileSearch Version 2.2 -Boyer-Moore-Horspool search algorithm

    unit Searches; (*-----------------------------------------------------------------------------* | Co ...

  6. 笔试算法题(48):简介 - A*搜索算法(A Star Search Algorithm)

    A*搜索算法(A Star Search Algorithm) A*算法主要用于在二维平面上寻找两个点之间的最短路径.在从起始点到目标点的过程中有很多个状态空间,DFS和BFS没有任何启发策略所以穷举 ...

  7. 【437】Binary search algorithm,二分搜索算法

    Complexity: O(log(n)) Ref: Binary search algorithm or 二分搜索算法 Ref: C 版本 while 循环 C Language scripts b ...

  8. js binary search algorithm

    js binary search algorithm js 二分查找算法 二分查找, 前置条件 存储在数组中 有序排列 理想条件: 数组是递增排列,数组中的元素互不相同; 重排 & 去重 顺序 ...

  9. PatentTips - Adaptive algorithm for selecting a virtualization algorithm in virtual machine environments

    BACKGROUND A Virtual Machine (VM) is an efficient, isolated duplicate of a real computer system. Mor ...

随机推荐

  1. Selenium WebDriver-操作单选框

    先判断按钮是否已经被选中 如果没有被选中,才可以点击 #encoding=utf-8 import unittest import time import chardet from selenium ...

  2. TensorFlow——零碎语法知识点

    张量(tensor) 张量 是图中计算节点的运算结果的引用,由name,shape,type三个属性构成. 张量的命名 可以以“name:src_output”的形式给出,node为计算节点名称,sr ...

  3. phpcms调用一个指定的栏目

    很多初学者在学习phpcms的时候在模板中都是静态的写导航的url,那样在后期维护的时候可是个巨大的工程啊,所以我在学的时候就想起织梦是能指定调用栏目的url,借鉴了这一想法, {$CATEGORY[ ...

  4. JavaScriptCore 简介

    转自http://esoftmobile.com/2013/06/19/integrating-javascript-into-native-applications/ Integrating Jav ...

  5. BZOJ4916 神犇和蒟蒻 【欧拉函数 + 杜教筛】

    题目 很久很久以前,有一只神犇叫yzy; 很久很久之后,有一只蒟蒻叫lty; 输入格式 请你读入一个整数N;1<=N<=1E9,A.B模1E9+7; 输出格式 请你输出一个整数A=\sum ...

  6. BZOJ3209 花神的数论题 【组合数 + 按位计数】

    题目 背景 众所周知,花神多年来凭借无边的神力狂虐各大 OJ.OI.CF.TC -- 当然也包括 CH 啦. 描述 话说花神这天又来讲课了.课后照例有超级难的神题啦-- 我等蒟蒻又遭殃了. 花神的题目 ...

  7. nginx日志打印请求响应时间

    log_format  timed_combined  '$remote_addr - $remote_user [$time_local] "$request" ' '$stat ...

  8. P1340 送礼物

    时间: 1000ms / 空间: 131072KiB / Java类名: Main 描述 作为惩罚,GY被遣送去帮助某神牛给女生送礼物(GY:貌似是个好差事)但是在GY看到礼物之后,他就不这么认为了. ...

  9. 【POJ1276】Cash Machine(多重背包单调队列优化)

    大神博客转载http://www.cppblog.com/MatoNo1/archive/2011/07/05/150231.aspx多重背包的单调队列初中就知道了但一直没(不会)写二进制优化初中就写 ...

  10. C#.net制作验证码(英文与数字组成的4位随机数),以及MD5值的使用

    原文发布时间为:2008-09-22 -- 来源于本人的百度文章 [由搬家工具导入] 参考资料:http://www.cnblogs.com/gwazy/articles/139510.html 三个 ...