UNPKG

typescript-algorithms-and-datastructures

Version:
83 lines 3.78 kB
(function (factory) { if (typeof module === "object" && typeof module.exports === "object") { var v = factory(require, exports); if (v !== undefined) module.exports = v; } else if (typeof define === "function" && define.amd) { define(["require", "exports", "../BitMatrix", "../Queue"], factory); } })(function (require, exports) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const BitMatrix_1 = require("../BitMatrix"); const Queue_1 = require("../Queue"); class DirectedAdjacencyMatrixGraph { constructor(hashFunction) { this.hashFunction = (a) => a.toString(); this.vertices = {}; this.edgeToVertexMap = []; this.edges = new BitMatrix_1.BitMatrix(0, 0); this.hashFunction = hashFunction || this.hashFunction; } outdegree(vertex) { const vertexIndex = this.vertices[this.hashFunction(vertex)]; return this.edges.getRowIndexes(vertexIndex).map(vertexIndex => this.edgeToVertexMap[vertexIndex]); } adjacent(vertex) { return this.outdegree(vertex); } addNode(node) { this.edgeToVertexMap.push(node); const newNodeIndex = this.edges.size()[0]; this.vertices[this.hashFunction(node)] = newNodeIndex; this.edges.resize(newNodeIndex + 1, newNodeIndex + 1); return this; } addEdge(from, to) { const fromNodeIndex = this.vertices[this.hashFunction(from)]; const toNodeIndex = this.vertices[this.hashFunction(to)]; this.edges.set(fromNodeIndex, toNodeIndex, true); return this; } indegree(vertex) { const vertexIndex = this.vertices[this.hashFunction(vertex)]; const indexes = this.edges.getColIndexes(vertexIndex); return indexes.map(index => this.edgeToVertexMap[index]); } nodes() { return this.edgeToVertexMap.slice(0); } removeEdge(from, to) { const fromNodeIndex = this.vertices[this.hashFunction(from)]; const toNodeIndex = this.vertices[this.hashFunction(to)]; this.edges.set(fromNodeIndex, toNodeIndex, false); return this; } topologicalSort() { const sortedElements = []; const verticesCount = this.edges.size()[0]; const edgesCopy = this.edges.clone(); const verticesWithNoIncomingEdges = new Queue_1.Queue(verticesCount); edgesCopy.getIndexes(true) .map((column, index) => column.length === 0 ? index : -1) .filter(index => index !== -1) .forEach(index => verticesWithNoIncomingEdges.enqueue(index)); while (verticesWithNoIncomingEdges.size() > 0) { const currentNodeIndex = verticesWithNoIncomingEdges.dequeue(); sortedElements.push(this.edgeToVertexMap[currentNodeIndex]); edgesCopy.getRowIndexes(currentNodeIndex).forEach(index => { edgesCopy.set(currentNodeIndex, index, false); if (edgesCopy.getColIndexes(index).length === 0) { verticesWithNoIncomingEdges.enqueue(index); } }); } if (edgesCopy.count() > 0) { throw new Error(`The graph contains cycles.`); } return sortedElements; } } exports.DirectedAdjacencyMatrixGraph = DirectedAdjacencyMatrixGraph; }); //# sourceMappingURL=DirectedAdjacencyMatrixGraph.js.map