dist-javascript-algorithms-and-data-structures
Version:
Algorithms and data-structures implemented on JavaScript
73 lines (52 loc) • 2.77 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = prim;
var _Graph = _interopRequireDefault(require("../../../data-structures/graph/Graph"));
var _PriorityQueue = _interopRequireDefault(require("../../../data-structures/priority-queue/PriorityQueue"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* @param {Graph} graph
* @return {Graph}
*/
function prim(graph) {
// It should fire error if graph is directed since the algorithm works only
// for undirected graphs.
if (graph.isDirected) {
throw new Error('Prim\'s algorithms works only for undirected graphs');
} // Init new graph that will contain minimum spanning tree of original graph.
const minimumSpanningTree = new _Graph.default(); // This priority queue will contain all the edges that are starting from
// visited nodes and they will be ranked by edge weight - so that on each step
// we would always pick the edge with minimal edge weight.
const edgesQueue = new _PriorityQueue.default(); // Set of vertices that has been already visited.
const visitedVertices = {}; // Vertex from which we will start graph traversal.
const startVertex = graph.getAllVertices()[0]; // Add start vertex to the set of visited ones.
visitedVertices[startVertex.getKey()] = startVertex; // Add all edges of start vertex to the queue.
startVertex.getEdges().forEach(graphEdge => {
edgesQueue.add(graphEdge, graphEdge.weight);
}); // Now let's explore all queued edges.
while (!edgesQueue.isEmpty()) {
// Fetch next queued edge with minimal weight.
/** @var {GraphEdge} currentEdge */
const currentMinEdge = edgesQueue.poll(); // Find out the next unvisited minimal vertex to traverse.
let nextMinVertex = null;
if (!visitedVertices[currentMinEdge.startVertex.getKey()]) {
nextMinVertex = currentMinEdge.startVertex;
} else if (!visitedVertices[currentMinEdge.endVertex.getKey()]) {
nextMinVertex = currentMinEdge.endVertex;
} // If all vertices of current edge has been already visited then skip this round.
if (nextMinVertex) {
// Add current min edge to MST.
minimumSpanningTree.addEdge(currentMinEdge); // Add vertex to the set of visited ones.
visitedVertices[nextMinVertex.getKey()] = nextMinVertex; // Add all current vertex's edges to the queue.
nextMinVertex.getEdges().forEach(graphEdge => {
// Add only vertices that link to unvisited nodes.
if (!visitedVertices[graphEdge.startVertex.getKey()] || !visitedVertices[graphEdge.endVertex.getKey()]) {
edgesQueue.add(graphEdge, graphEdge.weight);
}
});
}
}
return minimumSpanningTree;
}