Skip to content

Commit f6c32e9

Browse files
authored
Merge branch 'master' into sushant
2 parents 3ccdc1b + 8726d40 commit f6c32e9

23 files changed

+2460
-206
lines changed

DIRECTORY.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@
173173
- 📄 [TarjansAlgorithm](src/main/java/com/thealgorithms/datastructures/graphs/TarjansAlgorithm.java)
174174
- 📄 [UndirectedAdjacencyListGraph](src/main/java/com/thealgorithms/datastructures/graphs/UndirectedAdjacencyListGraph.java)
175175
- 📄 [WelshPowell](src/main/java/com/thealgorithms/datastructures/graphs/WelshPowell.java)
176+
- 📄 [TwoSat](src/main/java/com/thealgorithms/datastructures/graphs/TwoSat.java)
176177
- 📁 **hashmap**
177178
- 📁 **hashing**
178179
- 📄 [GenericHashMapUsingArray](src/main/java/com/thealgorithms/datastructures/hashmap/hashing/GenericHashMapUsingArray.java)
@@ -352,6 +353,8 @@
352353
- 📄 [PredecessorConstrainedDfs](src/main/java/com/thealgorithms/graph/PredecessorConstrainedDfs.java)
353354
- 📄 [StronglyConnectedComponentOptimized](src/main/java/com/thealgorithms/graph/StronglyConnectedComponentOptimized.java)
354355
- 📄 [TravelingSalesman](src/main/java/com/thealgorithms/graph/TravelingSalesman.java)
356+
- 📄 [Dinic](src/main/java/com/thealgorithms/graph/Dinic.java)
357+
- 📄 [YensKShortestPaths](src/main/java/com/thealgorithms/graph/YensKShortestPaths.java)
355358
- 📁 **greedyalgorithms**
356359
- 📄 [ActivitySelection](src/main/java/com/thealgorithms/greedyalgorithms/ActivitySelection.java)
357360
- 📄 [BandwidthAllocation](src/main/java/com/thealgorithms/greedyalgorithms/BandwidthAllocation.java)

src/main/java/com/thealgorithms/datastructures/bloomfilter/BloomFilter.java

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.thealgorithms.datastructures.bloomfilter;
22

3+
import java.util.Arrays;
34
import java.util.BitSet;
45

56
/**
@@ -115,7 +116,7 @@ private static class Hash<T> {
115116
* @return the computed hash value
116117
*/
117118
public int compute(T key) {
118-
return index * asciiString(String.valueOf(key));
119+
return index * contentHash(key);
119120
}
120121

