Skip to content

Commit

Permalink
Merge 7dfa081 into a2d30b0
Browse files Browse the repository at this point in the history
  • Loading branch information
eush77 committed Aug 2, 2014
2 parents a2d30b0 + 7dfa081 commit ac25d9c
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 2 deletions.
55 changes: 55 additions & 0 deletions algorithms/graph/prim.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
'use strict';

var PriorityQueue = require('../../data_structures/priority_queue'),
Graph = require('../../data_structures/graph');


/**
* Prim's minimum spanning tree (forest) algorithm.
* Complexity: O(E * log(V)).
*
* @param {Graph} graph - Undirected graph.
* @return {Graph} Minimum spanning tree or forest
* (depending on whether input graph is connected itself).
*/
var prim = function (graph) {
if (graph.directed) {
throw new Error('Can\'t build MST of a directed graph.');
}

var mst = new Graph(false);
var parent = Object.create(null);

var q = new PriorityQueue();
graph.vertices.forEach(function (vertex) {
q.insert(vertex, Infinity);
});

/* jshint loopfunc: true */
while (!q.isEmpty()) {
var top = q.extract(true);
var vertex = top.item,
weight = top.priority;

if (parent[vertex]) {
mst.addEdge(parent[vertex], vertex, weight);
}
else {
mst.addVertex(vertex);
}

// Relax.
graph.neighbors(vertex).forEach(function (neighbor) {
var weight = graph.edge(vertex, neighbor);
if (weight < q.priority(neighbor)) {
q.changePriority(neighbor, weight);
parent[neighbor] = vertex;
}
});
}

return mst;
};


module.exports = prim;
8 changes: 6 additions & 2 deletions data_structures/priority_queue.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,13 @@ PriorityQueue.prototype.insert = function (item, priority) {
MinHeap.prototype.insert.call(this, o);
};

PriorityQueue.prototype.extract = function () {
PriorityQueue.prototype.extract = function (withPriority) {
var min = MinHeap.prototype.extract.call(this);
return min && min.item;
return withPriority ? min : min && min.item;
};

PriorityQueue.prototype.priority = function (item) {
return this._items[item].priority;
};

PriorityQueue.prototype.changePriority = function (item, priority) {
Expand Down
1 change: 1 addition & 0 deletions main.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ var lib = {
kruskal: require('./algorithms/graph/kruskal'),
breadthFirstSearch: require('./algorithms/graph/breadth_first_search'),
bfsShortestPath: require('./algorithms/graph/bfs_shortest_path'),
prim: require('./algorithms/graph/prim'),
},
Math: {
fibonacci: require('./algorithms/math/fibonacci'),
Expand Down
2 changes: 2 additions & 0 deletions test/algorithms/graph/minimum_spanning_tree.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use strict';

var kruskal = require('../../../algorithms/graph/kruskal'),
prim = require('../../../algorithms/graph/prim'),
Graph = require('../../../data_structures/graph'),
depthFirstSearch = require('../../../algorithms/graph/depth_first_search'),
assert = require('assert');
Expand Down Expand Up @@ -179,4 +180,5 @@ var testMstAlgorithm = function (mst) {

describe('Minimum Spanning Tree', function () {
describe('#Kruskal\'s Algorithm', testMstAlgorithm.bind(null, kruskal));
describe('#Prim\'s Algorithm', testMstAlgorithm.bind(null, prim));
});

0 comments on commit ac25d9c

Please sign in to comment.