mirror of
https://github.com/20kaushik02/spotify-manager.git
synced 2026-01-25 14:14:06 +00:00
editorconfig
This commit is contained in:
134
utils/graph.js
134
utils/graph.js
@@ -4,9 +4,9 @@ const typedefs = require("../typedefs");
|
||||
|
||||
/**
|
||||
* Directed graph, may or may not be connected.
|
||||
*
|
||||
*
|
||||
* NOTE: Assumes that nodes and edges are valid.
|
||||
*
|
||||
*
|
||||
* Example:
|
||||
* ```javascript
|
||||
* let nodes = ["a", "b", "c", "d", "e"];
|
||||
@@ -22,80 +22,80 @@ const typedefs = require("../typedefs");
|
||||
* ```
|
||||
*/
|
||||
class myGraph {
|
||||
/**
|
||||
* @param {string[]} nodes Graph nodes IDs
|
||||
* @param {{ from: string, to: string }[]} edges Graph edges b/w nodes
|
||||
*/
|
||||
constructor(nodes, edges) {
|
||||
this.nodes = [...nodes];
|
||||
this.edges = structuredClone(edges);
|
||||
}
|
||||
/**
|
||||
* @param {string[]} nodes Graph nodes IDs
|
||||
* @param {{ from: string, to: string }[]} edges Graph edges b/w nodes
|
||||
*/
|
||||
constructor(nodes, edges) {
|
||||
this.nodes = [...nodes];
|
||||
this.edges = structuredClone(edges);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} node
|
||||
* @returns {string[]}
|
||||
*/
|
||||
getDirectHeads(node) {
|
||||
return this.edges.filter(edge => edge.to == node).map(edge => edge.from);
|
||||
}
|
||||
/**
|
||||
* @param {string} node
|
||||
* @returns {string[]}
|
||||
*/
|
||||
getDirectHeads(node) {
|
||||
return this.edges.filter(edge => edge.to == node).map(edge => edge.from);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} node
|
||||
* @returns {string[]}
|
||||
*/
|
||||
getDirectTails(node) {
|
||||
return this.edges.filter(edge => edge.from == node).map(edge => edge.to);
|
||||
}
|
||||
/**
|
||||
* @param {string} node
|
||||
* @returns {string[]}
|
||||
*/
|
||||
getDirectTails(node) {
|
||||
return this.edges.filter(edge => edge.from == node).map(edge => edge.to);
|
||||
}
|
||||
|
||||
/**
|
||||
* Kahn's topological sort
|
||||
* @returns {string[]}
|
||||
*/
|
||||
topoSort() {
|
||||
let inDegree = {};
|
||||
let zeroInDegreeQueue = [];
|
||||
let topologicalOrder = [];
|
||||
/**
|
||||
* Kahn's topological sort
|
||||
* @returns {string[]}
|
||||
*/
|
||||
topoSort() {
|
||||
let inDegree = {};
|
||||
let zeroInDegreeQueue = [];
|
||||
let topologicalOrder = [];
|
||||
|
||||
// Initialize inDegree of all nodes to 0
|
||||
for (let node of this.nodes) {
|
||||
inDegree[node] = 0;
|
||||
}
|
||||
// Initialize inDegree of all nodes to 0
|
||||
for (let node of this.nodes) {
|
||||
inDegree[node] = 0;
|
||||
}
|
||||
|
||||
// Calculate inDegree of each node
|
||||
for (let edge of this.edges) {
|
||||
inDegree[edge.to]++;
|
||||
}
|
||||
// Calculate inDegree of each node
|
||||
for (let edge of this.edges) {
|
||||
inDegree[edge.to]++;
|
||||
}
|
||||
|
||||
// Collect nodes with 0 inDegree
|
||||
for (let node of this.nodes) {
|
||||
if (inDegree[node] === 0) {
|
||||
zeroInDegreeQueue.push(node);
|
||||
}
|
||||
}
|
||||
// Collect nodes with 0 inDegree
|
||||
for (let node of this.nodes) {
|
||||
if (inDegree[node] === 0) {
|
||||
zeroInDegreeQueue.push(node);
|
||||
}
|
||||
}
|
||||
|
||||
// process nodes with 0 inDegree
|
||||
while (zeroInDegreeQueue.length > 0) {
|
||||
let node = zeroInDegreeQueue.shift();
|
||||
topologicalOrder.push(node);
|
||||
// process nodes with 0 inDegree
|
||||
while (zeroInDegreeQueue.length > 0) {
|
||||
let node = zeroInDegreeQueue.shift();
|
||||
topologicalOrder.push(node);
|
||||
|
||||
for (let tail of this.getDirectTails(node)) {
|
||||
inDegree[tail]--;
|
||||
if (inDegree[tail] === 0) {
|
||||
zeroInDegreeQueue.push(tail);
|
||||
}
|
||||
}
|
||||
}
|
||||
return topologicalOrder;
|
||||
}
|
||||
for (let tail of this.getDirectTails(node)) {
|
||||
inDegree[tail]--;
|
||||
if (inDegree[tail] === 0) {
|
||||
zeroInDegreeQueue.push(tail);
|
||||
}
|
||||
}
|
||||
}
|
||||
return topologicalOrder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the graph contains a cycle
|
||||
* @returns {boolean}
|
||||
*/
|
||||
detectCycle() {
|
||||
// If topological order includes all nodes, no cycle exists
|
||||
return this.topoSort().length < this.nodes.length;
|
||||
}
|
||||
/**
|
||||
* Check if the graph contains a cycle
|
||||
* @returns {boolean}
|
||||
*/
|
||||
detectCycle() {
|
||||
// If topological order includes all nodes, no cycle exists
|
||||
return this.topoSort().length < this.nodes.length;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = myGraph;
|
||||
|
||||
Reference in New Issue
Block a user