Skip to content

Instantly share code, notes, and snippets.

@Williammer
Last active June 5, 2016 04:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Williammer/04f2228fd7175966a1650079ca758448 to your computer and use it in GitHub Desktop.
Save Williammer/04f2228fd7175966a1650079ca758448 to your computer and use it in GitHub Desktop.
Graphic related algorithm
function cat() {
var head = _.first(arguments);
if (existy(head))
return head.concat.apply(head, _.rest(arguments));
else
return [];
}
function construct(head, tail) {
return cat([head], _.toArray(tail));
}
function nexts(graph, node) {
if (_.isEmpty(graph)) return [];
var pair = _.first(graph);
var from = _.first(pair);
var to = second(pair);
var more = _.rest(graph);
if (_.isEqual(node, from))
// if it's the 1st of 1st pair -> 2nd of 1st pair + 2nd of other pairs
return construct(to, nexts(more, node));
else
return nexts(more, node);
}
function depthSearch(graph, nodes, seen) {
if (_.isEmpty(nodes)) return rev(seen);
var node = _.first(nodes);
var more = _.rest(nodes);
if (_.contains(seen, node))
// seen this node already, see the rest
return depthSearch(graph, more, seen);
else
// 1st seen thsi node, go on to all it's 2nd node with other nodes(this manifests DFS)
return depthSearch(graph,
cat(nexts(graph, node), more),
construct(node, seen));
}
function Graph(v) {
this.vertices = v;
this.vertexList = [];
this.edges = 0;
this.adj = [];
for (var i = 0; i < this.vertices; ++i) {
this.adj[i] = [];
this.adj[i].push("");
}
this.addEdge = addEdge;
this.showGraph = showGraph;
this.dfs = dfs;
this.marked = [];
for (var i = 0; i < this.vertices; ++i) {
this.marked[i] = false;
}
this.bfs = bfs;
this.edgeTo = [];
this.hasPathTo = hasPathTo;
this.pathTo = pathTo;
this.topSortHelper = topSortHelper;
this.topSort = topSort;
}
function topSort() {
var stack = [];
var visited = [];
for (var i = 0; i < this.vertices; i++) {
visited[i] = false;
}
for (var i = 0; i < this.vertices; i++) {
if (visited[i] == false) {
this.topSortHelper(i, visited, stack);
}
}
for (var i = 0; i < stack.length; i++) {
if (stack[i] != undefined && stack[i] != false) {
print(this.vertexList[stack[i]]);
}
}
}
function topSortHelper(v, visited, stack) {
visited[v] = true;
for each(var w in this.adj[v]) {
if (!visited[w]) {
this.topSortHelper(visited[w], visited, stack);
}
}
stack.push(v);
}
function addEdge(v, w) {
this.adj[v].push(w);
this.adj[w].push(v);
this.edges++;
}
/*function showGraph() {
for (var i = 0; i < this.vertices; ++i) {
putstr(i + " -> ");
for (var j = 0; j < this.vertices; ++j) {
if (this.adj[i][j] != undefined)
putstr(this.adj[i][j] + ' ');
}
print();
}
}*/
// a new function to display symbolic names instead of numbers
function showGraph() {
var visited = [];
for (var i = 0; i < this.vertices; ++i) {
putstr(this.vertexList[i] + " -> ");
visited.push(this.vertexList[i]);
for (var j = 0; j < this.vertices; ++j) {
if (this.adj[i][j] != undefined) {
if (visited.indexOf(this.vertexList[j]) < 0) {
putstr(this.vertexList[j] + ' ');
}
}
}
print();
visited.pop();
}
}
function dfs(v) {
this.marked[v] = true;
if (this.adj[v] != undefined) {
print("Visited vertex: " + v);
}
for each(var w in this.adj[v]) {
if (!this.marked[w]) {
this.dfs(w);
}
}
}
function bfs(s) {
var queue = [];
this.marked[s] = true;
queue.unshift(s);
while (queue.length > 0) {
var v = queue.shift();
if (typeof(v) != "string") {
print("Visited vertex: " + v);
}
for each(var w in this.adj[v]) {
if (!this.marked[w]) {
this.edgeTo[w] = v;
this.marked[w] = true;
queue.unshift(w);
}
}
}
}
function hasPathTo(v) {
return this.marked[v];
}
function pathTo(v) {
var source = 0;
if (!this.hasPathTo(v)) {
return undefined;
}
var path = [];
for (var i = v; i != source; i = this.edgeTo[i]) {
path.push(i);
}
path.push(s);
return path;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment