lgrthms
Version:
Algorithms and data structures for your JavaScript and TypeScript projects 🧑💻
78 lines (77 loc) • 3.35 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.bfsShortestPath = exports.dijkstrasAlgorithm = void 0;
const MinHeap_1 = require("../../dataStructures/MinHeap");
const Queue_1 = require("../../dataStructures/Queue");
// O((n + e) * nlog(n)) time | O(n) space — where
// n is the number of nodes
// e is the number of edges
function dijkstrasAlgorithm(startId, finishId, graph) {
const nodeInfos = {};
const nodeInfosHeap = new MinHeap_1.MinHeap((a, b) => a.distance - b.distance);
if (!graph.getNode(startId) || !graph.getNode(finishId)) {
return getResultantPath(finishId, nodeInfos);
}
const startInfo = { nodeId: startId, prevId: '', distance: 0 };
nodeInfos[startId] = startInfo;
nodeInfosHeap.insert(startInfo);
while (nodeInfosHeap.size > 0) {
const nodeInfo = nodeInfosHeap.extract();
const node = graph.getNode(nodeInfo.nodeId);
for (const neighborId in node.edges) {
const currentDistance = nodeInfo.distance;
const distanceToNeighbor = node.edges[neighborId];
const totalDistance = currentDistance + distanceToNeighbor;
if (nodeInfos[neighborId] === undefined || totalDistance < nodeInfos[neighborId].distance) {
const neighborInfo = { nodeId: neighborId, prevId: nodeInfo.nodeId, distance: totalDistance };
nodeInfos[neighborId] = neighborInfo;
nodeInfosHeap.insert(neighborInfo);
}
}
}
return getResultantPath(finishId, nodeInfos);
}
exports.dijkstrasAlgorithm = dijkstrasAlgorithm;
// O(n + e) time | O(n) space — where
// n is the number of nodes
// e is the number of edges
function bfsShortestPath(startId, finishId, graph) {
const nodeInfos = {};
const queue = new Queue_1.Queue();
if (!graph.getNode(startId) || !graph.getNode(finishId)) {
return getResultantPath(finishId, nodeInfos);
}
const startInfo = { nodeId: startId, prevId: '', distance: 0 };
nodeInfos[startId] = startInfo;
queue.enqueue(startInfo);
while (queue.size > 0) {
const nodeInfo = queue.dequeue();
const node = graph.getNode(nodeInfo.nodeId);
for (const neighborId in node.edges) {
const currentDistance = nodeInfo.distance;
const distanceToNeighbor = node.edges[neighborId];
const totalDistance = currentDistance + distanceToNeighbor;
if (nodeInfos[neighborId] === undefined || totalDistance < nodeInfos[neighborId].distance) {
const neighborInfo = { nodeId: neighborId, prevId: nodeInfo.nodeId, distance: totalDistance };
nodeInfos[neighborId] = neighborInfo;
queue.enqueue(neighborInfo);
}
}
}
return getResultantPath(finishId, nodeInfos);
}
exports.bfsShortestPath = bfsShortestPath;
function getResultantPath(finishId, nodeInfos) {
const resultantPath = { path: [], distance: -1 };
if (nodeInfos[finishId] === undefined) {
return resultantPath;
}
resultantPath.distance = nodeInfos[finishId].distance;
let currentId = finishId;
while (currentId) {
resultantPath.path.push(currentId);
currentId = nodeInfos[currentId].prevId;
}
resultantPath.path.reverse();
return resultantPath;
}