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
JavaScript
// 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
};