Skip to content

Instantly share code, notes, and snippets.

@skoshy
Created May 6, 2017 16:00
Show Gist options
  • Save skoshy/643e448cc9795bc70e52694a60560ee1 to your computer and use it in GitHub Desktop.
Save skoshy/643e448cc9795bc70e52694a60560ee1 to your computer and use it in GitHub Desktop.
Basic graph for JS
/* Modified from http://blog.benoitvallon.com/data-structures-in-javascript/the-graph-data-structure/ */
function Graph() {
this.vertices = [];
this.edges = [];
this.numberOfEdges = 0;
this.addVertex = function(vertex) {
this.vertices.push(vertex);
this.edges[vertex] = [];
};
this.removeVertex = function(vertex) {
var index = this.vertices.includes(vertex);
if(~index) {
this.vertices.splice(index, 1);
}
while(this.edges[vertex].length) {
var adjacentVertex = this.edges[vertex].pop();
this.removeEdge(adjacentVertex, vertex);
}
};
this.addEdge = function(vertex1, vertex2) {
this.edges[vertex1].push(vertex2);
this.edges[vertex2].push(vertex1);
this.numberOfEdges++;
};
this.removeEdge = function(vertex1, vertex2) {
var index1 = this.edges[vertex1] ? this.edges[vertex1].indexOf(vertex2) : -1;
var index2 = this.edges[vertex2] ? this.edges[vertex2].indexOf(vertex1) : -1;
if(~index1) {
this.edges[vertex1].splice(index1, 1);
this.numberOfEdges--;
}
if(~index2) {
this.edges[vertex2].splice(index2, 1);
}
};
this.size = function() {
return this.vertices.length;
};
this.relations = function() {
return this.numberOfEdges;
};
this.traverseDFS = function(vertex, fn) {
if(!~this.vertices.indexOf(vertex)) {
return console.log('Vertex not found');
}
var visited = [];
this._traverseDFS(vertex, visited, fn);
};
this._traverseDFS = function(vertex, visited, fn) {
visited[vertex] = true;
if(this.edges[vertex] !== undefined) {
fn(vertex);
}
for(var i = 0; i < this.edges[vertex].length; i++) {
if(!visited[this.edges[vertex][i]]) {
this._traverseDFS(this.edges[vertex][i], visited, fn);
}
}
};
this.traverseBFS = function(vertex, fn) {
if(!~this.vertices.indexOf(vertex)) {
return console.log('Vertex not found');
}
var queue = [];
queue.push(vertex);
var visited = [];
visited[vertex] = true;
while(queue.length) {
vertex = queue.shift();
fn(vertex);
for(var i = 0; i < this.edges[vertex].length; i++) {
if(!visited[this.edges[vertex][i]]) {
visited[this.edges[vertex][i]] = true;
queue.push(this.edges[vertex][i]);
}
}
}
};
this.pathFromTo = function(vertexSource, vertexDestination) {
if(!~this.vertices.indexOf(vertexSource)) {
return console.log('Vertex not found');
}
var queue = [];
queue.push(vertexSource);
var visited = [];
visited[vertexSource] = true;
var paths = [];
while(queue.length) {
var vertex = queue.shift();
for(var i = 0; i < this.edges[vertex].length; i++) {
if(!visited[this.edges[vertex][i]]) {
visited[this.edges[vertex][i]] = true;
queue.push(this.edges[vertex][i]);
// save paths between vertices
paths[this.edges[vertex][i]] = vertex;
}
}
}
if(!visited[vertexDestination]) {
return undefined;
}
var path = [];
for(var j = vertexDestination; j != vertexSource; j = paths[j]) {
path.push(j);
}
path.push(j);
return path.reverse().join('-');
};
this.print = function() {
console.log(this.vertices.map(function(vertex) {
return (vertex + ' -> ' + this.edges[vertex].join(', ')).trim();
}, this).join(' | '));
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment