[Algorithm] Breadth First JavaScript Search Algorithm for Graphs
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的更多相关文章
- [Algorithm] Beating the Binary Search algorithm – Interpolation Search, Galloping Search
From: http://blog.jobbole.com/73517/ 二分检索是查找有序数组最简单然而最有效的算法之一.现在的问题是,更复杂的算法能不能做的更好?我们先看一下其他方法. 有些情况下 ...
- [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 ...
- [Algorithms] Binary Search Algorithm using TypeScript
(binary search trees) which form the basis of modern databases and immutable data structures. Binary ...
- [Algorithm] A* Search Algorithm Basic
A* is a best-first search, meaning that it solves problems by searching amoung all possible paths to ...
- TSearch & TFileSearch Version 2.2 -Boyer-Moore-Horspool search algorithm
unit Searches; (*-----------------------------------------------------------------------------* | Co ...
- 笔试算法题(48):简介 - A*搜索算法(A Star Search Algorithm)
A*搜索算法(A Star Search Algorithm) A*算法主要用于在二维平面上寻找两个点之间的最短路径.在从起始点到目标点的过程中有很多个状态空间,DFS和BFS没有任何启发策略所以穷举 ...
- 【437】Binary search algorithm,二分搜索算法
Complexity: O(log(n)) Ref: Binary search algorithm or 二分搜索算法 Ref: C 版本 while 循环 C Language scripts b ...
- js binary search algorithm
js binary search algorithm js 二分查找算法 二分查找, 前置条件 存储在数组中 有序排列 理想条件: 数组是递增排列,数组中的元素互不相同; 重排 & 去重 顺序 ...
- 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 ...
随机推荐
- 哪里是Maven的中央存储库?
当你建立了一个Maven工程,Maven会检查你的pom.xml文件,确定要下载的依赖.首先,Maven将从您的本地库Maven查找,如果没有找到,Maven会从中央存储库-http://repo1. ...
- No entity found for query异常
错误为getSingleResult();获取值时获取不到报异常. getSingleResult的源码有一句: @throws EntityNotFoundException if there is ...
- iOS学习笔记02-UIScrollView
父类UIView方法 // autoresizingMask - 现在基本弃用,改用autoLayout typedef NS_OPTIONS(NSUInteger, UIViewAutoresizi ...
- 【bzoj2134】单选错位 期望
题目描述 输入 n很大,为了避免读入耗时太多,输入文件只有5个整数参数n, A, B, C, a1,由上交的程序产生数列a.下面给出pascal/C/C++的读入语句和产生序列的语句(默认从标准输入读 ...
- 【bzoj3170】[Tjoi 2013]松鼠聚会 旋转坐标系
题目描述 有N个小松鼠,它们的家用一个点x,y表示,两个点的距离定义为:点(x,y)和它周围的8个点即上下左右四个点和对角的四个点,距离为1.现在N个松鼠要走到一个松鼠家去,求走过的最短距离. 输入 ...
- 【Luogu】P2801教主的魔法(分块)
题目链接 激动qwq.这是我A的第一道分块. 分块之后对块内元素暴力sort.修改的时候对于整块打个标记,查询的时候只需要查C-tag就行了 对于非整块,暴力修改,改完之后sort 对于查询……非整块 ...
- NOIP2017赛前模拟(4):总结
题目: 1.打牌 给定n个整数(n<=1000000),按照扑克牌对子(x,x)或者顺子(x,x+1,x+2)打出牌···问最多可以打出多少次对子或者顺子?牌的大小<=1000000 2. ...
- yield的概念及使用姿势
概念: 当调用Thread.yield方法时,会给线程调度器一个当前线程愿意让出CPU使用的暗示,但是线程调度器可能会忽略这个暗示. 代码演示: public class YieldDemo impl ...
- 按 Tab 在多个 InputField 间切换
下面这个链接里的有些unity的东西还没搞懂..改天继续看 http://forum.unity3d.com/threads/tab-between-input-fields.263779/ if(I ...
- Wmap5 测试80端口 Your port 80 is actually used by :Server: Microsoft-HTTPAPI/2.0
问题:win7系统! 在wamp5的apache启动不了: 目录下点击[测试80端口]的时候提示:Your port 80 is actually used by : Server: Microsof ...