121122
/**
@@ -135,5 +136,31 @@ private int asciiString(String word) {
135136
}
136137
return sum;
137138
}
139+
140+
/**
141+
* Computes a content-based hash for arrays; falls back to ASCII-sum of String value otherwise.
142+
*/
143+
private int contentHash(Object key) {
144+
if (key instanceof int[]) {
145+
return Arrays.hashCode((int[]) key);
146+
} else if (key instanceof long[]) {
147+
return Arrays.hashCode((long[]) key);
148+
} else if (key instanceof byte[]) {
149+
return Arrays.hashCode((byte[]) key);
150+
} else if (key instanceof short[]) {
151+
return Arrays.hashCode((short[]) key);
152+
} else if (key instanceof char[]) {
153+
return Arrays.hashCode((char[]) key);
154+
} else if (key instanceof boolean[]) {
155+
return Arrays.hashCode((boolean[]) key);
156+
} else if (key instanceof float[]) {
157+
return Arrays.hashCode((float[]) key);
158+
} else if (key instanceof double[]) {
159+
return Arrays.hashCode((double[]) key);
160+
} else if (key instanceof Object[]) {
161+
return Arrays.deepHashCode((Object[]) key);
162+
}
163+
return asciiString(String.valueOf(key));
164+
}
138165
}
139166
}
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
package com.thealgorithms.datastructures.graphs;
2+
3+
import java.util.ArrayList;
4+
import java.util.Arrays;
5+
import java.util.HashSet;
6+
import java.util.List;
7+
import java.util.Set;
8+
9+
/**
10+
* An implementation of Dial's Algorithm for the single-source shortest path problem.
11+
* This algorithm is an optimization of Dijkstra's algorithm and is particularly
12+
* efficient for graphs with small, non-negative integer edge weights.
13+
*
14+
* It uses a bucket queue (implemented here as a List of HashSets) to store vertices,
15+
* where each bucket corresponds to a specific distance from the source. This is more
16+
* efficient than a standard priority queue when the range of edge weights is small.
17+
*
18+
* Time Complexity: O(E + W * V), where E is the number of edges, V is the number
19+
* of vertices, and W is the maximum weight of any edge.
20+
*
21+
* @see <a href="https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm#Dial's_algorithm">Wikipedia - Dial's Algorithm</a>
22+
*/
23+
public final class DialsAlgorithm {
24+
/**
25+
* Private constructor to prevent instantiation of this utility class.
26+
*/
27+
private DialsAlgorithm() {
28+
}
29+
/**
30+
* Represents an edge in the graph, connecting to a destination vertex with a given weight.
31+
*/
32+
public static class Edge {
33+
private final int destination;
34+
private final int weight;
35+
36+
public Edge(int destination, int weight) {
37+
this.destination = destination;
38+
this.weight = weight;
39+
}
40+
41+
public int getDestination() {
42+
return destination;
43+
}
44+
45+
public int getWeight() {
46+
return weight;
47+
}
48+
}
49+
/**
50+
* Finds the shortest paths from a source vertex to all other vertices in a weighted graph.
51+
*
52+
* @param graph The graph represented as an adjacency list.
53+
* @param source The source vertex to start from (0-indexed).
54+
* @param maxEdgeWeight The maximum weight of any single edge in the graph.
55+
* @return An array of integers where the value at each index `i` is the
56+
* shortest distance from the source to vertex `i`. Unreachable vertices
57+
* will have a value of Integer.MAX_VALUE.
58+
* @throws IllegalArgumentException if the source vertex is out of bounds.
59+
*/
60+
public static int[] run(List<List<Edge>> graph, int source, int maxEdgeWeight) {
61+
int numVertices = graph.size();
62+
if (source < 0 || source >= numVertices) {
63+
throw new IllegalArgumentException("Source vertex is out of bounds.");
64+
}
65+
66+
// Initialize distances array
67+
int[] distances = new int[numVertices];
68+
Arrays.fill(distances, Integer.MAX_VALUE);
69+
distances[source] = 0;
70+
71+
// The bucket queue. Size is determined by the max possible path length.
72+
int maxPathWeight = maxEdgeWeight * (numVertices > 0 ? numVertices - 1 : 0);
73+
List<Set<Integer>> buckets = new ArrayList<>(maxPathWeight + 1);
74+
for (int i = 0; i <= maxPathWeight; i++) {
75+
buckets.add(new HashSet<>());
76+
}
77+
78+
// Add the source vertex to the first bucket
79+
buckets.get(0).add(source);
80+
81+
// Process buckets in increasing order of distance
82+
for (int d = 0; d <= maxPathWeight; d++) {
83+
// Process all vertices in the current bucket
84+
while (!buckets.get(d).isEmpty()) {
85+
// Get and remove a vertex from the current bucket
86+
int u = buckets.get(d).iterator().next();
87+
buckets.get(d).remove(u);
88+
89+
// If we've found a shorter path already, skip
90+
if (d > distances[u]) {
91+
continue;
92+
}
93+
94+
// Relax all adjacent edges
95+
for (Edge edge : graph.get(u)) {
96+
int v = edge.getDestination();
97+
int weight = edge.getWeight();
98+
99+
// If a shorter path to v is found
100+
if (distances[u] != Integer.MAX_VALUE && distances[u] + weight < distances[v]) {
101+
// If v was already in a bucket, remove it from the old one
102+
if (distances[v] != Integer.MAX_VALUE) {
103+
buckets.get(distances[v]).remove(v);
104+
}
105+
// Update distance and move v to the new bucket
106+
distances[v] = distances[u] + weight;
107+
buckets.get(distances[v]).add(v);
108+
}
109+
}
110+
}
111+
}
112+
return distances;
113+
}
114+
}

0 commit comments

Comments
 (0)