123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209 |
- //Link is like an Edge in the graph/tree structure
- class Link {
- constructor(from, to) {
- this.to = to;
- this.from = from;
- }
- } //Node--> Vertex
- class Node {
- constructor(id) {
- this.id = id;
- }
- }
- class Graph {
- constructor(NodeType) {
- this.nodes = {};
- this.links = {};
- }
- addNode(node) {
- if (this.nodes[node.id]) {
- throw new Error("Node already exists with ID " + node.id);
- }
- this.nodes[node.id] = node;
- if (!this.links[node.id]) this.links[node.id] = this._emptyLink();
- }
- _emptyLink() {
- return {
- out: new Set(),
- in: new Set()
- };
- } //double directionLink
- addDoubleLink(v1, v2) {
- let l1 = new Link(v1.id, v2.id);
- let l2 = new Link(v2.id, v1.id);
- this.nodes[v1.id].add(l1);
- this.nodes[v2.id].add(l2);
- }
- addOneWayLink(from, to) {
- let link = new Link(from.id, to.id);
- this.nodes[from.id].add(link);
- } //we give the link we
- addLink(link) {
- let from = link.from;
- let to = link.to;
- if (!this.nodes[from.id] || !this.nodes[to.id]) {
- throw new Error("One of the Nodes Doesnt Exist");
- }
- if (this.links[from.id].out.has(link) || this.links[to.id].in.has(link)) {
- throw new Error("Link already exists");
- }
- this.links[from.id].out.add(link);
- this.links[to.id].in.add(link);
- }
- removeLink(link) {
- this.links[link.from.id].out.delete(link);
- this.links[link.to.id].in.delete(link);
- }
- removeNode(node) {
- if (!this.nodes[node.id]) return true;
- let outlinks = this.links[node.id].out;
- let inlinks = this.links[node.id].in;
- outlinks.forEach(link => this.removeLink(link));
- inlinks.forEach(link => this.removeLink(link));
- delete this.nodes[node.id];
- delete this.links[node.id];
- return node;
- }
- DFSRecursive(start, cb) {
- if (!start) return null;
- var resultList = [];
- var visited = {};
- var links = this.links;
- var found = false;
- (function dfs(vertex) {
- visited[vertex.id] = true;
- resultList.push(vertex); //console.log(resultList)
- if (cb(vertex) === true) {
- //console.log("####true")
- found = true;
- return resultList;
- }
- for (var link of links[vertex.id].out) {
- if (!visited[link.to.id]) {
- let res = dfs(link.to.id);
- if (found) return;
- resultList.pop();
- }
- }
- })(start);
- return resultList;
- } //depth first
- DFS(start, cb) {
- var visited = {};
- visited[start.id] = true;
- var stack = [start];
- var stackRes = [[]];
- let vertex;
- while (stack.length) {
- vertex = stack.pop();
- let res = stackRes.pop(); // console.log(res);
- if (cb(vertex) === true) {
- return [...res, vertex];
- }
- for (var link of this.links[vertex.id].out) {
- if (!visited[link.to.id]) {
- visited[link.to.id] = true;
- stack.push(link.to);
- stackRes.push([...res, vertex]);
- }
- } // resultList.pop();
- }
- return false;
- }
- BFS(start, cb) {
- var visited = {
- [start.id]: true
- };
- var stack = [start];
- var stackRes = [[]];
- let vertex;
- while (stack.length) {
- vertex = stack.shift();
- let res = stackRes.shift();
- if (cb(vertex) === true) {
- return [...res, vertex];
- }
- for (var link of this.links[vertex.id].out) {
- if (!visited[link.to.id]) {
- visited[link.to.id] = true;
- stack.push(link.to);
- stackRes.push([...res, vertex]);
- }
- }
- }
- return false;
- }
- }
- var graph = new Graph(Node);
- 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');
- var F = new Node("F");
- var AB = new Link(A, B);
- var AD = new Link(A, D);
- var BC = new Link(B, C);
- var CF = new Link(C, F);
- var DB = new Link(D, B);
- var DE = new Link(D, E);
- var EF = new Link(E, F);
- var FE = new Link(F, E);
- graph.addNode(A);
- graph.addNode(B);
- graph.addNode(C);
- graph.addNode(D);
- graph.addNode(E);
- graph.addNode(F);
- graph.addLink(AB);
- graph.addLink(AD);
- graph.addLink(BC);
- graph.addLink(CF);
- graph.addLink(DB);
- graph.addLink(DE);
- graph.addLink(EF);
- graph.addLink(FE);
- let recur = graph.DFS(A, node => node.id === E.id);
- let bfs = graph.BFS(A, node => node.id === C.id);
- module.exports = {
- Node,
- Link,
- Graph
- }; //console.log(tree.links)
|