Skip to content

Commit c706d6c

Browse files
authored
Merge branch 'master' into master
2 parents 6bfc96c + 474e0de commit c706d6c

File tree

9 files changed

+614
-96
lines changed

9 files changed

+614
-96
lines changed

DIRECTORY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -871,6 +871,7 @@
871871
* [LeftistHeapTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/heaps/LeftistHeapTest.java)
872872
* [MedianFinderTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/heaps/MedianFinderTest.java)
873873
* [MergeKSortedArraysTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/heaps/MergeKSortedArraysTest.java)
874+
* [MinHeapTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/heaps/MinHeapTest.java)
874875
* [MinPriorityQueueTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/heaps/MinPriorityQueueTest.java)
875876
* lists
876877
* [CircleLinkedListTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/lists/CircleLinkedListTest.java)

src/main/java/com/thealgorithms/datastructures/graphs/WelshPowell.java

Lines changed: 106 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,41 @@
55
import java.util.HashSet;
66
import java.util.stream.IntStream;
77

8-
/*
9-
* The Welsh-Powell algorithm is a graph coloring algorithm
10-
* used for coloring a graph with the minimum number of colors.
11-
* https://en.wikipedia.org/wiki/Graph_coloring
8+
/**
9+
* The Welsh-Powell algorithm is a graph coloring algorithm that aims to color a graph
10+
* using the minimum number of colors such that no two adjacent vertices share the same color.
11+
*
12+
* <p>
13+
* The algorithm works by:
14+
* <ol>
15+
* <li>Sorting the vertices in descending order based on their degrees (number of edges connected).</li>
16+
* <li>Iterating through each vertex and assigning it the smallest available color that has not been used by its adjacent vertices.</li>
17+
* <li>Coloring adjacent vertices with the same color is avoided.</li>
18+
* </ol>
19+
* </p>
20+
*
21+
* <p>
22+
* For more information, see <a href="https://en.wikipedia.org/wiki/Graph_coloring">Graph Coloring</a>.
23+
* </p>
1224
*/
13-
1425
public final class WelshPowell {
15-
private static final int BLANK_COLOR = -1; // Representing uncolored state
26+
private static final int BLANK_COLOR = -1; // Constant representing an uncolored state
1627

1728
private WelshPowell() {
1829
}
1930

31+
/**
32+
* Represents a graph using an adjacency list.
33+
*/
2034
static final class Graph {
21-
private HashSet<Integer>[] adjacencyLists;
22-
35+
private final HashSet<Integer>[] adjacencyLists;
36+
37+
/**
38+
* Initializes a graph with a specified number of vertices.
39+
*
40+
* @param vertices the number of vertices in the graph
41+
* @throws IllegalArgumentException if the number of vertices is negative
42+
*/
2343
private Graph(int vertices) {
2444
if (vertices < 0) {
2545
throw new IllegalArgumentException("Number of vertices cannot be negative");
@@ -29,6 +49,13 @@ private Graph(int vertices) {
2949
Arrays.setAll(adjacencyLists, i -> new HashSet<>());
3050
}
3151

52+
/**
53+
* Adds an edge between two vertices in the graph.
54+
*
55+
* @param nodeA one end of the edge
56+
* @param nodeB the other end of the edge
57+
* @throws IllegalArgumentException if the vertices are out of bounds or if a self-loop is attempted
58+
*/
3259
private void addEdge(int nodeA, int nodeB) {
3360
validateVertex(nodeA);
3461
validateVertex(nodeB);
@@ -39,21 +66,46 @@ private void addEdge(int nodeA, int nodeB) {
3966
adjacencyLists[nodeB].add(nodeA);
4067
}
4168

69+
/**
70+
* Validates that the vertex index is within the bounds of the graph.
71+
*
72+
* @param vertex the index of the vertex to validate
73+
* @throws IllegalArgumentException if the vertex is out of bounds
74+
*/
4275
private void validateVertex(int vertex) {
4376
if (vertex < 0 || vertex >= getNumVertices()) {
4477
throw new IllegalArgumentException("Vertex " + vertex + " is out of bounds");
4578
}
4679
}
4780

81+
/**
82+
* Returns the adjacency list for a specific vertex.
83+
*
84+
* @param vertex the index of the vertex
85+
* @return the set of adjacent vertices
86+
*/
4887
HashSet<Integer> getAdjacencyList(int vertex) {
4988
return adjacencyLists[vertex];
5089
}
5190

91+
/**
92+
* Returns the number of vertices in the graph.
93+
*
94+
* @return the number of vertices
95+
*/
5296
int getNumVertices() {
5397
return adjacencyLists.length;
5498
}
5599
}
56100

101+
/**
102+
* Creates a graph with the specified number of vertices and edges.
103+
*
104+
* @param numberOfVertices the total number of vertices
105+
* @param listOfEdges a 2D array representing edges where each inner array contains two vertex indices
106+
* @return a Graph object representing the created graph
107+
* @throws IllegalArgumentException if the edge array is invalid or vertices are out of bounds
108+
*/
57109
public static Graph makeGraph(int numberOfVertices, int[][] listOfEdges) {
58110
Graph graph = new Graph(numberOfVertices);
59111
for (int[] edge : listOfEdges) {
@@ -65,6 +117,12 @@ public static Graph makeGraph(int numberOfVertices, int[][] listOfEdges) {
65117
return graph;
66118
}
67119

120+
/**
121+
* Finds the coloring of the given graph using the Welsh-Powell algorithm.
122+
*
123+
* @param graph the input graph to color
124+
* @return an array of integers where each index represents a vertex and the value represents the color assigned
125+
*/
68126
public static int[] findColoring(Graph graph) {
69127
int[] colors = initializeColors(graph.getNumVertices());
70128
Integer[] sortedVertices = getSortedNodes(graph);
@@ -83,30 +141,70 @@ public static int[] findColoring(Graph graph) {
83141
return colors;
84142
}
85143

144+
/**
145+
* Helper method to check if a color is unassigned
146+
*
147+
* @param color the color to check
148+
* @return {@code true} if the color is unassigned, {@code false} otherwise
149+
*/
86150
private static boolean isBlank(int color) {
87151
return color == BLANK_COLOR;
88152
}
89153

154+
/**
155+
* Checks if a vertex has adjacent colored vertices
156+
*
157+
* @param graph the input graph
158+
* @param vertex the vertex to check
159+
* @param colors the array of colors assigned to the vertices
160+
* @return {@code true} if the vertex has adjacent colored vertices, {@code false} otherwise
161+
*/
90162
private static boolean isAdjacentToColored(Graph graph, int vertex, int[] colors) {
91163
return graph.getAdjacencyList(vertex).stream().anyMatch(otherVertex -> !isBlank(colors[otherVertex]));
92164
}
93165

166+
/**
167+
* Initializes the colors array with blank color
168+
*
169+
* @param numberOfVertices the number of vertices in the graph
170+
* @return an array of integers representing the colors assigned to the vertices
171+
*/
94172
private static int[] initializeColors(int numberOfVertices) {
95173
int[] colors = new int[numberOfVertices];
96174
Arrays.fill(colors, BLANK_COLOR);
97175
return colors;
98176
}
99177

178+
/**
179+
* Sorts the vertices by their degree in descending order
180+
*
181+
* @param graph the input graph
182+
* @return an array of integers representing the vertices sorted by degree
183+
*/
100184
private static Integer[] getSortedNodes(final Graph graph) {
101185
return IntStream.range(0, graph.getNumVertices()).boxed().sorted(Comparator.comparingInt(v -> - graph.getAdjacencyList(v).size())).toArray(Integer[] ::new);
102186
}
103187

188+
/**
189+
* Computes the colors already used by the adjacent vertices
190+
*
191+
* @param graph the input graph
192+
* @param vertex the vertex to check
193+
* @param colors the array of colors assigned to the vertices
194+
* @return an array of booleans representing the colors used by the adjacent vertices
195+
*/
104196
private static boolean[] computeUsedColors(final Graph graph, final int vertex, final int[] colors) {
105197
boolean[] usedColors = new boolean[graph.getNumVertices()];
106198
graph.getAdjacencyList(vertex).stream().map(neighbor -> colors[neighbor]).filter(color -> !isBlank(color)).forEach(color -> usedColors[color] = true);
107199
return usedColors;
108200
}
109201

202+
/**
203+
* Finds the first unused color
204+
*
205+
* @param usedColors the array of colors used by the adjacent vertices
206+
* @return the first unused color
207+
*/
110208
private static int firstUnusedColor(boolean[] usedColors) {
111209
return IntStream.range(0, usedColors.length).filter(color -> !usedColors[color]).findFirst().getAsInt();
112210
}

src/main/java/com/thealgorithms/datastructures/hashmap/hashing/GenericHashMapUsingArrayList.java

Lines changed: 85 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,34 @@
33
import java.util.ArrayList;
44
import java.util.LinkedList;
55

6+
/**
7+
* A generic implementation of a hash map using an array list of linked lists for collision resolution.
8+
* This class allows storage of key-value pairs with average-case constant time complexity for insertion,
9+
* deletion, and retrieval operations.
10+
*
11+
* <p>
12+
* The hash map uses separate chaining to handle collisions. Each bucket in the hash map is represented
13+
* by a linked list that holds nodes containing key-value pairs. When multiple keys hash to the same index,
14+
* they are stored in the same linked list.
15+
* </p>
16+
*
17+
* <p>
18+
* The hash map automatically resizes itself when the load factor exceeds 0.5. The load factor is defined
19+
* as the ratio of the number of entries to the number of buckets. When resizing occurs, all existing entries
20+
* are rehashed and inserted into the new buckets.
21+
* </p>
22+
*
23+
* @param <K> the type of keys maintained by this hash map
24+
* @param <V> the type of mapped values
25+
*/
626
public class GenericHashMapUsingArrayList<K, V> {
727

8-
ArrayList<LinkedList<Node>> buckets;
9-
private float lf = 0.5f;
10-
private int size;
28+
private ArrayList<LinkedList<Node>> buckets; // Array list of buckets (linked lists)
29+
private int size; // Number of key-value pairs in the hash map
1130

31+
/**
32+
* Constructs a new empty hash map with an initial capacity of 10 buckets.
33+
*/
1234
public GenericHashMapUsingArrayList() {
1335
buckets = new ArrayList<>();
1436
for (int i = 0; i < 10; i++) {
@@ -17,6 +39,13 @@ public GenericHashMapUsingArrayList() {
1739
size = 0;
1840
}
1941

42+
/**
43+
* Associates the specified value with the specified key in this map.
44+
* If the map previously contained a mapping for the key, the old value is replaced.
45+
*
46+
* @param key the key with which the specified value is to be associated
47+
* @param value the value to be associated with the specified key
48+
*/
2049
public void put(K key, V value) {
2150
int hash = Math.abs(key.hashCode() % buckets.size());
2251
LinkedList<Node> nodes = buckets.get(hash);
@@ -31,25 +60,36 @@ public void put(K key, V value) {
3160
nodes.add(new Node(key, value));
3261
size++;
3362

34-
if ((float) size / buckets.size() > lf) {
63+
// Load factor threshold for resizing
64+
float loadFactorThreshold = 0.5f;
65+
if ((float) size / buckets.size() > loadFactorThreshold) {
3566
reHash();
3667
}
3768
}
3869

70+
/**
71+
* Resizes the hash map by doubling the number of buckets and rehashing existing entries.
72+
*/
3973
private void reHash() {
40-
ArrayList<LinkedList<Node>> old = buckets;
74+
ArrayList<LinkedList<Node>> oldBuckets = buckets;
4175
buckets = new ArrayList<>();
4276
size = 0;
43-
for (int i = 0; i < old.size() * 2; i++) {
77+
for (int i = 0; i < oldBuckets.size() * 2; i++) {
4478
buckets.add(new LinkedList<>());
4579
}
46-
for (LinkedList<Node> nodes : buckets) {
80+
for (LinkedList<Node> nodes : oldBuckets) {
4781
for (Node node : nodes) {
4882
put(node.key, node.val);
4983
}
5084
}
5185
}
5286

87+
/**
88+
* Returns the value to which the specified key is mapped, or null if this map contains no mapping for the key.
89+
*
90+
* @param key the key whose associated value is to be returned
91+
* @return the value associated with the specified key, or null if no mapping exists
92+
*/
5393
public V get(K key) {
5494
int hash = Math.abs(key.hashCode() % buckets.size());
5595
LinkedList<Node> nodes = buckets.get(hash);
@@ -61,6 +101,11 @@ public V get(K key) {
61101
return null;
62102
}
63103

104+
/**
105+
* Removes the mapping for the specified key from this map if present.
106+
*
107+
* @param key the key whose mapping is to be removed from the map
108+
*/
64109
public void remove(K key) {
65110
int hash = Math.abs(key.hashCode() % buckets.size());
66111
LinkedList<Node> nodes = buckets.get(hash);
@@ -72,18 +117,36 @@ public void remove(K key) {
72117
break;
73118
}
74119
}
75-
nodes.remove(target);
76-
size--;
120+
if (target != null) {
121+
nodes.remove(target);
122+
size--;
123+
}
77124
}
78125

126+
/**
127+
* Returns true if this map contains a mapping for the specified key.
128+
*
129+
* @param key the key whose presence in this map is to be tested
130+
* @return true if this map contains a mapping for the specified key
131+
*/
79132
public boolean containsKey(K key) {
80133
return get(key) != null;
81134
}
82135

136+
/**
137+
* Returns the number of key-value pairs in this map.
138+
*
139+
* @return the number of key-value pairs
140+
*/
83141
public int size() {
84142
return this.size;
85143
}
86144

145+
/**
146+
* Returns a string representation of the map, containing all key-value pairs.
147+
*
148+
* @return a string representation of the map
149+
*/
87150
@Override
88151
public String toString() {
89152
StringBuilder builder = new StringBuilder();
@@ -96,15 +159,27 @@ public String toString() {
96159
builder.append(", ");
97160
}
98161
}
162+
// Remove trailing comma and space if there are any elements
163+
if (builder.length() > 1) {
164+
builder.setLength(builder.length() - 2);
165+
}
99166
builder.append("}");
100167
return builder.toString();
101168
}
102169

170+
/**
171+
* A private inner class representing a key-value pair (node) in the hash map.
172+
*/
103173
private class Node {
104-
105174
K key;
106175
V val;
107176

177+
/**
178+
* Constructs a new Node with the specified key and value.
179+
*
180+
* @param key the key of the key-value pair
181+
* @param val the value of the key-value pair
182+
*/
108183
Node(K key, V val) {
109184
this.key = key;
110185
this.val = val;

src/main/java/com/thealgorithms/datastructures/heaps/Heap.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,5 +40,5 @@ public interface Heap {
4040
* @param elementIndex int containing the position in the heap of the
4141
* element to be deleted.
4242
*/
43-
void deleteElement(int elementIndex);
43+
void deleteElement(int elementIndex) throws EmptyHeapException;
4444
}

src/main/java/com/thealgorithms/datastructures/heaps/HeapElement.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,4 +167,8 @@ public int hashCode() {
167167
result += (additionalInfo != null) ? additionalInfo.hashCode() : 0;
168168
return result;
169169
}
170+
171+
public String getValue() {
172+
return additionalInfo.toString();
173+
}
170174
}

0 commit comments

Comments
 (0)