UNPKG

srikar526_graph_and_string_algorithms

Version:

A collection of common graph and string algorithms in JavaScript, including Dijkstra's, Floyd-Warshall, Union-Find, Naive Pattern Matching, and Rabin-Karp.

192 lines (164 loc) 7.16 kB
// Dijkstra's Algorithm // Function to find the vertex with the minimum distance from the set of vertices not yet processed function minimumDistance(distance, visited, n) { let min = Infinity; // Initialize the minimum distance let minIndex = -1; // Initialize the index of the vertex with the minimum distance // Loop through all vertices to find the vertex with the minimum distance for (let i = 0; i < n; i++) { if (!visited[i] && distance[i] <= min) { min = distance[i]; minIndex = i; } } return minIndex; } // Recursive function to print the path from source to the given vertex function printParentPath(parent, i) { if (parent[i] === -1) { return; // Base case: if no parent, we are at the source vertex } printParentPath(parent, parent[i]); // Recursively print the path console.log(i + 1 + " "); // Print the current vertex } // Function to implement Dijkstra's shortest path algorithm function dijkstra(graph, source, n) { const distance = Array(n).fill(Infinity); // Initialize the distance array with infinity const visited = Array(n).fill(false); // Initialize the visited array with false const parent = Array(n).fill(-1); // Array to store the parent of each vertex distance[source] = 0; // Set the distance of the source vertex to 0 // Loop through all vertices for (let i = 0; i < n - 1; i++) { const u = minimumDistance(distance, visited, n); // Get the vertex with the minimum distance visited[u] = true; // Mark the vertex as visited // Update the distances to the neighboring vertices for (let j = 0; j < n; j++) { const currentDistance = distance[u] + graph[u][j]; // Calculate the distance to the neighbor if (!visited[j] && graph[u][j] && currentDistance < distance[j]) { parent[j] = u; // Update the parent of the vertex distance[j] = currentDistance; // Update the distance } } } // Print the shortest paths from the source to all other vertices console.log("Vertex\t\tDistance\tPath"); for (let i = 1; i < n; i++) { if (distance[i] >= Infinity) { console.log(source + 1 + "->" + i + 1 + "\t\t Path Does not exist"); break; } console.log(source + 1 + "->" + i + 1 + "\t\t" + distance[i] + "\t\t" + source + 1); printParentPath(parent, i); // Print the path for the vertex console.log(); } } // Floyd Warshall Algorithm // Function to implement the Floyd Warshall algorithm to find shortest paths between all pairs of vertices function floydWarshall(graph, n) { // Update the graph to store the shortest distances between all pairs of vertices for (let k = 0; k < n; k++) { for (let i = 0; i < n; i++) { for (let j = 0; j < n; j++) { if (graph[i][j] > graph[i][k] + graph[k][j]) { graph[i][j] = graph[i][k] + graph[k][j]; // Update the distance } } } } // Print the resulting shortest path matrix console.log("The shortest path matrix is: "); for (let i = 0; i < n; i++) { for (let j = 0; j < n; j++) { console.log(graph[i][j] + " "); // Print the shortest distance between vertex i and vertex j } console.log(); } } // Union-Find Algorithm (for Cycle Detection) // Function to find the representative of a set function find(parent, i) { if (parent[i] === i) { return i; // Return the representative if it is the root } return find(parent, parent[i]); // Recursively find the root } // Function to perform union of two sets function union(parent, x, y) { parent[x] = y; // Make y the parent of x } // Function to check if there is a cycle in the graph function isCycle(graph, V, E) { const parent = Array(V).fill(0).map((_, idx) => idx); // Initialize each vertex as its own parent // Loop through all edges in the graph for (let i = 0; i < E; i++) { const x = find(parent, graph[i].src); // Find the representative of the source vertex const y = find(parent, graph[i].dest); // Find the representative of the destination vertex if (x === y) { return true; // A cycle is detected if both vertices have the same representative } union(parent, x, y); // Otherwise, unite the two sets } return false; // No cycle found } // Naive Pattern Matching Algorithm // Function to implement the naive pattern matching algorithm function naivePatternSearch(text, pattern) { const m = pattern.length; // Length of the pattern const n = text.length; // Length of the text // Loop through all possible starting positions in the text for (let i = 0; i <= n - m; i++) { let j; // Check if the substring starting at index i matches the pattern for (j = 0; j < m; j++) { if (text[i + j] !== pattern[j]) break; // If a mismatch occurs, break } if (j === m) { console.log(`Pattern found at index ${i} in the main string`); // Pattern found } } } // Rabin-Karp Algorithm // Function to implement the Rabin-Karp algorithm function rabinKarp(pattern, text, q) { const m = pattern.length; // Length of the pattern const n = text.length; // Length of the text let p = 0; // Hash value for the pattern let t = 0; // Hash value for the text let h = 1; // Initial hash value let count = 0; // Count of pattern occurrences // Precompute the value of h (d^(m-1) % q) for (let i = 0; i < m - 1; i++) { h = (h * 10) % q; // Update the hash multiplier } // Calculate the hash value for the pattern and the first window of the text for (let i = 0; i < m; i++) { p = (10 * p + pattern.charCodeAt(i)) % q; t = (10 * t + text.charCodeAt(i)) % q; } // Loop through the text to find occurrences of the pattern for (let i = 0; i <= n - m; i++) { if (p === t) { // If hash values match, check if the pattern matches let j; for (j = 0; j < m; j++) { if (text[i + j] !== pattern[j]) break; // If mismatch occurs, break } if (j === m) { console.log(`Pattern is found at position: ${i + 1}`); // Pattern found count++; } } // Update the hash value for the next window of the text if (i < n - m) { t = (10 * (t - text.charCodeAt(i) * h) + text.charCodeAt(i + m)) % q; if (t < 0) t = (t + q); // Handle negative hash values } } return count; } // Export the algorithms for usage in other applications module.exports = { dijkstra, floydWarshall, isCycle, naivePatternSearch, rabinKarp };