graph.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. //Link is like an Edge in the graph/tree structure
  2. class Link {
  3. constructor(from, to) {
  4. this.to = to;
  5. this.from = from;
  6. }
  7. } //Node--> Vertex
  8. class Node {
  9. constructor(id) {
  10. this.id = id;
  11. }
  12. }
  13. class Graph {
  14. constructor(NodeType) {
  15. this.nodes = {};
  16. this.links = {};
  17. }
  18. addNode(node) {
  19. if (this.nodes[node.id]) {
  20. throw new Error("Node already exists with ID " + node.id);
  21. }
  22. this.nodes[node.id] = node;
  23. if (!this.links[node.id]) this.links[node.id] = this._emptyLink();
  24. }
  25. _emptyLink() {
  26. return {
  27. out: new Set(),
  28. in: new Set()
  29. };
  30. } //double directionLink
  31. addDoubleLink(v1, v2) {
  32. let l1 = new Link(v1.id, v2.id);
  33. let l2 = new Link(v2.id, v1.id);
  34. this.nodes[v1.id].add(l1);
  35. this.nodes[v2.id].add(l2);
  36. }
  37. addOneWayLink(from, to) {
  38. let link = new Link(from.id, to.id);
  39. this.nodes[from.id].add(link);
  40. } //we give the link we
  41. addLink(link) {
  42. let from = link.from;
  43. let to = link.to;
  44. if (!this.nodes[from.id] || !this.nodes[to.id]) {
  45. throw new Error("One of the Nodes Doesnt Exist");
  46. }
  47. if (this.links[from.id].out.has(link) || this.links[to.id].in.has(link)) {
  48. throw new Error("Link already exists");
  49. }
  50. this.links[from.id].out.add(link);
  51. this.links[to.id].in.add(link);
  52. }
  53. removeLink(link) {
  54. this.links[link.from.id].out.delete(link);
  55. this.links[link.to.id].in.delete(link);
  56. }
  57. removeNode(node) {
  58. if (!this.nodes[node.id]) return true;
  59. let outlinks = this.links[node.id].out;
  60. let inlinks = this.links[node.id].in;
  61. outlinks.forEach(link => this.removeLink(link));
  62. inlinks.forEach(link => this.removeLink(link));
  63. delete this.nodes[node.id];
  64. delete this.links[node.id];
  65. return node;
  66. }
  67. DFSRecursive(start, cb) {
  68. if (!start) return null;
  69. var resultList = [];
  70. var visited = {};
  71. var links = this.links;
  72. var found = false;
  73. (function dfs(vertex) {
  74. visited[vertex.id] = true;
  75. resultList.push(vertex); //console.log(resultList)
  76. if (cb(vertex) === true) {
  77. //console.log("####true")
  78. found = true;
  79. return resultList;
  80. }
  81. for (var link of links[vertex.id].out) {
  82. if (!visited[link.to.id]) {
  83. let res = dfs(link.to.id);
  84. if (found) return;
  85. resultList.pop();
  86. }
  87. }
  88. })(start);
  89. return resultList;
  90. } //depth first
  91. DFS(start, cb) {
  92. var visited = {};
  93. visited[start.id] = true;
  94. var stack = [start];
  95. var stackRes = [[]];
  96. let vertex;
  97. while (stack.length) {
  98. vertex = stack.pop();
  99. let res = stackRes.pop(); // console.log(res);
  100. if (cb(vertex) === true) {
  101. return [...res, vertex];
  102. }
  103. for (var link of this.links[vertex.id].out) {
  104. if (!visited[link.to.id]) {
  105. visited[link.to.id] = true;
  106. stack.push(link.to);
  107. stackRes.push([...res, vertex]);
  108. }
  109. } // resultList.pop();
  110. }
  111. return false;
  112. }
  113. BFS(start, cb) {
  114. var visited = {
  115. [start.id]: true
  116. };
  117. var stack = [start];
  118. var stackRes = [[]];
  119. let vertex;
  120. while (stack.length) {
  121. vertex = stack.shift();
  122. let res = stackRes.shift();
  123. if (cb(vertex) === true) {
  124. return [...res, vertex];
  125. }
  126. for (var link of this.links[vertex.id].out) {
  127. if (!visited[link.to.id]) {
  128. visited[link.to.id] = true;
  129. stack.push(link.to);
  130. stackRes.push([...res, vertex]);
  131. }
  132. }
  133. }
  134. return false;
  135. }
  136. }
  137. var graph = new Graph(Node);
  138. var A = new Node("A");
  139. var B = new Node('B');
  140. var C = new Node('C');
  141. var D = new Node('D');
  142. var E = new Node('E');
  143. var F = new Node("F");
  144. var AB = new Link(A, B);
  145. var AD = new Link(A, D);
  146. var BC = new Link(B, C);
  147. var CF = new Link(C, F);
  148. var DB = new Link(D, B);
  149. var DE = new Link(D, E);
  150. var EF = new Link(E, F);
  151. var FE = new Link(F, E);
  152. graph.addNode(A);
  153. graph.addNode(B);
  154. graph.addNode(C);
  155. graph.addNode(D);
  156. graph.addNode(E);
  157. graph.addNode(F);
  158. graph.addLink(AB);
  159. graph.addLink(AD);
  160. graph.addLink(BC);
  161. graph.addLink(CF);
  162. graph.addLink(DB);
  163. graph.addLink(DE);
  164. graph.addLink(EF);
  165. graph.addLink(FE);
  166. let recur = graph.DFS(A, node => node.id === E.id);
  167. let bfs = graph.BFS(A, node => node.id === C.id);
  168. module.exports = {
  169. Node,
  170. Link,
  171. Graph
  172. }; //console.log(tree.links)