graph.js 3.7 KB

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