diff --git a/README.md b/README.md
index b8289c953..06ce5059e 100644
--- a/README.md
+++ b/README.md
@@ -5,7 +5,8 @@ This public repository
contains the Java source code
for the algorithms and clients in the textbook
Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
-This is the official version—it is actively maintained and updated by the authors.
+The official version at https://github.com/kevin-wayne/algs4
+is actively maintained and updated by the authors.
The programs are organized in the package edu.princeton.cs.algs4
.
If you need only the class files (and not the source code), you can use
algs4.jar instead.
@@ -40,7 +41,7 @@ However, please do not store solutions to programming assignments in public repo
## Copyright
-Copyright © 2000–2017 by Robert Sedgewick and Kevin Wayne.
+Copyright © 2000–2023 by Robert Sedgewick and Kevin Wayne.
## License
@@ -61,6 +62,9 @@ Some of the code in this repository has been translated to other languages:
- * For additional documentation, - * see Section 1.2 of - * Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne. + * For additional documentation, + * see Section 1.2 of + * Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne. * * @author Robert Sedgewick * @author Kevin Wayne @@ -52,7 +52,7 @@ public void addDataValue(double x) { n++; double delta = x - mu; mu += delta / n; - sum += (double) (n - 1) / n * delta * delta; + sum += ((double) (n - 1) / n) * delta * delta; } /** @@ -121,7 +121,7 @@ public static void main(String[] args) { } /****************************************************************************** - * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne. + * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne. * * This file is part of algs4.jar, which accompanies the textbook * diff --git a/src/main/java/edu/princeton/cs/algs4/AcyclicLP.java b/src/main/java/edu/princeton/cs/algs4/AcyclicLP.java index 479aac325..a67761834 100644 --- a/src/main/java/edu/princeton/cs/algs4/AcyclicLP.java +++ b/src/main/java/edu/princeton/cs/algs4/AcyclicLP.java @@ -3,20 +3,20 @@ * Execution: java AcyclicP V E * Dependencies: EdgeWeightedDigraph.java DirectedEdge.java Topological.java * Data files: https://algs4.cs.princeton.edu/44sp/tinyEWDAG.txt - * - * Computes longeset paths in an edge-weighted acyclic digraph. + * + * Computes longest paths in an edge-weighted acyclic digraph. * * Remark: should probably check that graph is a DAG before running * * % java AcyclicLP tinyEWDAG.txt 5 - * 5 to 0 (2.44) 5->1 0.32 1->3 0.29 3->6 0.52 6->4 0.93 4->0 0.38 - * 5 to 1 (0.32) 5->1 0.32 - * 5 to 2 (2.77) 5->1 0.32 1->3 0.29 3->6 0.52 6->4 0.93 4->7 0.37 7->2 0.34 - * 5 to 3 (0.61) 5->1 0.32 1->3 0.29 - * 5 to 4 (2.06) 5->1 0.32 1->3 0.29 3->6 0.52 6->4 0.93 - * 5 to 5 (0.00) - * 5 to 6 (1.13) 5->1 0.32 1->3 0.29 3->6 0.52 - * 5 to 7 (2.43) 5->1 0.32 1->3 0.29 3->6 0.52 6->4 0.93 4->7 0.37 + * 5 to 0 (2.44) 5->1 0.32 1->3 0.29 3->6 0.52 6->4 0.93 4->0 0.38 + * 5 to 1 (0.32) 5->1 0.32 + * 5 to 2 (2.77) 5->1 0.32 1->3 0.29 3->6 0.52 6->4 0.93 4->7 0.37 7->2 0.34 + * 5 to 3 (0.61) 5->1 0.32 1->3 0.29 + * 5 to 4 (2.06) 5->1 0.32 1->3 0.29 3->6 0.52 6->4 0.93 + * 5 to 5 (0.00) + * 5 to 6 (1.13) 5->1 0.32 1->3 0.29 3->6 0.52 + * 5 to 7 (2.43) 5->1 0.32 1->3 0.29 3->6 0.52 6->4 0.93 4->7 0.37 * ******************************************************************************/ @@ -28,15 +28,24 @@ * acyclic graphs (DAGs). The edge weights can be positive, negative, or zero. *
* This implementation uses a topological-sort based algorithm. - * The constructor takes time proportional to V + E, - * where V is the number of vertices and E is the number of edges. - * Each call to {@code distTo(int)} and {@code hasPathTo(int)} takes constant time; - * each call to {@code pathTo(int)} takes time proportional to the number of - * edges in the shortest path returned. + * The constructor takes Θ(V + E) time in the + * worst case, where V is the number of vertices and + * E is the number of edges. + * Each instance method takes Θ(1) time. + * It uses Θ(V) extra space (not including the + * edge-weighted digraph). + *
+ * This correctly computes longest paths if all arithmetic performed is + * without floating-point rounding error or arithmetic overflow. + * This is the case if all edge weights are integers and if none of the + * intermediate results exceeds 252. Since all intermediate + * results are sums of edge weights, they are bounded by V C, + * where V is the number of vertices and C is the maximum + * absolute value of any edge weight. *
- * For additional documentation, - * see Section 4.4 of - * Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne. + * For additional documentation, + * see Section 4.4 of + * Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne. * * @author Robert Sedgewick * @author Kevin Wayne @@ -79,7 +88,7 @@ private void relax(DirectedEdge e) { if (distTo[w] < distTo[v] + e.weight()) { distTo[w] = distTo[v] + e.weight(); edgeTo[w] = e; - } + } } /** @@ -158,7 +167,7 @@ public static void main(String[] args) { } /****************************************************************************** - * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne. + * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne. * * This file is part of algs4.jar, which accompanies the textbook * diff --git a/src/main/java/edu/princeton/cs/algs4/AcyclicSP.java b/src/main/java/edu/princeton/cs/algs4/AcyclicSP.java index 745e5343e..f90e9155f 100644 --- a/src/main/java/edu/princeton/cs/algs4/AcyclicSP.java +++ b/src/main/java/edu/princeton/cs/algs4/AcyclicSP.java @@ -7,14 +7,14 @@ * Computes shortest paths in an edge-weighted acyclic digraph. * * % java AcyclicSP tinyEWDAG.txt 5 - * 5 to 0 (0.73) 5->4 0.35 4->0 0.38 - * 5 to 1 (0.32) 5->1 0.32 - * 5 to 2 (0.62) 5->7 0.28 7->2 0.34 - * 5 to 3 (0.61) 5->1 0.32 1->3 0.29 - * 5 to 4 (0.35) 5->4 0.35 - * 5 to 5 (0.00) - * 5 to 6 (1.13) 5->1 0.32 1->3 0.29 3->6 0.52 - * 5 to 7 (0.28) 5->7 0.28 + * 5 to 0 (0.73) 5->4 0.35 4->0 0.38 + * 5 to 1 (0.32) 5->1 0.32 + * 5 to 2 (0.62) 5->7 0.28 7->2 0.34 + * 5 to 3 (0.61) 5->1 0.32 1->3 0.29 + * 5 to 4 (0.35) 5->4 0.35 + * 5 to 5 (0.00) + * 5 to 6 (1.13) 5->1 0.32 1->3 0.29 3->6 0.52 + * 5 to 7 (0.28) 5->7 0.28 * ******************************************************************************/ @@ -26,15 +26,24 @@ * graphs (DAGs). The edge weights can be positive, negative, or zero. *
* This implementation uses a topological-sort based algorithm. - * The constructor takes time proportional to V + E, - * where V is the number of vertices and E is the number of edges. - * Each call to {@code distTo(int)} and {@code hasPathTo(int)} takes constant time; - * each call to {@code pathTo(int)} takes time proportional to the number of - * edges in the shortest path returned. + * The constructor takes Θ(V + E) time in the + * worst case, where V is the number of vertices and + * E is the number of edges. + * Each instance method takes Θ(1) time. + * It uses Θ(V) extra space (not including the + * edge-weighted digraph). *
- * For additional documentation, - * see Section 4.4 of - * Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne. + * This correctly computes shortest paths if all arithmetic performed is + * without floating-point rounding error or arithmetic overflow. + * This is the case if all edge weights are integers and if none of the + * intermediate results exceeds 252. Since all intermediate + * results are sums of edge weights, they are bounded by V C, + * where V is the number of vertices and C is the maximum + * absolute value of any edge weight. + *
+ * For additional documentation, + * see Section 4.4 of + * Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne. * * @author Robert Sedgewick * @author Kevin Wayne @@ -78,7 +87,7 @@ private void relax(DirectedEdge e) { if (distTo[w] > distTo[v] + e.weight()) { distTo[w] = distTo[v] + e.weight(); edgeTo[w] = e; - } + } } /** @@ -157,7 +166,7 @@ public static void main(String[] args) { } /****************************************************************************** - * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne. + * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne. * * This file is part of algs4.jar, which accompanies the textbook * diff --git a/src/main/java/edu/princeton/cs/algs4/AdjMatrixEdgeWeightedDigraph.java b/src/main/java/edu/princeton/cs/algs4/AdjMatrixEdgeWeightedDigraph.java index 8cbd6929f..797a2c4f4 100644 --- a/src/main/java/edu/princeton/cs/algs4/AdjMatrixEdgeWeightedDigraph.java +++ b/src/main/java/edu/princeton/cs/algs4/AdjMatrixEdgeWeightedDigraph.java @@ -5,7 +5,7 @@ * * An edge-weighted digraph, implemented using an adjacency matrix. * Parallel edges are disallowed; self-loops are allowed. - * + * ******************************************************************************/ package edu.princeton.cs.algs4; @@ -14,7 +14,7 @@ import java.util.NoSuchElementException; /** - * The {@code AdjMatrixEdgeWeightedDigraph} class represents a edge-weighted + * The {@code AdjMatrixEdgeWeightedDigraph} class represents an edge-weighted * digraph of vertices named 0 through V - 1, where each * directed edge is of type {@link DirectedEdge} and has a real-valued weight. * It supports the following two primary operations: add a directed edge @@ -41,14 +41,14 @@ public class AdjMatrixEdgeWeightedDigraph { private final int V; private int E; private DirectedEdge[][] adj; - + /** * Initializes an empty edge-weighted digraph with {@code V} vertices and 0 edges. * @param V the number of vertices * @throws IllegalArgumentException if {@code V < 0} */ public AdjMatrixEdgeWeightedDigraph(int V) { - if (V < 0) throw new IllegalArgumentException("number of vertices must be nonnegative"); + if (V < 0) throw new IllegalArgumentException("number of vertices must be non-negative"); this.V = V; this.E = 0; this.adj = new DirectedEdge[V][V]; @@ -63,14 +63,14 @@ public AdjMatrixEdgeWeightedDigraph(int V) { */ public AdjMatrixEdgeWeightedDigraph(int V, int E) { this(V); - if (E < 0) throw new IllegalArgumentException("number of edges must be nonnegative"); + if (E < 0) throw new IllegalArgumentException("number of edges must be non-negative"); if (E > V*V) throw new IllegalArgumentException("too many edges"); // can be inefficient while (this.E != E) { - int v = StdRandom.uniform(V); - int w = StdRandom.uniform(V); - double weight = Math.round(100 * StdRandom.uniform()) / 100.0; + int v = StdRandom.uniformInt(V); + int w = StdRandom.uniformInt(V); + double weight = 0.01 * StdRandom.uniformInt(0, 100); addEdge(new DirectedEdge(v, w, weight)); } } @@ -192,7 +192,7 @@ public static void main(String[] args) { } /****************************************************************************** - * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne. + * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne. * * This file is part of algs4.jar, which accompanies the textbook * diff --git a/src/main/java/edu/princeton/cs/algs4/WhiteFilter.java b/src/main/java/edu/princeton/cs/algs4/AllowFilter.java similarity index 71% rename from src/main/java/edu/princeton/cs/algs4/WhiteFilter.java rename to src/main/java/edu/princeton/cs/algs4/AllowFilter.java index 18677bf96..4f269496e 100644 --- a/src/main/java/edu/princeton/cs/algs4/WhiteFilter.java +++ b/src/main/java/edu/princeton/cs/algs4/AllowFilter.java @@ -1,25 +1,25 @@ /****************************************************************************** - * Compilation: javac WhiteFilter.java - * Execution: java WhiteFilter whitelist.txt < input.txt + * Compilation: javac AllowFilter.java + * Execution: java AllowFilter allowlist.txt < input.txt * Dependencies: SET In.java StdIn.java StdOut.java * Data files: https://algs4.cs.princeton.edu/35applications/tinyTale.txt - * https://algs4.cs.princeton.edu/35applications/list.txt - * - * Read in a whitelist of words from a file. Then read in a list of - * words from standard input and print out all those words that + * https://algs4.cs.princeton.edu/35applications/allowlist.txt + * + * Reads an allowlist of words from a file. Then readsa list of + * words from standard input and prints all those words that * are in the first file. - * - * % more tinyTale.txt - * it was the best of times it was the worst of times - * it was the age of wisdom it was the age of foolishness - * it was the epoch of belief it was the epoch of incredulity - * it was the season of light it was the season of darkness + * + * % more tinyTale.txt + * it was the best of times it was the worst of times + * it was the age of wisdom it was the age of foolishness + * it was the epoch of belief it was the epoch of incredulity + * it was the season of light it was the season of darkness * it was the spring of hope it was the winter of despair * - * % more list.txt - * was it the of - * - * % java WhiteFilter list.txt < tinyTale.txt + * % more list.txt + * was it the of + * + * % java AllowFilter list.txt < tinyTale.txt * it was the of it was the of * it was the of it was the of * it was the of it was the of @@ -31,21 +31,22 @@ package edu.princeton.cs.algs4; /** - * The {@code WhiteFilter} class provides a client for reading in a whitelist + * The {@code AllowFilter} class provides a client for reading in an allowlist * of words from a file; then, reading in a sequence of words from standard input, * printing out each word that appears in the file. - * It is useful as a test client for various symbol table implementations. + * It is useful as a test client for various symbol-table implementations. *
- * For additional documentation, see Section 3.5 of
+ * For additional documentation,
+ * see Section 3.5 of
* Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
-public class WhiteFilter {
+public class AllowFilter {
// Do not instantiate.
- private WhiteFilter() { }
+ private AllowFilter() { }
public static void main(String[] args) {
SET
- * For additional documentation, see Section 1.2 of
+ * For additional documentation,
+ * see Section 1.2 of
* Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
-public class Whitelist {
+public class Allowlist {
// Do not instantiate.
- private Whitelist() { }
+ private Allowlist() { }
/**
- * Reads in a sequence of integers from the whitelist file, specified as
+ * Reads in a sequence of integers from the allowlist file, specified as
* a command-line argument. Reads in integers from standard input and
* prints to standard output those integers that are not in the file.
*
@@ -58,7 +59,7 @@ public static void main(String[] args) {
int[] white = in.readAllInts();
StaticSETofInts set = new StaticSETofInts(white);
- // Read key, print if not in whitelist.
+ // Read key, print if not in allowlist.
while (!StdIn.isEmpty()) {
int key = StdIn.readInt();
if (!set.contains(key))
@@ -68,7 +69,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/Alphabet.java b/src/main/java/edu/princeton/cs/algs4/Alphabet.java
index c38ca69da..0bcba1662 100644
--- a/src/main/java/edu/princeton/cs/algs4/Alphabet.java
+++ b/src/main/java/edu/princeton/cs/algs4/Alphabet.java
@@ -256,7 +256,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/AmericanFlag.java b/src/main/java/edu/princeton/cs/algs4/AmericanFlag.java
index 61111e8bd..c83b70dae 100644
--- a/src/main/java/edu/princeton/cs/algs4/AmericanFlag.java
+++ b/src/main/java/edu/princeton/cs/algs4/AmericanFlag.java
@@ -1,14 +1,14 @@
/******************************************************************************
* Compilation: javac AmericanFlag.java
* Execution: java AmericanFlag < input.txt
- * java AmericanFlag int < input-non-negative-ints.txt
+ * java AmericanFlag int < input-non-negative-ints.txt
* Dependencies: StdIn.java StdOut.java Stack.java
* Data files: https://algs4.cs.princeton.edu/51radix/words3.txt
* https://algs4.cs.princeton.edu/51radix/shells.txt
*
* Sort an array of strings or integers in-place using American flag sort.
*
- * % java AmericanFlag < shells.txt
+ * % java AmericanFlag < shells.txt
* are
* by
* sea
@@ -30,7 +30,7 @@
/**
* The {@code AmericanFlag} class provides static methods for sorting an
- * array of extended ASCII strings or integers in-place using
+ * array of extended ASCII strings or integers in-place using
* American flag sort. This is a non-recursive implementation.
*
* For additional documentation,
@@ -38,7 +38,7 @@
* Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne
* and
* Engineering Radix Sort by McIlroy and Bostic.
- * For a version that uses only one auxilary array, see {@link AmericanFlagX}.
+ * For a version that uses only one auxiliary array, see {@link AmericanFlagX}.
*
* @author Robert Sedgewick
* @author Kevin Wayne
@@ -47,12 +47,12 @@
public class AmericanFlag {
private static final int BITS_PER_BYTE = 8;
- private static final int BITS_PER_INT = 32; // each Java int is 32 bits
+ private static final int BITS_PER_INT = 32; // each Java int is 32 bits
private static final int R = 256; // extend ASCII alphabet size
private static final int CUTOFF = 15; // cutoff to insertion sort
// do not instantiate
- private AmericanFlag() { }
+ private AmericanFlag() { }
// return dth character of s, -1 if d = length of string
private static int charAt(String s, int d) {
@@ -82,12 +82,12 @@ public static void sort(String[] a, int lo, int hi) {
st.push(lo);
st.push(hi);
st.push(d);
-
+
while (!st.isEmpty()) {
d = st.pop();
hi = st.pop();
lo = st.pop();
-
+
if (hi <= lo + CUTOFF) {
insertion(a, lo, hi, d);
continue;
@@ -103,12 +103,12 @@ public static void sort(String[] a, int lo, int hi) {
first[0] = lo;
for (int c = 0; c <= R; c++) {
first[c+1] += first[c];
-
- if (c > 0 && first[c+1]-1 > first[c]) {
+
+ if (c > 0 && first[c+1]-1 > first[c]) {
// add subproblem for character c (excludes sentinel c == 0)
st.push(first[c]);
st.push(first[c+1] - 1);
- st.push(d+1);
+ st.push(d+1);
}
}
@@ -125,7 +125,7 @@ public static void sort(String[] a, int lo, int hi) {
}
next[c]++;
}
-
+
// clear first[] and next[] arrays
for (int c = 0; c < R+2; c++) {
first[c] = 0;
@@ -133,7 +133,7 @@ public static void sort(String[] a, int lo, int hi) {
}
}
}
-
+
// insertion sort a[lo..hi], starting at dth character
private static void insertion(String[] a, int lo, int hi, int d) {
for (int i = lo; i <= hi; i++)
@@ -160,7 +160,7 @@ private static boolean less(String v, String w, int d) {
/**
* Rearranges the array of 32-bit integers in ascending order.
- * Currently assumes that the integers are nonnegative.
+ * Currently, assumes that the integers are nonnegative.
*
* @param a the array to be sorted
*/
@@ -180,17 +180,17 @@ private static void sort(int[] a, int lo, int hi) {
st.push(lo);
st.push(hi);
st.push(d);
-
+
while (!st.isEmpty()) {
d = st.pop();
hi = st.pop();
lo = st.pop();
-
+
if (hi <= lo + CUTOFF) {
insertion(a, lo, hi, d);
continue;
}
-
+
// compute frequency counts (need R = 256)
int shift = BITS_PER_INT - BITS_PER_BYTE*d - BITS_PER_BYTE;
for (int i = lo; i <= hi; i++) {
@@ -202,12 +202,12 @@ private static void sort(int[] a, int lo, int hi) {
first[0] = lo;
for (int c = 0; c < R; c++) {
first[c+1] += first[c];
-
- if (d < 3 && first[c+1]-1 > first[c]) {
+
+ if (d < 3 && first[c+1]-1 > first[c]) {
// add subproblem for byte c
st.push(first[c]);
st.push(first[c+1] - 1);
- st.push(d+1);
+ st.push(d+1);
}
}
@@ -224,7 +224,7 @@ private static void sort(int[] a, int lo, int hi) {
}
next[c]++;
}
-
+
// clear first[] and next[] arrays
for (int c = 0; c < R+1; c++) {
first[c] = 0;
@@ -246,7 +246,7 @@ private static void exch(int[] a, int i, int j) {
a[i] = a[j];
a[j] = temp;
}
-
+
// is v less than w, starting at byte d
private static boolean less(int v, int w, int d) {
int mask = R - 1; // 0xFF;
@@ -259,7 +259,7 @@ private static boolean less(int v, int w, int d) {
}
return false;
}
-
+
/**
* Reads in a sequence of extended ASCII strings or non-negative ints from standard input;
* American flag sorts them;
@@ -289,7 +289,7 @@ public static void main(String[] args) {
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/AmericanFlagX.java b/src/main/java/edu/princeton/cs/algs4/AmericanFlagX.java
index 8228f4af8..2d2e6c688 100644
--- a/src/main/java/edu/princeton/cs/algs4/AmericanFlagX.java
+++ b/src/main/java/edu/princeton/cs/algs4/AmericanFlagX.java
@@ -7,7 +7,7 @@
*
* Sort an array of strings or integers in-place using American Flag sort.
*
- * % java AmericanFlagX < shells.txt
+ * % java AmericanFlagX < shells.txt
* are
* by
* sea
@@ -29,8 +29,8 @@
/**
* The {@code AmericanFlagX} class provides static methods for sorting an
- * array of extended ASCII strings or integers in-place using
- * American Flag sort. This implementation is non-recursive and uses only
+ * array of extended ASCII strings or integers in-place using
+ * American Flag sort. This implementation is non-recursive and uses only
* one auxiliary array.
*
* For additional documentation,
@@ -38,7 +38,7 @@
* Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne
* and
* Engineering Radix Sort by McIlroy and Bostic.
- * For a version that uses two auxilary arrays, see {@link AmericanFlag}.
+ * For a version that uses two auxiliary arrays, see {@link AmericanFlag}.
*
* @author Ivan Pesin
*/
@@ -48,7 +48,7 @@ public class AmericanFlagX {
private static final int CUTOFF = 15; // cutoff to insertion sort
// do not instantiate
- private AmericanFlagX() { }
+ private AmericanFlagX() { }
// return dth character of s, -1 if d = length of string
private static int charAt(String s, int d) {
@@ -77,7 +77,7 @@ public static void sort(String[] a, int lo, int hi) {
st.push(lo);
st.push(hi);
st.push(d);
-
+
while (!st.isEmpty()) {
d = st.pop();
hi = st.pop();
@@ -94,22 +94,22 @@ public static void sort(String[] a, int lo, int hi) {
count[c]++;
}
- // accumulate counts relative to a[0], so that
+ // accumulate counts relative to a[0], so that
// count[c] is the number of keys <= c
count[0] += lo;
for (int c = 0; c < R; c++) {
count[c+1] += count[c];
-
- if (c > 0 && count[c+1]-1 > count[c]) {
+
+ if (c > 0 && count[c+1]-1 > count[c]) {
// add subproblem for character c (excludes sentinel c == 0)
st.push(count[c]);
st.push(count[c+1]-1);
- st.push(d+1);
+ st.push(d+1);
}
}
// permute data in place
- // for details and proof see Knuth Theorem 5.1.2B and ch 5.2 excercise 13.
+ // for details and proof see Knuth Theorem 5.1.2B and ch 5.2 exercise 13.
for (int r = hi; r >= lo; r--) {
// locate element that must be shifted right of r
@@ -122,20 +122,20 @@ public static void sort(String[] a, int lo, int hi) {
// if r < lo the subarray is sorted.
if (r < lo) break;
-
+
// permute a[r] until correct element is in place
while (--count[c] != r) {
exch(a, r, count[c]);
c = charAt(a[r], d) + 1;
}
}
-
+
// clear count[] array
for (int c = 0; c < R+1; c++)
count[c] = 0;
}
}
-
+
// insertion sort a[lo..hi], starting at dth character
private static void insertion(String[] a, int lo, int hi, int d) {
for (int i = lo; i <= hi; i++)
@@ -159,7 +159,7 @@ private static boolean less(String v, String w, int d) {
}
return v.length() < w.length();
}
-
+
/**
* Reads in a sequence of extended ASCII strings or non-negative ints from standard input;
* American flag sorts them;
@@ -167,7 +167,7 @@ private static boolean less(String v, String w, int d) {
*
* @param args the command-line arguments
*/
- public static void main(String[] args) {
+ public static void main(String[] args) {
String[] a = StdIn.readAllStrings();
sort(a);
// print results
@@ -178,7 +178,7 @@ public static void main(String[] args) {
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/Arbitrage.java b/src/main/java/edu/princeton/cs/algs4/Arbitrage.java
index 2cf53e485..850184be1 100644
--- a/src/main/java/edu/princeton/cs/algs4/Arbitrage.java
+++ b/src/main/java/edu/princeton/cs/algs4/Arbitrage.java
@@ -35,6 +35,14 @@
* The running time is proportional to V3 in the
* worst case, where V is the number of currencies.
*
+ * This code is guaranteed to find an arbitrage opportunity in a
+ * currency exchange table (or report that no such arbitrage
+ * opportunity exists) under the assumption that all arithmetic
+ * performed is without floating-point rounding error or arithmetic
+ * overflow. Since the code computes the logarithms of the edge weights,
+ * floating-point rounding error will be present, and it may fail on
+ * some pathological inputs.
+ *
* For additional documentation,
* see Section 4.4 of
* Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
@@ -88,7 +96,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/AssignmentProblem.java b/src/main/java/edu/princeton/cs/algs4/AssignmentProblem.java
index 0cb0be67a..f1630c55d 100644
--- a/src/main/java/edu/princeton/cs/algs4/AssignmentProblem.java
+++ b/src/main/java/edu/princeton/cs/algs4/AssignmentProblem.java
@@ -24,6 +24,11 @@
* O(n^3 log n) to solve an n-by-n
* instance.
*
+ * This computes correct results if all arithmetic performed is
+ * without floating-point rounding error or arithmetic overflow.
+ * This is the case if all edge weights are integers and if none of the
+ * intermediate results exceeds 252.
+ *
* For additional documentation, see
* Section 6.5
* Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
@@ -32,7 +37,7 @@
* @author Kevin Wayne
*/
public class AssignmentProblem {
- private static final double FLOATING_POINT_EPSILON = 1E-14;
+ private static final double FLOATING_POINT_EPSILON = 1.0E-14;
private static final int UNMATCHED = -1;
private int n; // number of rows and columns
@@ -49,7 +54,7 @@ public class AssignmentProblem {
* @param weight the n-by-n matrix of weights
* @throws IllegalArgumentException unless all weights are nonnegative
* @throws IllegalArgumentException if {@code weight} is {@code null}
- */
+ */
public AssignmentProblem(double[][] weight) {
if (weight == null) throw new IllegalArgumentException("constructor argument is null");
@@ -85,7 +90,7 @@ public AssignmentProblem(double[][] weight) {
assert certifySolution();
}
- // find shortest augmenting path and upate
+ // find shortest augmenting path and update
private void augment() {
// build residual graph
@@ -126,7 +131,7 @@ private void augment() {
}
// reduced cost of i-j
- // (subtracting off minWeight reweights all weights to be non-negative)
+ // (subtracting off minWeight re-weights all weights to be non-negative)
private double reducedCost(int i, int j) {
double reducedCost = (weight[i][j] - minWeight) + px[i] - py[j];
@@ -281,7 +286,7 @@ public static void main(String[] args) {
double[][] weight = new double[n][n];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
- weight[i][j] = StdRandom.uniform(900) + 100; // 3 digits
+ weight[i][j] = StdRandom.uniformInt(900) + 100; // 3 digits
}
}
@@ -306,7 +311,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/Average.java b/src/main/java/edu/princeton/cs/algs4/Average.java
index 71c887a78..1c4706f65 100644
--- a/src/main/java/edu/princeton/cs/algs4/Average.java
+++ b/src/main/java/edu/princeton/cs/algs4/Average.java
@@ -2,7 +2,7 @@
* Compilation: javac Average.java
* Execution: java Average < data.txt
* Dependencies: StdIn.java StdOut.java
- *
+ *
* Reads in a sequence of real numbers, and computes their average.
*
* % java Average
@@ -28,7 +28,7 @@
* @author Robert Sedgewick
* @author Kevin Wayne
*/
-public class Average {
+public class Average {
// this class should not be instantiated
private Average() { }
@@ -39,7 +39,7 @@ private Average() { }
*
* @param args the command-line arguments
*/
- public static void main(String[] args) {
+ public static void main(String[] args) {
int count = 0; // number input values
double sum = 0.0; // sum of input values
@@ -59,7 +59,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/BST.java b/src/main/java/edu/princeton/cs/algs4/BST.java
index b80e927cf..1645d01d9 100644
--- a/src/main/java/edu/princeton/cs/algs4/BST.java
+++ b/src/main/java/edu/princeton/cs/algs4/BST.java
@@ -2,13 +2,13 @@
* Compilation: javac BST.java
* Execution: java BST
* Dependencies: StdIn.java StdOut.java Queue.java
- * Data files: https://algs4.cs.princeton.edu/32bst/tinyST.txt
+ * Data files: https://algs4.cs.princeton.edu/32bst/tinyST.txt
*
* A symbol table implemented with a binary search tree.
- *
+ *
* % more tinyST.txt
* S E A R C H E X A M P L E
- *
+ *
* % java BST < tinyST.txt
* A 8
* C 4
@@ -43,22 +43,26 @@
* value associated with a key to {@code null} is equivalent to deleting the key
* from the symbol table.
*
- * This implementation uses an (unbalanced) binary search tree. It requires that
+ * It requires that
* the key type implements the {@code Comparable} interface and calls the
* {@code compareTo()} and method to compare two keys. It does not call either
* {@code equals()} or {@code hashCode()}.
+ *
+ * This implementation uses an (unbalanced) binary search tree.
* The put, contains, remove, minimum,
* maximum, ceiling, floor, select, and
- * rank operations each take
- * linear time in the worst case, if the tree becomes unbalanced.
- * The size, and is-empty operations take constant time.
- * Construction takes constant time.
+ * rank operations each take Θ(n) time in the worst
+ * case, where n is the number of key-value pairs.
+ * The size and is-empty operations take Θ(1) time.
+ * The keys method takes Θ(n) time in the worst case.
+ * Construction takes Θ(1) time.
*
- * For additional documentation, see Section 3.2 of
- * Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
- * For other implementations, see {@link ST}, {@link BinarySearchST},
- * {@link SequentialSearchST}, {@link RedBlackBST},
+ * For alternative implementations of the symbol table API, see {@link ST},
+ * {@link BinarySearchST}, {@link SequentialSearchST}, {@link RedBlackBST},
* {@link SeparateChainingHashST}, and {@link LinearProbingHashST},
+ * For additional documentation, see
+ * Section 3.2 of
+ * Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
@@ -142,7 +146,7 @@ private Value get(Node x, Key key) {
}
/**
- * Inserts the specified key-value pair into the symbol table, overwriting the old
+ * Inserts the specified key-value pair into the symbol table, overwriting the old
* value with the new value if the symbol table already contains the specified key.
* Deletes the specified key (and its associated value) from this symbol table
* if the specified value is {@code null}.
@@ -209,8 +213,8 @@ private Node deleteMax(Node x) {
}
/**
- * Removes the specified key and its associated value from this symbol table
- * (if the key is in this symbol table).
+ * Removes the specified key and its associated value from this symbol table
+ * (if the key is in this symbol table).
*
* @param key the key
* @throws IllegalArgumentException if {@code key} is {@code null}
@@ -227,17 +231,17 @@ private Node delete(Node x, Key key) {
int cmp = key.compareTo(x.key);
if (cmp < 0) x.left = delete(x.left, key);
else if (cmp > 0) x.right = delete(x.right, key);
- else {
+ else {
if (x.right == null) return x.left;
if (x.left == null) return x.right;
Node t = x;
x = min(t.right);
x.right = deleteMin(t.right);
x.left = t.left;
- }
+ }
x.size = size(x.left) + size(x.right) + 1;
return x;
- }
+ }
/**
@@ -249,12 +253,12 @@ private Node delete(Node x, Key key) {
public Key min() {
if (isEmpty()) throw new NoSuchElementException("calls min() with empty symbol table");
return min(root).key;
- }
+ }
- private Node min(Node x) {
- if (x.left == null) return x;
- else return min(x.left);
- }
+ private Node min(Node x) {
+ if (x.left == null) return x;
+ else return min(x.left);
+ }
/**
* Returns the largest key in the symbol table.
@@ -265,12 +269,12 @@ private Node min(Node x) {
public Key max() {
if (isEmpty()) throw new NoSuchElementException("calls max() with empty symbol table");
return max(root).key;
- }
+ }
private Node max(Node x) {
- if (x.right == null) return x;
- else return max(x.right);
- }
+ if (x.right == null) return x;
+ else return max(x.right);
+ }
/**
* Returns the largest key in the symbol table less than or equal to {@code key}.
@@ -284,22 +288,25 @@ public Key floor(Key key) {
if (key == null) throw new IllegalArgumentException("argument to floor() is null");
if (isEmpty()) throw new NoSuchElementException("calls floor() with empty symbol table");
Node x = floor(root, key);
- if (x == null) return null;
+ if (x == null) throw new NoSuchElementException("argument to floor() is too small");
else return x.key;
- }
+ }
private Node floor(Node x, Key key) {
if (x == null) return null;
int cmp = key.compareTo(x.key);
if (cmp == 0) return x;
if (cmp < 0) return floor(x.left, key);
- Node t = floor(x.right, key);
+ Node t = floor(x.right, key);
if (t != null) return t;
- else return x;
- }
+ else return x;
+ }
public Key floor2(Key key) {
- return floor2(root, key, null);
+ Key x = floor2(root, key, null);
+ if (x == null) throw new NoSuchElementException("argument to floor() is too small");
+ else return x;
+
}
private Key floor2(Node x, Key key, Key best) {
@@ -308,7 +315,7 @@ private Key floor2(Node x, Key key, Key best) {
if (cmp < 0) return floor2(x.left, key, best);
else if (cmp > 0) return floor2(x.right, key, x.key);
else return x.key;
- }
+ }
/**
* Returns the smallest key in the symbol table greater than or equal to {@code key}.
@@ -322,7 +329,7 @@ public Key ceiling(Key key) {
if (key == null) throw new IllegalArgumentException("argument to ceiling() is null");
if (isEmpty()) throw new NoSuchElementException("calls ceiling() with empty symbol table");
Node x = ceiling(root, key);
- if (x == null) return null;
+ if (x == null) throw new NoSuchElementException("argument to ceiling() is too large");
else return x.key;
}
@@ -330,39 +337,41 @@ private Node ceiling(Node x, Key key) {
if (x == null) return null;
int cmp = key.compareTo(x.key);
if (cmp == 0) return x;
- if (cmp < 0) {
- Node t = ceiling(x.left, key);
+ if (cmp < 0) {
+ Node t = ceiling(x.left, key);
if (t != null) return t;
- else return x;
- }
- return ceiling(x.right, key);
- }
+ else return x;
+ }
+ return ceiling(x.right, key);
+ }
/**
- * Return the key in the symbol table whose rank is {@code k}.
- * This is the (k+1)st smallest key in the symbol table.
+ * Return the key in the symbol table of a given {@code rank}.
+ * This key has the property that there are {@code rank} keys in
+ * the symbol table that are smaller. In other words, this key is the
+ * ({@code rank}+1)st smallest key in the symbol table.
*
- * @param k the order statistic
- * @return the key in the symbol table of rank {@code k}
- * @throws IllegalArgumentException unless {@code k} is between 0 and
+ * @param rank the order statistic
+ * @return the key in the symbol table of given {@code rank}
+ * @throws IllegalArgumentException unless {@code rank} is between 0 and
* n–1
*/
- public Key select(int k) {
- if (k < 0 || k >= size()) {
- throw new IllegalArgumentException("argument to select() is invalid: " + k);
+ public Key select(int rank) {
+ if (rank < 0 || rank >= size()) {
+ throw new IllegalArgumentException("argument to select() is invalid: " + rank);
}
- Node x = select(root, k);
- return x.key;
+ return select(root, rank);
}
- // Return key of rank k.
- private Node select(Node x, int k) {
- if (x == null) return null;
- int t = size(x.left);
- if (t > k) return select(x.left, k);
- else if (t < k) return select(x.right, k-t-1);
- else return x;
- }
+ // Return key in BST rooted at x of given rank.
+ // Precondition: rank is in legal range.
+ private Key select(Node x, int rank) {
+ if (x == null) return null;
+ int leftSize = size(x.left);
+ if (leftSize > rank) return select(x.left, rank);
+ else if (leftSize < rank) return select(x.right, rank - leftSize - 1);
+ else return x.key;
+ }
/**
* Return the number of keys in the symbol table strictly less than {@code key}.
@@ -374,23 +383,24 @@ private Node select(Node x, int k) {
public int rank(Key key) {
if (key == null) throw new IllegalArgumentException("argument to rank() is null");
return rank(key, root);
- }
+ }
// Number of keys in the subtree less than key.
private int rank(Key key, Node x) {
- if (x == null) return 0;
- int cmp = key.compareTo(x.key);
- if (cmp < 0) return rank(key, x.left);
- else if (cmp > 0) return 1 + size(x.left) + rank(key, x.right);
- else return size(x.left);
- }
+ if (x == null) return 0;
+ int cmp = key.compareTo(x.key);
+ if (cmp < 0) return rank(key, x.left);
+ else if (cmp > 0) return 1 + size(x.left) + rank(key, x.right);
+ else return size(x.left);
+ }
/**
- * Returns all keys in the symbol table as an {@code Iterable}.
+ * Returns all keys in the symbol table in ascending order,
+ * as an {@code Iterable}.
* To iterate over all of the keys in the symbol table named {@code st},
* use the foreach notation: {@code for (Key key : st.keys())}.
*
- * @return all keys in the symbol table
+ * @return all keys in the symbol table in ascending order
*/
public Iterable
* This implementation uses a singly linked list with a static nested class Node.
@@ -50,7 +50,7 @@
* @author Robert Sedgewick
* @author Kevin Wayne
*
- * @param
- * This implementation uses the Bellman-Ford-Moore algorithm.
- * The constructor takes time proportional to V (V + E)
- * in the worst case, where V is the number of vertices and E
- * is the number of edges.
- * Each call to {@code distTo(int)} and {@code hasPathTo(int)},
- * {@code hasNegativeCycle} takes constant time;
- * each call to {@code pathTo(int)} and {@code negativeCycle()}
- * takes time proportional to length of the path returned.
+ * This implementation uses a queue-based implementation of
+ * the Bellman-Ford-Moore algorithm.
+ * The constructor takes Θ(E V) time
+ * in the worst case, where V is the number of vertices and
+ * E is the number of edges. In practice, it performs much better.
+ * Each instance method takes Θ(1) time.
+ * It uses Θ(V) extra space (not including the
+ * edge-weighted digraph).
*
- * For additional documentation,
- * see Section 4.4 of
- * Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
+ * This correctly computes shortest paths if all arithmetic performed is
+ * without floating-point rounding error or arithmetic overflow.
+ * This is the case if all edge weights are integers and if none of the
+ * intermediate results exceeds 252. Since all intermediate
+ * results are sums of edge weights, they are bounded by V C,
+ * where V is the number of vertices and C is the maximum
+ * absolute value of any edge weight.
+ *
+ * For additional documentation,
+ * see Section 4.4 of
+ * Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class BellmanFordSP {
+ // for floating-point precision issues
+ private static final double EPSILON = 1E-14;
+
private double[] distTo; // distTo[v] = distance of shortest s->v path
private DirectedEdge[] edgeTo; // edgeTo[v] = last edge on shortest s->v path
private boolean[] onQueue; // onQueue[v] = is v currently on the queue?
@@ -93,7 +106,7 @@ public BellmanFordSP(EdgeWeightedDigraph G, int s) {
private void relax(EdgeWeightedDigraph G, int v) {
for (DirectedEdge e : G.adj(v)) {
int w = e.to();
- if (distTo[w] > distTo[v] + e.weight()) {
+ if (distTo[w] > distTo[v] + e.weight() + EPSILON) {
distTo[w] = distTo[v] + e.weight();
edgeTo[w] = e;
if (!onQueue[w]) {
@@ -101,7 +114,7 @@ private void relax(EdgeWeightedDigraph G, int v) {
onQueue[w] = true;
}
}
- if (cost++ % G.V() == 0) {
+ if (++cost % G.V() == 0) {
findNegativeCycle();
if (hasNegativeCycle()) return; // found a negative cycle
}
@@ -120,7 +133,7 @@ public boolean hasNegativeCycle() {
/**
* Returns a negative cycle reachable from the source vertex {@code s}, or {@code null}
* if there is no such cycle.
- * @return a negative cycle reachable from the soruce vertex {@code s}
+ * @return a negative cycle reachable from the source vertex {@code s}
* as an iterable of edges, and {@code null} if there is no such cycle
*/
public Iterable
* For additional documentation,
- * see Section 5.5 of
+ * see Section 5.5 of
* Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
*
* See also {@link HexDump} and {@link PictureDump}.
@@ -74,7 +74,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/BinaryIn.java b/src/main/java/edu/princeton/cs/algs4/BinaryIn.java
index 21aa07b0a..b8eb4e13e 100644
--- a/src/main/java/edu/princeton/cs/algs4/BinaryIn.java
+++ b/src/main/java/edu/princeton/cs/algs4/BinaryIn.java
@@ -1,11 +1,11 @@
/******************************************************************************
* Compilation: javac BinaryIn.java
* Execution: java BinaryIn input output
- * Dependencies: none
- *
+ * Dependencies: none
+ *
* This library is for reading binary data from an input stream.
*
- * % java BinaryIn https://introcs.cs.princeton.edu/cover.jpg output.jpg
+ * % java BinaryIn https://introcs.cs.princeton.edu/java/cover.png output.png
*
******************************************************************************/
@@ -17,13 +17,17 @@
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
+
+import java.net.URI;
+import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLConnection;
+
import java.util.NoSuchElementException;
/**
- * Binary input. This class provides methods for reading
- * in bits from a binary input stream, either
+ * The
- * All primitive types are assumed to be represented using their
+ * All primitive types are assumed to be represented using their
* standard Java representations, in big-endian (most significant
* byte first) order.
*
@@ -80,7 +84,7 @@ public BinaryIn(Socket socket) {
fillBuffer();
}
catch (IOException ioe) {
- System.err.println("Could not open " + socket);
+ System.err.println("could not read socket: " + socket);
}
}
@@ -97,7 +101,7 @@ public BinaryIn(URL url) {
fillBuffer();
}
catch (IOException ioe) {
- System.err.println("Could not open " + url);
+ System.err.println("could not open URL: '" + url + "'");
}
}
@@ -123,7 +127,9 @@ public BinaryIn(String name) {
// or URL from web
if (url == null) {
- url = new URL(name);
+ URI uri = new URI(name);
+ if (uri.isAbsolute()) url = uri.toURL();
+ else throw new IllegalArgumentException("could not read: '" + name+ "'");
}
URLConnection site = url.openConnection();
@@ -131,8 +137,8 @@ public BinaryIn(String name) {
in = new BufferedInputStream(is);
fillBuffer();
}
- catch (IOException ioe) {
- System.err.println("Could not open " + name);
+ catch (IOException | URISyntaxException e) {
+ System.err.println("could not open: '" + name + "'");
}
}
@@ -213,10 +219,11 @@ public char readChar() {
/**
- * Reads the next r bits from this binary input stream and return as an r-bit character.
+ * Reads the next r bits from this binary input stream and return
+ * as an r-bit character.
*
* @param r number of bits to read
- * @return the next {@code r} bits of data from this binary input streamt as a {@code char}
+ * @return the next {@code r} bits of data from this binary input stream as a {@code char}
* @throws NoSuchElementException if there are fewer than {@code r} bits available
* @throws IllegalArgumentException unless {@code 1 <= r <= 16}
*/
@@ -237,7 +244,7 @@ public char readChar(int r) {
/**
- * Reads the remaining bytes of data from this binary input stream and return as a string.
+ * Reads the remaining bytes of data from this binary input stream and return as a string.
*
* @return the remaining bytes of data from this binary input stream as a {@code String}
* @throws NoSuchElementException if this binary input stream is empty or if the number of bits
@@ -288,7 +295,8 @@ public int readInt() {
}
/**
- * Reads the next r bits from this binary input stream return as an r-bit int.
+ * Reads the next r bits from this binary input stream return
+ * as an r-bit int.
*
* @param r number of bits to read
* @return the next {@code r} bits of data from this binary input stream as a {@code int}
@@ -357,7 +365,7 @@ public byte readByte() {
char c = readChar();
return (byte) (c & 0xff);
}
-
+
/**
* Unit tests the {@code BinaryIn} data type.
* Reads the name of a file or URL (first command-line argument)
@@ -379,7 +387,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/BinaryInsertion.java b/src/main/java/edu/princeton/cs/algs4/BinaryInsertion.java
index 72cf749af..e43a40be1 100644
--- a/src/main/java/edu/princeton/cs/algs4/BinaryInsertion.java
+++ b/src/main/java/edu/princeton/cs/algs4/BinaryInsertion.java
@@ -4,8 +4,8 @@
* Dependencies: StdOut.java StdIn.java
* Data files: https://algs4.cs.princeton.edu/21elementary/tiny.txt
* https://algs4.cs.princeton.edu/21elementary/words3.txt
- *
- * Sorts a sequence of strings from standard input using
+ *
+ * Sorts a sequence of strings from standard input using
* binary insertion sort with half exchanges.
*
* % more tiny.txt
@@ -28,16 +28,20 @@
* The {@code BinaryInsertion} class provides a static method for sorting an
* array using an optimized binary insertion sort with half exchanges.
*
- * This implementation makes ~ n lg n compares for any array of length n.
- * However, in the worst case, the running time is quadratic because the
- * number of array accesses can be proportional to n^2 (e.g, if the array
- * is reverse sorted). As such, it is not suitable for sorting large
- * arrays (unless the number of inversions is small).
+ * In the worst case, this implementation makes
+ * ~ n log2n compares to sort an array of length
+ * n. However, in the worst case, the running time is
+ * Θ(n2) because the number of array accesses
+ * can be quadratic.
+ * As such, it is not suitable for sorting large arrays
+ * (unless the number of inversions is small).
*
- * The sorting algorithm is stable and uses O(1) extra memory.
+ * This sorting algorithm is stable.
+ * It uses Θ(1) extra memory (not including the input array).
*
- * For additional documentation, see Section 2.1 of
- * Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
+ * For additional documentation,
+ * see Section 2.1
+ * of Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
*
* @author Ivan Pesin
* @author Robert Sedgewick
@@ -60,12 +64,12 @@ public static void sort(Comparable[] a) {
Comparable v = a[i];
int lo = 0, hi = i;
while (lo < hi) {
- int mid = lo + (hi - lo) / 2;
+ int mid = lo + (hi - lo) / 2;
if (less(v, a[mid])) hi = mid;
else lo = mid + 1;
}
- // insetion sort with "half exchanges"
+ // insertion sort with "half exchanges"
// (insert a[i] at index j and shift a[j], ..., a[i-1] to right)
for (int j = i; j > lo; --j)
a[j] = a[j-1];
@@ -79,7 +83,7 @@ public static void sort(Comparable[] a) {
/***************************************************************************
* Helper sorting function.
***************************************************************************/
-
+
// is v < w ?
private static boolean less(Comparable v, Comparable w) {
return v.compareTo(w) < 0;
@@ -120,7 +124,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/BinaryOut.java b/src/main/java/edu/princeton/cs/algs4/BinaryOut.java
index 8dc1dccb1..8db5d3b3f 100644
--- a/src/main/java/edu/princeton/cs/algs4/BinaryOut.java
+++ b/src/main/java/edu/princeton/cs/algs4/BinaryOut.java
@@ -21,9 +21,9 @@
import java.net.Socket;
/**
- * Binary output. This class provides methods for converting
- * primtive type variables ({@code boolean}, {@code byte}, {@code char},
- * {@code int}, {@code long}, {@code float}, and {@code double})
+ * The
- * This implementation uses a sorted array. It requires that
+ * It requires that
* the key type implements the {@code Comparable} interface and calls the
* {@code compareTo()} and method to compare two keys. It does not call either
* {@code equals()} or {@code hashCode()}.
- * The put and remove operations each take linear time in
- * the worst case; the contains, ceiling, floor,
- * and rank operations take logarithmic time; the size,
- * is-empty, minimum, maximum, and select
- * operations take constant time. Construction takes constant time.
*
- * For additional documentation, see Section 3.1 of
- * Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
- * For other implementations, see {@link ST}, {@link BST},
- * {@link SequentialSearchST}, {@link RedBlackBST},
+ * This implementation uses a sorted array.
+ * The put and remove operations take Θ(n)
+ * time in the worst case.
+ * The contains, ceiling, floor,
+ * and rank operations take Θ(log n) time in the worst
+ * case.
+ * The size, is-empty, minimum, maximum,
+ * and select operations take Θ(1) time.
+ * Construction takes Θ(1) time.
+ *
+ * For alternative implementations of the symbol table API,
+ * see {@link ST}, {@link BST}, {@link SequentialSearchST}, {@link RedBlackBST},
* {@link SeparateChainingHashST}, and {@link LinearProbingHashST},
+ * For additional documentation,
+ * see Section 3.1 of
* Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
*/
public class BinarySearchST
- * All primitive types are assumed to be represented using their
+ * All primitive types are assumed to be represented using their
* standard Java representations, in big-endian (most significant
* byte first) order.
*
@@ -136,7 +137,7 @@ public static char readChar() {
}
/**
- * Reads the next r bits from standard input and return as an r-bit character.
+ * Reads the next r bits from standard input and return as an r-bit character.
*
* @param r number of bits to read.
* @return the next r bits of data from standard input as a {@code char}
@@ -159,7 +160,7 @@ public static char readChar(int r) {
}
/**
- * Reads the remaining bytes of data from standard input and return as a string.
+ * Reads the remaining bytes of data from standard input and return as a string.
*
* @return the remaining bytes of data from standard input as a {@code String}
* @throws NoSuchElementException if standard input is empty or if the number of bits
@@ -210,7 +211,7 @@ public static int readInt() {
}
/**
- * Reads the next r bits from standard input and return as an r-bit int.
+ * Reads the next r bits from standard input and return as an r-bit int.
*
* @param r number of bits to read.
* @return the next r bits of data from standard input as a {@code int}
@@ -280,7 +281,7 @@ public static byte readByte() {
char c = readChar();
return (byte) (c & 0xff);
}
-
+
/**
* Test client. Reads in a binary input file from standard input and writes
* it to standard output.
@@ -299,7 +300,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/BinaryStdOut.java b/src/main/java/edu/princeton/cs/algs4/BinaryStdOut.java
index 058087d64..943e11db3 100644
--- a/src/main/java/edu/princeton/cs/algs4/BinaryStdOut.java
+++ b/src/main/java/edu/princeton/cs/algs4/BinaryStdOut.java
@@ -17,8 +17,8 @@
import java.io.IOException;
/**
- * Binary standard output. This class provides methods for converting
- * primtive type variables ({@code boolean}, {@code byte}, {@code char},
+ * The
* The client should not intermix calls to {@code BinaryStdOut} with calls
- * to {@code StdOut} or {@code System.out}; otherwise unexpected behavior
+ * to {@code StdOut} or {@code System.out}; otherwise unexpected behavior
* will result.
*
* @author Robert Sedgewick
@@ -62,7 +62,7 @@ private static void writeBit(boolean bit) {
// if buffer is full (8 bits), write out as a single byte
n++;
if (n == 8) clearBuffer();
- }
+ }
/**
* Writes the 8-bit byte to standard output.
@@ -142,7 +142,7 @@ public static void close() {
*/
public static void write(boolean x) {
writeBit(x);
- }
+ }
/**
* Writes the 8-bit byte to standard output.
@@ -164,7 +164,7 @@ public static void write(int x) {
}
/**
- * Writes the r-bit int to standard output.
+ * Writes the r-bit int to standard output.
* @param x the {@code int} to write.
* @param r the number of relevant bits in the char.
* @throws IllegalArgumentException if {@code r} is not between 1 and 32.
@@ -230,7 +230,7 @@ public static void write(short x) {
/**
* Writes the 8-bit char to standard output.
* @param x the {@code char} to write.
- * @throws IllegalArgumentException if {@code x} is not betwen 0 and 255.
+ * @throws IllegalArgumentException if {@code x} is not between 0 and 255.
*/
public static void write(char x) {
if (x < 0 || x >= 256) throw new IllegalArgumentException("Illegal 8-bit char = " + x);
@@ -238,7 +238,7 @@ public static void write(char x) {
}
/**
- * Writes the r-bit char to standard output.
+ * Writes the r-bit char to standard output.
* @param x the {@code char} to write.
* @param r the number of relevant bits in the char.
* @throws IllegalArgumentException if {@code r} is not between 1 and 16.
@@ -269,9 +269,9 @@ public static void write(String s) {
}
/**
- * Writes the string of r-bit characters to standard output.
+ * Writes the string of r-bit characters to standard output.
* @param s the {@code String} to write.
- * @param r the number of relevants bits in each character.
+ * @param r the number of relevant bits in each character.
* @throws IllegalArgumentException if r is not between 1 and 16.
* @throws IllegalArgumentException if any character in the string is not
* between 0 and 2r - 1.
@@ -299,7 +299,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/BinomialMinPQ.java b/src/main/java/edu/princeton/cs/algs4/BinomialMinPQ.java
index 661e4a4b6..06bec8b44 100644
--- a/src/main/java/edu/princeton/cs/algs4/BinomialMinPQ.java
+++ b/src/main/java/edu/princeton/cs/algs4/BinomialMinPQ.java
@@ -304,7 +304,7 @@ public int compare(Key key1, Key key2) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/Bipartite.java b/src/main/java/edu/princeton/cs/algs4/Bipartite.java
index 88cb8684d..1644ebd4f 100644
--- a/src/main/java/edu/princeton/cs/algs4/Bipartite.java
+++ b/src/main/java/edu/princeton/cs/algs4/Bipartite.java
@@ -1,7 +1,7 @@
/******************************************************************************
* Compilation: javac Bipartite.java
* Execution: java Bipartite V E F
- * Dependencies: Graph.java
+ * Dependencies: Graph.java
* Data files: https://algs4.cs.princeton.edu/41graph/tinyG.txt
* https://algs4.cs.princeton.edu/41graph/mediumG.txt
* https://algs4.cs.princeton.edu/41graph/largeG.txt
@@ -15,25 +15,25 @@
/**
- * The {@code Bipartite} class represents a data type for
- * determining whether an undirected graph is bipartite or whether
- * it has an odd-length cycle.
+ * The {@code Bipartite} class represents a data type for
+ * determining whether an undirected graph is bipartite or whether
+ * it has an odd-length cycle.
+ * A graph is bipartite if and only if it has no odd-length cycle.
* The isBipartite operation determines whether the graph is
* bipartite. If so, the color operation determines a
* bipartition; if not, the oddCycle operation determines a
* cycle with an odd number of edges.
*
- * This implementation uses depth-first search.
- * The constructor takes time proportional to V + E
- * (in the worst case),
- * where V is the number of vertices and E is the number of edges.
- * Afterwards, the isBipartite and color operations
- * take constant time; the oddCycle operation takes time proportional
- * to the length of the cycle.
+ * This implementation uses depth-first search.
+ * The constructor takes Θ(V + E) time in
+ * the worst case, where V is the number of vertices and E
+ * is the number of edges.
+ * Each instance method takes Θ(1) time.
+ * It uses Θ(V) extra space (not including the graph).
* See {@link BipartiteX} for a nonrecursive version that uses breadth-first
* search.
*
- * For additional documentation, see Section 4.1
+ * For additional documentation, see Section 4.1
* of Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
*
* @author Robert Sedgewick
@@ -66,7 +66,7 @@ public Bipartite(Graph G) {
assert check(G);
}
- private void dfs(Graph G, int v) {
+ private void dfs(Graph G, int v) {
marked[v] = true;
for (int w : G.adj(v)) {
@@ -78,7 +78,7 @@ private void dfs(Graph G, int v) {
edgeTo[w] = v;
color[w] = !color[v];
dfs(G, w);
- }
+ }
// if v-w create an odd-length cycle, find it
else if (color[w] == color[v]) {
@@ -101,7 +101,7 @@ else if (color[w] == color[v]) {
public boolean isBipartite() {
return isBipartite;
}
-
+
/**
* Returns the side of the bipartite that vertex {@code v} is on.
*
@@ -109,7 +109,7 @@ public boolean isBipartite() {
* @return the side of the bipartition that vertex {@code v} is on; two vertices
* are in the same side of the bipartition if and only if they have the
* same color
- * @throws IllegalArgumentException unless {@code 0 <= v < V}
+ * @throws IllegalArgumentException unless {@code 0 <= v < V}
* @throws UnsupportedOperationException if this method is called when the graph
* is not bipartite
*/
@@ -129,7 +129,7 @@ public boolean color(int v) {
* otherwise
*/
public Iterable
- * See also {@link HopcroftKarp}, which solves the problem in O(E sqrt(V))
- * using the Hopcroft-Karp algorithm and
+ * See also {@link HopcroftKarp}, which solves the problem in
+ * O(E sqrt(V)) using the Hopcroft-Karp
+ * algorithm and
* BipartiteMatchingToMaxflow,
- * which solves the problem in O(E V) time via a reduction to maxflow.
+ * which solves the problem in O((E + V) V)
+ * time via a reduction to maxflow.
*
* For additional documentation, see
* Section 6.5
@@ -317,7 +318,7 @@ public static void main(String[] args) {
if (G.V() < 1000) StdOut.println(G);
BipartiteMatching matching = new BipartiteMatching(G);
-
+
// print maximum matching
StdOut.printf("Number of edges in max matching = %d\n", matching.size());
StdOut.printf("Number of vertices in min vertex cover = %d\n", matching.size());
@@ -345,7 +346,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/BipartiteX.java b/src/main/java/edu/princeton/cs/algs4/BipartiteX.java
index af467abcb..c41b5f500 100644
--- a/src/main/java/edu/princeton/cs/algs4/BipartiteX.java
+++ b/src/main/java/edu/princeton/cs/algs4/BipartiteX.java
@@ -1,7 +1,7 @@
/******************************************************************************
* Compilation: javac BipartiteX.java
* Execution: java Bipartite V E F
- * Dependencies: Graph.java
+ * Dependencies: Graph.java
*
* Given a graph, find either (i) a bipartition or (ii) an odd-length cycle.
* Runs in O(E + V) time.
@@ -13,25 +13,25 @@
/**
- * The {@code BipartiteX} class represents a data type for
- * determining whether an undirected graph is bipartite or whether
- * it has an odd-length cycle.
+ * The {@code BipartiteX} class represents a data type for
+ * determining whether an undirected graph is bipartite or whether
+ * it has an odd-length cycle.
+ * A graph is bipartite if and only if it has no odd-length cycle.
* The isBipartite operation determines whether the graph is
* bipartite. If so, the color operation determines a
* bipartition; if not, the oddCycle operation determines a
* cycle with an odd number of edges.
*
- * This implementation uses breadth-first search and is nonrecursive.
- * The constructor takes time proportional to V + E
- * (in the worst case),
- * where V is the number of vertices and E is the number of edges.
- * Afterwards, the isBipartite and color operations
- * take constant time; the oddCycle operation takes time proportional
- * to the length of the cycle.
+ * This implementation uses breadth-first search and is nonrecursive.
+ * The constructor takes Θ(V + E) time in
+ * in the worst case, where V is the number of vertices
+ * and E is the number of edges.
+ * Each instance method takes Θ(1) time.
+ * It uses Θ(V) extra space (not including the graph).
* See {@link Bipartite} for a recursive version that uses depth-first search.
*
* For additional documentation,
- * see Section 4.1
+ * see Section 4.1
* of Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
*
* @author Robert Sedgewick
@@ -67,7 +67,7 @@ public BipartiteX(Graph G) {
assert check(G);
}
- private void bfs(Graph G, int s) {
+ private void bfs(Graph G, int s) {
Queue
- * For additional documentation, see Section 3.5 of
+ * For additional documentation,
+ * see Section 3.5 of
* Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
- *
+ *
* @author Robert Sedgewick
* @author Kevin Wayne
*/
-public class BlackFilter {
+public class BlockFilter {
// Do not instantiate.
- private BlackFilter() { }
+ private BlockFilter() { }
public static void main(String[] args) {
SET
* This implementation uses Boruvka's algorithm and the union-find
* data type.
- * The constructor takes time proportional to E log V
- * and extra space (not including the graph) proportional to V,
- * where V is the number of vertices and E is the number of edges.
- * Afterwards, the {@code weight()} method takes constant time
- * and the {@code edges()} method takes time proportional to V.
+ * The constructor takes Θ(E log V) time in
+ * the worst case, where V is the number of vertices and
+ * E is the number of edges.
+ * Each instance method takes Θ(1) time.
+ * It uses Θ(V) extra space (not including the
+ * edge-weighted graph).
+ *
+ * This {@code weight()} method correctly computes the weight of the MST
+ * if all arithmetic performed is without floating-point rounding error
+ * or arithmetic overflow.
+ * This is the case if all edge weights are non-negative integers
+ * and the weight of the MST does not exceed 252.
*
* For additional documentation,
* see Section 4.3 of
@@ -51,7 +58,7 @@
* @author Kevin Wayne
*/
public class BoruvkaMST {
- private static final double FLOATING_POINT_EPSILON = 1E-12;
+ private static final double FLOATING_POINT_EPSILON = 1.0E-12;
private Bag
* This implementation uses breadth-first search.
- * The constructor takes time proportional to V + E,
- * where V is the number of vertices and E is the number of edges.
- * Each call to {@link #distTo(int)} and {@link #hasPathTo(int)} takes constant time;
- * each call to {@link #pathTo(int)} takes time proportional to the length
- * of the path.
- * It uses extra space (not including the digraph) proportional to V.
+ * The constructor takes Θ(V + E) time in the
+ * worst case, where V is the number of vertices and E is
+ * the number of edges.
+ * Each instance method takes Θ(1) time.
+ * It uses Θ(V) extra space (not including the digraph).
*
- * For additional documentation,
- * see Section 4.2 of
+ * For additional documentation,
+ * see Section 4.2 of
* Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
*
* @author Robert Sedgewick
@@ -75,6 +74,8 @@ public BreadthFirstDirectedPaths(Digraph G, int s) {
* to every other vertex in graph {@code G}.
* @param G the digraph
* @param sources the source vertices
+ * @throws IllegalArgumentException if {@code sources} is {@code null}
+ * @throws IllegalArgumentException if {@code sources} contains no vertices
* @throws IllegalArgumentException unless each vertex {@code v} in
* {@code sources} satisfies {@code 0 <= v < V}
*/
@@ -143,7 +144,8 @@ public boolean hasPathTo(int v) {
* Returns the number of edges in a shortest path from the source {@code s}
* (or sources) to vertex {@code v}?
* @param v the vertex
- * @return the number of edges in a shortest path
+ * @return the number of edges in such a shortest path
+ * (or {@code Integer.MAX_VALUE} if there is no such path)
* @throws IllegalArgumentException unless {@code 0 <= v < V}
*/
public int distTo(int v) {
@@ -177,20 +179,25 @@ private void validateVertex(int v) {
throw new IllegalArgumentException("vertex " + v + " is not between 0 and " + (V-1));
}
- // throw an IllegalArgumentException unless {@code 0 <= v < V}
+ // throw an IllegalArgumentException if vertices is null, has zero vertices,
+ // or has a vertex not between 0 and V-1
private void validateVertices(Iterable
* This implementation uses breadth-first search.
- * The constructor takes time proportional to V + E,
- * where V is the number of vertices and E is the number of edges.
- * Each call to {@link #distTo(int)} and {@link #hasPathTo(int)} takes constant time;
- * each call to {@link #pathTo(int)} takes time proportional to the length
- * of the path.
- * It uses extra space (not including the graph) proportional to V.
+ * The constructor takes Θ(V + E) time in the
+ * worst case, where V is the number of vertices and E
+ * is the number of edges.
+ * Each instance method takes Θ(1) time.
+ * It uses Θ(V) extra space (not including the graph).
*
* For additional documentation,
- * see Section 4.1
+ * see Section 4.1
* of Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
*
* @author Robert Sedgewick
@@ -90,6 +89,8 @@ public BreadthFirstPaths(Graph G, int s) {
* and every other vertex in graph {@code G}.
* @param G the graph
* @param sources the source vertices
+ * @throws IllegalArgumentException if {@code sources} is {@code null}
+ * @throws IllegalArgumentException if {@code sources} contains no vertices
* @throws IllegalArgumentException unless {@code 0 <= s < V} for each vertex
* {@code s} in {@code sources}
*/
@@ -162,7 +163,8 @@ public boolean hasPathTo(int v) {
* Returns the number of edges in a shortest path between the source vertex {@code s}
* (or sources) and vertex {@code v}?
* @param v the vertex
- * @return the number of edges in a shortest path
+ * @return the number of edges in such a shortest path
+ * (or {@code Integer.MAX_VALUE} if there is no such path)
* @throws IllegalArgumentException unless {@code 0 <= v < V}
*/
public int distTo(int v) {
@@ -240,16 +242,22 @@ private void validateVertex(int v) {
throw new IllegalArgumentException("vertex " + v + " is not between 0 and " + (V-1));
}
- // throw an IllegalArgumentException unless {@code 0 <= v < V}
+ // throw an IllegalArgumentException if vertices is null, has zero vertices,
+ // or has a vertex not between 0 and V-1
private void validateVertices(Iterable
+ * The component identifier of a vertex is an integer between
+ * 0 and k–1, where k is the number of connected components.
+ * Two vertices have the same component identifier if and only if
+ * they are in the same connected component.
*
* This implementation uses depth-first search.
- * The constructor takes time proportional to V + E
- * (in the worst case),
- * where V is the number of vertices and E is the number of edges.
- * Afterwards, the id, count, connected,
- * and size operations take constant time.
+ * The constructor takes Θ(V + E) time,
+ * where V is the number of vertices and E is the
+ * number of edges.
+ * Each instance method takes Θ(1) time.
+ * It uses Θ(V) extra space (not including the graph).
*
- * For additional documentation, see Section 4.1
- * of Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
+ * For additional documentation, see
+ * Section 4.1
+ * of Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
@@ -235,7 +236,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/CPM.java b/src/main/java/edu/princeton/cs/algs4/CPM.java
index 63324a3b6..8e350f127 100644
--- a/src/main/java/edu/princeton/cs/algs4/CPM.java
+++ b/src/main/java/edu/princeton/cs/algs4/CPM.java
@@ -37,9 +37,9 @@
*
* This implementation uses {@link AcyclicLP} to find a longest
* path in a DAG.
- * The running time is proportional to V + E,
- * where V is the number of jobs and E is the
- * number of precedence constraints.
+ * The program takes Θ(V + E) time in
+ * the worst case, where V is the number of jobs and
+ * E is the number of precedence constraints.
*
* For additional documentation,
* see Section 4.4 of
@@ -99,7 +99,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/Cat.java b/src/main/java/edu/princeton/cs/algs4/Cat.java
index 983553ef2..b89809d53 100644
--- a/src/main/java/edu/princeton/cs/algs4/Cat.java
+++ b/src/main/java/edu/princeton/cs/algs4/Cat.java
@@ -5,17 +5,17 @@
* Data files: https://algs4.cs.princeton.edu/11model/in1.txt
* https://algs4.cs.princeton.edu/11model/in2.txt
*
- * Reads in text files specified as the first command-line
+ * Reads in text files specified as the first command-line
* arguments, concatenates them, and writes the result to
* filename specified as the last command-line arguments.
*
* % more in1.txt
* This is
*
- * % more in2.txt
+ * % more in2.txt
* a tiny
* test.
- *
+ *
* % java Cat in1.txt in2.txt out.txt
*
* % more out.txt
@@ -37,7 +37,7 @@
* @author Robert Sedgewick
* @author Kevin Wayne
*/
-public class Cat {
+public class Cat {
// this class should not be instantiated
private Cat() { }
@@ -49,7 +49,7 @@ private Cat() { }
*
* @param args the command-line arguments
*/
- public static void main(String[] args) {
+ public static void main(String[] args) {
Out out = new Out(args[args.length - 1]);
for (int i = 0; i < args.length - 1; i++) {
In in = new In(args[i]);
@@ -63,7 +63,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/ClosestPair.java b/src/main/java/edu/princeton/cs/algs4/ClosestPair.java
index 533055808..c6638c41f 100644
--- a/src/main/java/edu/princeton/cs/algs4/ClosestPair.java
+++ b/src/main/java/edu/princeton/cs/algs4/ClosestPair.java
@@ -4,7 +4,7 @@
* Dependencies: Point2D.java
* Data files: https://algs4.cs.princeton.edu/99hull/rs1423.txt
* https://algs4.cs.princeton.edu/99hull/kw1260.txt
- *
+ *
* Given n points in the plane, find the closest pair in n log n time.
*
* Note: could speed it up by comparing square of Euclidean distances
@@ -18,11 +18,11 @@
/**
* The {@code ClosestPair} data type computes a closest pair of points
- * in a set of n points in the plane and provides accessor methods
+ * in a set of n points in the plane and provides accessor methods
* for getting the closest pair of points and the distance between them.
* The distance between two points is their Euclidean distance.
*
- * This implementation uses a divide-and-conquer algorithm.
+ * This implementation uses a divide-and-conquer algorithm.
* It runs in O(n log n) time in the worst case and uses
* O(n) extra space.
*
@@ -56,10 +56,11 @@ public ClosestPair(Point2D[] points) {
int n = points.length;
if (n <= 1) return;
- // sort by x-coordinate (breaking ties by y-coordinate)
+ // sort by x-coordinate (breaking ties by y-coordinate via stability)
Point2D[] pointsByX = new Point2D[n];
for (int i = 0; i < n; i++)
pointsByX[i] = points[i];
+ Arrays.sort(pointsByX, Point2D.Y_ORDER);
Arrays.sort(pointsByX, Point2D.X_ORDER);
// check for coincident points
@@ -72,7 +73,7 @@ public ClosestPair(Point2D[] points) {
}
}
- // sort by y-coordinate (but not yet sorted)
+ // sort by y-coordinate (but not yet sorted)
Point2D[] pointsByY = new Point2D[n];
for (int i = 0; i < n; i++)
pointsByY[i] = pointsByX[i];
@@ -148,7 +149,7 @@ public Point2D other() {
}
/**
- * Returns the Eucliden distance between the closest pair of points.
+ * Returns the Euclidean distance between the closest pair of points.
*
* @return the Euclidean distance between the closest pair of points
* {@code Double.POSITIVE_INFINITY} if no such pair of points
@@ -170,8 +171,8 @@ private static void merge(Comparable[] a, Comparable[] aux, int lo, int mid, int
for (int k = lo; k <= hi; k++) {
aux[k] = a[k];
}
-
- // merge back to a[]
+
+ // merge back to a[]
int i = lo, j = mid+1;
for (int k = lo; k <= hi; k++) {
if (i > mid) a[k] = aux[j++];
@@ -207,7 +208,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/CollisionSystem.java b/src/main/java/edu/princeton/cs/algs4/CollisionSystem.java
index 9842541b8..df79a85f9 100644
--- a/src/main/java/edu/princeton/cs/algs4/CollisionSystem.java
+++ b/src/main/java/edu/princeton/cs/algs4/CollisionSystem.java
@@ -1,7 +1,7 @@
/******************************************************************************
* Compilation: javac CollisionSystem.java
* Execution: java CollisionSystem n (n random particles)
- * java CollisionSystem < input.txt (from a file)
+ * java CollisionSystem < input.txt (from a file)
* Dependencies: StdDraw.java Particle.java MinPQ.java
* Data files: https://algs4.cs.princeton.edu/61event/diffusion.txt
* https://algs4.cs.princeton.edu/61event/diffusion2.txt
@@ -10,7 +10,7 @@
* https://algs4.cs.princeton.edu/61event/brownian2.txt
* https://algs4.cs.princeton.edu/61event/billiards5.txt
* https://algs4.cs.princeton.edu/61event/pendulum.txt
- *
+ *
* Creates n random particles and simulates their motion according
* to the laws of elastic collisions.
*
@@ -25,9 +25,9 @@
* moving in the unit box, according to the laws of elastic collision.
* This event-based simulation relies on a priority queue.
*
- * For additional documentation,
- * see Section 6.1 of
- * Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
+ * For additional documentation,
+ * see Section 6.1 of
+ * Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
@@ -80,14 +80,14 @@ private void redraw(double limit) {
}
}
-
+
/**
* Simulates the system of particles for the specified amount of time.
*
* @param limit the amount of time
*/
public void simulate(double limit) {
-
+
// initialize PQ with collision events and redraw event
pq = new MinPQ
+ * This computes correct results if all arithmetic performed is
+ * without floating-point rounding error or arithmetic overflow.
+ * In practice, there will be floating-point rounding error.
+ *
* For additional documentation, see Section 9.9 of
* Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
*
@@ -233,7 +237,7 @@ public Complex cos() {
public Complex tan() {
return sin().divides(cos());
}
-
+
/**
* Unit tests the {@code Complex} data type.
@@ -262,7 +266,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/Count.java b/src/main/java/edu/princeton/cs/algs4/Count.java
index 1940b50b9..89e2b5523 100644
--- a/src/main/java/edu/princeton/cs/algs4/Count.java
+++ b/src/main/java/edu/princeton/cs/algs4/Count.java
@@ -5,12 +5,12 @@
* Data files: https://algs4.cs.princeton.edu/50strings/abra.txt
* https://algs4.cs.princeton.edu/50strings/pi.txt
*
- * Create an alphabet specified on the command line, read in a
+ * Create an alphabet specified on the command line, read in a
* sequence of characters over that alphabet (ignoring characters
* not in the alphabet), computes the frequency of occurrence of
* each character, and print out the results.
*
- * % java Count ABCDR < abra.txt
+ * % java Count ABCDR < abra.txt
* A 5
* B 2
* C 1
@@ -54,7 +54,7 @@ private Count() { }
/**
* Reads in text from standard input; calculates the frequency of
* occurrence of each character over the alphabet specified as a
- * commmand-line argument; and prints the frequencies to standard
+ * command-line argument; and prints the frequencies to standard
* output.
*
* @param args the command-line arguments
@@ -75,7 +75,7 @@ public static void main(String[] args) {
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/Counter.java b/src/main/java/edu/princeton/cs/algs4/Counter.java
index 1773a3e75..922136b94 100644
--- a/src/main/java/edu/princeton/cs/algs4/Counter.java
+++ b/src/main/java/edu/princeton/cs/algs4/Counter.java
@@ -42,14 +42,14 @@ public class Counter implements Comparable
* This implementation uses depth-first search.
- * The constructor takes time proportional to V + E
- * (in the worst case),
- * where V is the number of vertices and E is the number of edges.
- * Afterwards, the hasCycle operation takes constant time;
- * the cycle operation takes time proportional
- * to the length of the cycle.
+ * The constructor takes Θ(V + E) time in the
+ * worst case, where V is the number of vertices and
+ * E is the number of edges.
+ * (The depth-first search part takes only O(V) time;
+ * however, checking for self-loops and parallel edges takes
+ * Θ(V + E) time in the worst case.
+ * Each instance method takes Θ(1) time.
+ * It uses Θ(V) extra space (not including the graph).
+ *
*
- * For additional documentation, see Section 4.1
+ * For additional documentation, see
+ * Section 4.1
* of Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
*
* @author Robert Sedgewick
@@ -54,8 +58,12 @@ public class Cycle {
* @param G the undirected graph
*/
public Cycle(Graph G) {
- if (hasSelfLoop(G)) return;
+ // need special case to identify parallel edge as a cycle
if (hasParallelEdges(G)) return;
+
+ // don't need special case to identify self-loop as a cycle
+ // if (hasSelfLoop(G)) return;
+
marked = new boolean[G.V()];
edgeTo = new int[G.V()];
for (int v = 0; v < G.V(); v++)
@@ -169,12 +177,10 @@ public static void main(String[] args) {
}
}
-
}
-
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/Date.java b/src/main/java/edu/princeton/cs/algs4/Date.java
index b7213e099..49443058b 100644
--- a/src/main/java/edu/princeton/cs/algs4/Date.java
+++ b/src/main/java/edu/princeton/cs/algs4/Date.java
@@ -13,9 +13,9 @@
* The {@code Date} class is an immutable data type to encapsulate a
* date (day, month, and year).
*
- * For additional documentation,
- * see Section 1.2 of
- * Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
+ * For additional documentation,
+ * see Section 1.2 of
+ * Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
@@ -133,8 +133,8 @@ public boolean isBefore(Date that) {
*
* @return the value {@code 0} if the argument date is equal to this date;
* a negative integer if this date is chronologically less than
- * the argument date; and a positive ineger if this date is chronologically
- * after the argument date
+ * the argument date; and a positive integer if this date is
+ * chronologically after the argument date
*/
@Override
public int compareTo(Date that) {
@@ -179,11 +179,7 @@ public boolean equals(Object other) {
*/
@Override
public int hashCode() {
- int hash = 17;
- hash = 31*hash + month;
- hash = 31*hash + day;
- hash = 31*hash + year;
- return hash;
+ return day + 31*month + 31*12*year;
}
/**
@@ -215,7 +211,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/DeDup.java b/src/main/java/edu/princeton/cs/algs4/DeDup.java
index 1fc2baa73..23d192bc3 100644
--- a/src/main/java/edu/princeton/cs/algs4/DeDup.java
+++ b/src/main/java/edu/princeton/cs/algs4/DeDup.java
@@ -7,14 +7,14 @@
* Read in a list of words from standard input and print out
* each word, removing any duplicates.
*
- * % more tinyTale.txt
- * it was the best of times it was the worst of times
- * it was the age of wisdom it was the age of foolishness
- * it was the epoch of belief it was the epoch of incredulity
- * it was the season of light it was the season of darkness
+ * % more tinyTale.txt
+ * it was the best of times it was the worst of times
+ * it was the age of wisdom it was the age of foolishness
+ * it was the epoch of belief it was the epoch of incredulity
+ * it was the season of light it was the season of darkness
* it was the spring of hope it was the winter of despair
*
- * % java DeDup < tinyTale.txt
+ * % java DeDup < tinyTale.txt
* it
* was
* the
@@ -43,7 +43,7 @@
* @author Robert Sedgewick
* @author Kevin Wayne
*/
-public class DeDup {
+public class DeDup {
// Do not instantiate.
private DeDup() { }
@@ -63,7 +63,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/DegreesOfSeparation.java b/src/main/java/edu/princeton/cs/algs4/DegreesOfSeparation.java
index 774576c5b..eaba98efa 100644
--- a/src/main/java/edu/princeton/cs/algs4/DegreesOfSeparation.java
+++ b/src/main/java/edu/princeton/cs/algs4/DegreesOfSeparation.java
@@ -4,8 +4,8 @@
* Dependencies: SymbolGraph.java Graph.java BreadthFirstPaths.java StdOut.java
* Data files: https://algs4.cs.princeton.edu/41graph/routes.txt
* https://algs4.cs.princeton.edu/41graph/movies.txt
- *
- *
+ *
+ *
* % java DegreesOfSeparation routes.txt " " "JFK"
* LAS
* JFK
@@ -129,7 +129,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/DepthFirstDirectedPaths.java b/src/main/java/edu/princeton/cs/algs4/DepthFirstDirectedPaths.java
index 8ae860aa7..eec5dd98d 100644
--- a/src/main/java/edu/princeton/cs/algs4/DepthFirstDirectedPaths.java
+++ b/src/main/java/edu/princeton/cs/algs4/DepthFirstDirectedPaths.java
@@ -30,21 +30,21 @@
package edu.princeton.cs.algs4;
/**
- * The {@code DepthFirstDirectedPaths} class represents a data type for finding
- * directed paths from a source vertex s to every
+ * The {@code DepthFirstDirectedPaths} class represents a data type for
+ * finding directed paths from a source vertex s to every
* other vertex in the digraph.
*
* This implementation uses depth-first search.
- * The constructor takes time proportional to V + E,
- * where V is the number of vertices and E is the number of edges.
- * Each call to {@link #hasPathTo(int)} takes constant time;
- * each call to {@link #pathTo(int)} takes time proportional to the length
- * of the path returned.
- * It uses extra space (not including the graph) proportional to V.
+ * The constructor takes Θ(V + E) time in the
+ * worst case, where V is the number of vertices and E
+ * is the number of edges.
+ * Each instance method takes Θ(1) time.
+ * It uses Θ(V) extra space (not including the digraph).
*
- * For additional documentation,
- * see Section 4.2 of
- * Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
+ * See {@link DepthFirstDirectedPaths} for a nonrecursive implementation.
+ * For additional documentation,
+ * see Section 4.2 of
+ * Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
@@ -68,7 +68,7 @@ public DepthFirstDirectedPaths(Digraph G, int s) {
dfs(G, s);
}
- private void dfs(Digraph G, int v) {
+ private void dfs(Digraph G, int v) {
marked[v] = true;
for (int w : G.adj(v)) {
if (!marked[w]) {
@@ -90,7 +90,7 @@ public boolean hasPathTo(int v) {
return marked[v];
}
-
+
/**
* Returns a directed path from the source vertex {@code s} to vertex {@code v}, or
* {@code null} if no such path.
@@ -149,7 +149,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/DepthFirstOrder.java b/src/main/java/edu/princeton/cs/algs4/DepthFirstOrder.java
index 4931f34f5..58c9e38ea 100644
--- a/src/main/java/edu/princeton/cs/algs4/DepthFirstOrder.java
+++ b/src/main/java/edu/princeton/cs/algs4/DepthFirstOrder.java
@@ -25,25 +25,25 @@
* 10 8 5
* 11 6 4
* 12 7 3
- * Preorder: 0 5 4 1 6 9 11 12 10 2 3 7 8
- * Postorder: 4 5 1 12 11 10 9 6 0 3 2 7 8
- * Reverse postorder: 8 7 2 3 0 6 9 10 11 12 1 5 4
+ * Preorder: 0 5 4 1 6 9 11 12 10 2 3 7 8
+ * Postorder: 4 5 1 12 11 10 9 6 0 3 2 7 8
+ * Reverse postorder: 8 7 2 3 0 6 9 10 11 12 1 5 4
*
******************************************************************************/
package edu.princeton.cs.algs4;
/**
- * The {@code DepthFirstOrder} class represents a data type for
+ * The {@code DepthFirstOrder} class represents a data type for
* determining depth-first search ordering of the vertices in a digraph
* or edge-weighted digraph, including preorder, postorder, and reverse postorder.
*
* This implementation uses depth-first search.
- * The constructor takes time proportional to V + E
- * (in the worst case),
- * where V is the number of vertices and E is the number of edges.
- * Afterwards, the preorder, postorder, and reverse postorder
- * operation takes take time proportional to V.
+ * Each constructor takes Θ(V + E) time,
+ * where V is the number of vertices and E is the
+ * number of edges.
+ * Each instance method takes Θ(1) time.
+ * It uses Θ(V) extra space (not including the digraph).
*
* For additional documentation,
* see Section 4.2 of
@@ -243,7 +243,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/DepthFirstPaths.java b/src/main/java/edu/princeton/cs/algs4/DepthFirstPaths.java
index 8d62f63fa..4b48fd09a 100644
--- a/src/main/java/edu/princeton/cs/algs4/DepthFirstPaths.java
+++ b/src/main/java/edu/princeton/cs/algs4/DepthFirstPaths.java
@@ -7,17 +7,16 @@
* https://algs4.cs.princeton.edu/41graph/mediumG.txt
* https://algs4.cs.princeton.edu/41graph/largeG.txt
*
- * Run depth first search on an undirected graph.
- * Runs in O(E + V) time.
+ * Run depth-first search on an undirected graph.
*
* % java Graph tinyCG.txt
* 6 8
- * 0: 2 1 5
- * 1: 0 2
- * 2: 0 1 3 4
- * 3: 5 4 2
- * 4: 3 2
- * 5: 3 0
+ * 0: 2 1 5
+ * 1: 0 2
+ * 2: 0 1 3 4
+ * 3: 5 4 2
+ * 4: 3 2
+ * 5: 3 0
*
* % java DepthFirstPaths tinyCG.txt 0
* 0 to 0: 0
@@ -37,14 +36,14 @@
* in an undirected graph.
*
* This implementation uses depth-first search.
- * The constructor takes time proportional to V + E,
- * where V is the number of vertices and E is the number of edges.
- * Each call to {@link #hasPathTo(int)} takes constant time;
- * each call to {@link #pathTo(int)} takes time proportional to the length
- * of the path.
- * It uses extra space (not including the graph) proportional to V.
+ * The constructor takes Θ(V + E) time in the
+ * worst case, where V is the number of vertices and
+ * E is the number of edges.
+ * Each instance method takes Θ(1) time.
+ * It uses Θ(V) extra space (not including the graph).
*
- * For additional documentation, see Section 4.1
+ * For additional documentation, see
+ * Section 4.1
* of Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
*
* @author Robert Sedgewick
@@ -147,7 +146,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/DepthFirstSearch.java b/src/main/java/edu/princeton/cs/algs4/DepthFirstSearch.java
index b70568974..8a994937e 100644
--- a/src/main/java/edu/princeton/cs/algs4/DepthFirstSearch.java
+++ b/src/main/java/edu/princeton/cs/algs4/DepthFirstSearch.java
@@ -9,11 +9,11 @@
* Runs in O(E + V) time.
*
* % java DepthFirstSearch tinyG.txt 0
- * 0 1 2 3 4 5 6
+ * 0 1 2 3 4 5 6
* NOT connected
*
* % java DepthFirstSearch tinyG.txt 9
- * 9 10 11 12
+ * 9 10 11 12
* NOT connected
*
******************************************************************************/
@@ -21,18 +21,21 @@
package edu.princeton.cs.algs4;
/**
- * The {@code DepthFirstSearch} class represents a data type for
+ * The {@code DepthFirstSearch} class represents a data type for
* determining the vertices connected to a given source vertex s
* in an undirected graph. For versions that find the paths, see
* {@link DepthFirstPaths} and {@link BreadthFirstPaths}.
*
* This implementation uses depth-first search.
- * The constructor takes time proportional to V + E
- * (in the worst case),
- * where V is the number of vertices and E is the number of edges.
- * It uses extra space (not including the graph) proportional to V.
+ * See {@link NonrecursiveDFS} for a non-recursive version.
+ * The constructor takes Θ(V + E) time in the worst
+ * case, where V is the number of vertices and E
+ * is the number of edges.
+ * Each instance method takes Θ(1) time.
+ * It uses Θ(V) extra space (not including the graph).
*
- * For additional documentation, see Section 4.1
+ * For additional documentation, see
+ * Section 4.1
* of Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
*
* @author Robert Sedgewick
@@ -115,7 +118,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/Digraph.java b/src/main/java/edu/princeton/cs/algs4/Digraph.java
index c3bb67f5c..79271dbb0 100644
--- a/src/main/java/edu/princeton/cs/algs4/Digraph.java
+++ b/src/main/java/edu/princeton/cs/algs4/Digraph.java
@@ -4,27 +4,27 @@
* Dependencies: Bag.java In.java StdOut.java
* Data files: https://algs4.cs.princeton.edu/42digraph/tinyDG.txt
* https://algs4.cs.princeton.edu/42digraph/mediumDG.txt
- * https://algs4.cs.princeton.edu/42digraph/largeDG.txt
+ * https://algs4.cs.princeton.edu/42digraph/largeDG.txt
*
* A graph, implemented using an array of lists.
* Parallel edges and self-loops are permitted.
*
* % java Digraph tinyDG.txt
* 13 vertices, 22 edges
- * 0: 5 1
- * 1:
- * 2: 0 3
- * 3: 5 2
- * 4: 3 2
- * 5: 4
- * 6: 9 4 8 0
+ * 0: 5 1
+ * 1:
+ * 2: 0 3
+ * 3: 5 2
+ * 4: 3 2
+ * 5: 4
+ * 6: 9 4 8 0
* 7: 6 9
- * 8: 6
- * 9: 11 10
- * 10: 12
- * 11: 4 12
- * 12: 9
- *
+ * 8: 6
+ * 9: 11 10
+ * 10: 12
+ * 11: 4 12
+ * 12: 9
+ *
******************************************************************************/
package edu.princeton.cs.algs4;
@@ -36,13 +36,23 @@
* named 0 through V - 1.
* It supports the following two primary operations: add an edge to the digraph,
* iterate over all of the vertices adjacent from a given vertex.
+ * It also provides
+ * methods for returning the indegree or outdegree of a vertex,
+ * the number of vertices V in the digraph,
+ * the number of edges E in the digraph, and the reverse digraph.
* Parallel edges and self-loops are permitted.
*
- * This implementation uses an adjacency-lists representation, which
+ * This implementation uses an adjacency-lists representation, which
* is a vertex-indexed array of {@link Bag} objects.
- * All operations take constant time (in the worst case) except
- * iterating over the vertices adjacent from a given vertex, which takes
- * time proportional to the number of such vertices.
+ * It uses Θ(E + V) space, where E is
+ * the number of edges and V is the number of vertices.
+ * The
* For additional documentation,
* see Section 4.2 of
@@ -59,7 +69,7 @@ public class Digraph {
private int E; // number of edges in this digraph
private Bag
* This implementation runs Dijkstra's algorithm from each vertex.
- * The constructor takes time proportional to V (E log V)
- * and uses space proprtional to V2,
- * where V is the number of vertices and E is the number of edges.
- * Afterwards, the {@code dist()} and {@code hasPath()} methods take
- * constant time and the {@code path()} method takes time proportional to the
- * number of edges in the shortest path returned.
+ * The constructor takes Θ(V (E log V)) time
+ * in the worst case, where V is the number of vertices and
+ * E is the number of edges.
+ * Each instance method takes Θ(1) time.
+ * It uses Θ(V2) extra space (not including the
+ * edge-weighted digraph).
*
- * For additional documentation,
- * see Section 4.4 of
- * Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
+ * For additional documentation,
+ * see Section 4.4 of
+ * Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
@@ -34,7 +36,7 @@ public class DijkstraAllPairsSP {
private DijkstraSP[] all;
/**
- * Computes a shortest paths tree from each vertex to to every other vertex in
+ * Computes a shortest paths tree from each vertex to every other vertex in
* the edge-weighted digraph {@code G}.
* @param G the edge-weighted digraph
* @throws IllegalArgumentException if an edge weight is negative
@@ -65,7 +67,7 @@ public Iterable
- * This implementation uses Dijkstra's algorithm with a binary heap.
- * The constructor takes time proportional to E log V,
- * where V is the number of vertices and E is the number of edges.
- * Each call to {@code distTo(int)} and {@code hasPathTo(int)} takes constant time;
- * each call to {@code pathTo(int)} takes time proportional to the number of
- * edges in the shortest path returned.
+ * This implementation uses Dijkstra's algorithm with a
+ * binary heap. The constructor takes
+ * Θ(E log V) time in the worst case,
+ * where V is the number of vertices and E is
+ * the number of edges. Each instance method takes Θ(1) time.
+ * It uses Θ(V) extra space (not including the
+ * edge-weighted digraph).
*
- * For additional documentation,
- * see Section 4.4 of
- * Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
+ * This correctly computes shortest paths if all arithmetic performed is
+ * without floating-point rounding error or arithmetic overflow.
+ * This is the case if all edge weights are integers and if none of the
+ * intermediate results exceeds 252. Since all intermediate
+ * results are sums of edge weights, they are bounded by V C,
+ * where V is the number of vertices and C is the maximum
+ * weight of any edge.
+ *
+ * For additional documentation,
+ * see Section 4.4 of
+ * Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
@@ -153,7 +162,7 @@ public Iterable
* This implementation uses Dijkstra's algorithm with a binary heap.
- * The constructor takes time proportional to E log V,
- * where V is the number of vertices and E is the number of edges.
- * Each call to {@code distTo(int)} and {@code hasPathTo(int)} takes constant time;
- * each call to {@code pathTo(int)} takes time proportional to the number of
- * edges in the shortest path returned.
+ * The constructor takes Θ(E log V) time in the
+ * worst case, where V is the number of vertices and
+ * E is the number of edges.
+ * Each instance method takes Θ(1) time.
+ * It uses Θ(V) extra space (not including the
+ * edge-weighted graph).
*
- * For additional documentation,
- * see Section 4.4 of
- * Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
+ * For additional documentation,
+ * see Section 4.4 of
+ * Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
* See {@link DijkstraSP} for a version on edge-weighted digraphs.
- *
+ *
+ * This correctly computes shortest paths if all arithmetic performed is
+ * without floating-point rounding error or arithmetic overflow.
+ * This is the case if all edge weights are integers and if none of the
+ * intermediate results exceeds 252. Since all intermediate
+ * results are sums of edge weights, they are bounded by V C,
+ * where V is the number of vertices and C is the maximum
+ * weight of any edge.
+ *
* @author Robert Sedgewick
* @author Kevin Wayne
* @author Nate Liu
@@ -165,7 +174,7 @@ public Iterable
* This implementation uses depth-first search.
- * The constructor takes time proportional to V + E
- * (in the worst case),
- * where V is the number of vertices and E is the number of edges.
- * Afterwards, the hasCycle operation takes constant time;
- * the cycle operation takes time proportional
- * to the length of the cycle.
+ * The constructor takes Θ(V + E) time in the worst
+ * case, where V is the number of vertices and E is
+ * the number of edges.
+ * Each instance method takes Θ(1) time.
+ * It uses Θ(V) extra space (not including the digraph).
*
* See {@link Topological} to compute a topological order if the
* digraph is acyclic.
@@ -62,7 +60,7 @@ public DirectedCycle(Digraph G) {
if (!marked[v] && cycle == null) dfs(G, v);
}
- // check that algorithm computes either the topological order or finds a directed cycle
+ // run DFS and find a directed cycle (if one exists)
private void dfs(Digraph G, int v) {
onStack[v] = true;
marked[v] = true;
@@ -156,7 +154,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/DirectedCycleX.java b/src/main/java/edu/princeton/cs/algs4/DirectedCycleX.java
index 73a377d22..a803c131b 100644
--- a/src/main/java/edu/princeton/cs/algs4/DirectedCycleX.java
+++ b/src/main/java/edu/princeton/cs/algs4/DirectedCycleX.java
@@ -11,7 +11,7 @@
package edu.princeton.cs.algs4;
/**
- * The {@code DirectedCycleX} class represents a data type for
+ * The {@code DirectedCycleX} class represents a data type for
* determining whether a digraph has a directed cycle.
* The hasCycle operation determines whether the digraph has
* a simple directed cycle and, if so, the cycle operation
@@ -20,10 +20,10 @@
* This implementation uses a nonrecursive, queue-based algorithm.
* The constructor takes time proportional to V + E
* (in the worst case),
- * where V is the number of vertices and E is the number of edges.
- * Afterwards, the hasCycle operation takes constant time;
- * the cycle operation takes time proportional
- * to the length of the cycle.
+ * where V is the number of vertices and E is the
+ * number of edges.
+ * Each instance method takes Θ(1) time.
+ * It uses Θ(V) extra space (not including the digraph).
*
* See {@link DirectedCycle} for a recursive version that uses depth-first search.
* See {@link Topological} or {@link TopologicalX} to compute a topological order
@@ -144,8 +144,8 @@ public static void main(String[] args) {
// add F extra edges
for (int i = 0; i < F; i++) {
- int v = StdRandom.uniform(V);
- int w = StdRandom.uniform(V);
+ int v = StdRandom.uniformInt(V);
+ int w = StdRandom.uniformInt(V);
G.addEdge(v, w);
}
@@ -170,7 +170,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/DirectedDFS.java b/src/main/java/edu/princeton/cs/algs4/DirectedDFS.java
index 7748afc06..57506db27 100644
--- a/src/main/java/edu/princeton/cs/algs4/DirectedDFS.java
+++ b/src/main/java/edu/princeton/cs/algs4/DirectedDFS.java
@@ -17,13 +17,13 @@
* 0 1 2 3 4 5
*
* % java DirectedDFS tinyDG.txt 1 2 6
- * 0 1 2 3 4 5 6 8 9 10 11 12
+ * 0 1 2 3 4 5 6 8 9 10 11 12
*
******************************************************************************/
package edu.princeton.cs.algs4;
/**
- * The {@code DirectedDFS} class represents a data type for
+ * The {@code DirectedDFS} class represents a data type for
* determining the vertices reachable from a given source vertex s
* (or set of source vertices) in a digraph. For versions that find the paths,
* see {@link DepthFirstDirectedPaths} and {@link BreadthFirstDirectedPaths}.
@@ -32,6 +32,8 @@
* The constructor takes time proportional to V + E
* (in the worst case),
* where V is the number of vertices and E is the number of edges.
+ * Each instance method takes Θ(1) time.
+ * It uses Θ(V) extra space (not including the digraph).
*
* For additional documentation,
* see Section 4.2 of
@@ -62,6 +64,8 @@ public DirectedDFS(Digraph G, int s) {
* connected to any of the source vertices {@code sources}.
* @param G the graph
* @param sources the source vertices
+ * @throws IllegalArgumentException if {@code sources} is {@code null}
+ * @throws IllegalArgumentException if {@code sources} contains no vertices
* @throws IllegalArgumentException unless {@code 0 <= s < V}
* for each vertex {@code s} in {@code sources}
*/
@@ -73,7 +77,7 @@ public DirectedDFS(Digraph G, Iterable
- * For additional documentation, see Section 4.4 of
+ * For additional documentation,
+ * see Section 4.4 of
* Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
-public class DirectedEdge {
+public class DirectedEdge {
private final int v;
private final int w;
private final double weight;
@@ -38,8 +39,8 @@ public class DirectedEdge {
* @throws IllegalArgumentException if {@code weight} is {@code NaN}
*/
public DirectedEdge(int v, int w, double weight) {
- if (v < 0) throw new IllegalArgumentException("Vertex names must be nonnegative integers");
- if (w < 0) throw new IllegalArgumentException("Vertex names must be nonnegative integers");
+ if (v < 0) throw new IllegalArgumentException("Vertex names must be non-negative integers");
+ if (w < 0) throw new IllegalArgumentException("Vertex names must be non-negative integers");
if (Double.isNaN(weight)) throw new IllegalArgumentException("Weight is NaN");
this.v = v;
this.w = w;
@@ -90,7 +91,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/DirectedEulerianCycle.java b/src/main/java/edu/princeton/cs/algs4/DirectedEulerianCycle.java
index 61d3e51c9..6e873f8e0 100644
--- a/src/main/java/edu/princeton/cs/algs4/DirectedEulerianCycle.java
+++ b/src/main/java/edu/princeton/cs/algs4/DirectedEulerianCycle.java
@@ -20,10 +20,11 @@
* uses every edge in the digraph exactly once.
*
* This implementation uses a nonrecursive depth-first search.
- * The constructor runs in O(E + V) time,
- * and uses O(V) extra space, where E is the
- * number of edges and V the number of vertices
- * All other methods take O(1) time.
+ * The constructor takes Θ(E + V) time in the worst
+ * case, where E is the number of edges and V is the
+ * number of vertices
+ * Each instance method takes Θ(1) time.
+ * It uses Θ(V) extra space (not including the digraph).
*
* To compute Eulerian paths in digraphs, see {@link DirectedEulerianPath}.
* To compute Eulerian cycles and paths in undirected graphs, see
@@ -32,17 +33,17 @@
* For additional documentation,
* see Section 4.2 of
* Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
- *
+ *
* @author Robert Sedgewick
* @author Kevin Wayne
* @author Nate Liu
*/
public class DirectedEulerianCycle {
- private Stack
* This implementation uses a nonrecursive depth-first search.
- * The constructor runs in O(E + V) time, and uses O(V) extra space,
- * where E is the number of edges and V the number of vertices
- * All other methods take O(1) time.
+ * The constructor take Θ(E + V) time
+ * in the worst case, where E is the number of edges and
+ * V is the number of vertices.
+ * It uses Θ(V) extra space (not including the digraph).
*
* To compute Eulerian cycles in digraphs, see {@link DirectedEulerianCycle}.
* To compute Eulerian cycles and paths in undirected graphs, see
@@ -31,7 +32,7 @@
* For additional documentation,
* see Section 4.2 of
* Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
- *
+ *
* @author Robert Sedgewick
* @author Kevin Wayne
* @author Nate Liu
@@ -41,7 +42,7 @@ public class DirectedEulerianPath {
/**
* Computes an Eulerian path in the specified digraph, if one exists.
- *
+ *
* @param G the digraph
*/
public DirectedEulerianPath(Digraph G) {
@@ -83,7 +84,7 @@ public DirectedEulerianPath(Digraph G) {
// push vertex with no more available edges to path
path.push(v);
}
-
+
// check if all edges have been used
if (path.size() != G.E() + 1)
path = null;
@@ -93,7 +94,7 @@ public DirectedEulerianPath(Digraph G) {
/**
* Returns the sequence of vertices on an Eulerian path.
- *
+ *
* @return the sequence of vertices on an Eulerian path;
* {@code null} if no such path
*/
@@ -103,7 +104,7 @@ public Iterable
- * For additional documentation, see Section 3.1 of
+ * For additional documentation, see
+ * Section 3.1 of
* Computer Science: An Interdisciplinary Approach by Robert Sedgewick and Kevin Wayne.
*
* @author Robert Sedgewick
@@ -89,97 +97,148 @@
public final class Draw implements ActionListener, MouseListener, MouseMotionListener, KeyListener {
/**
- * The color black.
+ * The color aqua (0, 255, 255).
+ */
+ public static final Color AQUA = new Color(0, 255, 255);
+
+ /**
+ * The color black (0, 0, 0).
*/
public static final Color BLACK = Color.BLACK;
/**
- * The color blue.
+ * The color blue (0, 0, 255).
*/
public static final Color BLUE = Color.BLUE;
/**
- * The color cyan.
+ * The color cyan (0, 255, 255).
*/
public static final Color CYAN = Color.CYAN;
/**
- * The color dark gray.
+ * The color fuscia (255, 0, 255).
+ */
+ public static final Color FUSCIA = new Color(255, 0, 255);
+
+ /**
+ * The color dark gray (64, 64, 64).
*/
public static final Color DARK_GRAY = Color.DARK_GRAY;
/**
- * The color gray.
+ * The color gray (128, 128, 128).
*/
public static final Color GRAY = Color.GRAY;
/**
- * The color green.
+ * The color green (0, 128, 0).
*/
- public static final Color GREEN = Color.GREEN;
+ public static final Color GREEN = new Color(0, 128, 0);
/**
- * The color light gray.
+ * The color light gray (192, 192, 192).
*/
public static final Color LIGHT_GRAY = Color.LIGHT_GRAY;
/**
- * The color magenta.
+ * The color lime (0, 255, 0).
+ */
+ public static final Color LIME = new Color(0, 255, 0);
+
+ /**
+ * The color magenta (255, 0, 255).
*/
public static final Color MAGENTA = Color.MAGENTA;
/**
- * The color orange.
+ * The color maroon (128, 0, 0).
+ */
+ public static final Color MAROON = new Color(128, 0, 0);
+
+ /**
+ * The color navy (0, 0, 128).
+ */
+ public static final Color NAVY = new Color(0, 0, 128);
+
+ /**
+ * The color olive (128, 128, 0).
+ */
+ public static final Color OLIVE = new Color(128, 128, 0);
+
+ /**
+ * The color orange (255, 200, 0).
*/
public static final Color ORANGE = Color.ORANGE;
/**
- * The color pink.
+ * The color pink (255, 175, 175).
*/
public static final Color PINK = Color.PINK;
/**
- * The color red.
+ * The color purple (128, 0, 128).
+ */
+ public static final Color PURPLE = new Color(128, 0, 128);
+
+ /**
+ * The color red (255, 0, 0).
*/
public static final Color RED = Color.RED;
/**
- * The color white.
+ * The color silver (192, 192, 192).
+ */
+ public static final Color SILVER = new Color(192, 192, 192);
+
+ /**
+ * The color teal (0, 128, 128).
+ */
+ public static final Color TEAL = new Color(0, 128, 128);
+
+ /**
+ * The color white (255, 255, 255).
*/
public static final Color WHITE = Color.WHITE;
/**
- * The color yellow.
+ * The color yellow (255, 255, 0).
*/
public static final Color YELLOW = Color.YELLOW;
/**
- * Shade of blue used in Introduction to Programming in Java.
+ * A 100% transparent color, for a transparent background.
+ */
+ public static final Color TRANSPARENT = new Color(0, 0, 0, 0);
+
+ /**
+ * The shade of blue used in Introduction to Programming in Java.
* It is Pantone 300U. The RGB values are approximately (9, 90, 166).
*/
public static final Color BOOK_BLUE = new Color(9, 90, 166);
/**
- * Shade of light blue used in Introduction to Programming in Java.
+ * The shade of light blue used in Introduction to Programming in Java.
* The RGB values are approximately (103, 198, 243).
*/
public static final Color BOOK_LIGHT_BLUE = new Color(103, 198, 243);
-
+
/**
- * Shade of red used in Algorithms, 4th edition.
+ * The shade of red used in Algorithms, 4th edition.
* It is Pantone 1805U. The RGB values are approximately (150, 35, 31).
*/
public static final Color BOOK_RED = new Color(150, 35, 31);
/**
- * Shade of orange used in Princeton's identity.
+ * The shade of orange used in Princeton University's identity.
* It is PMS 158. The RGB values are approximately (245, 128, 37).
*/
public static final Color PRINCETON_ORANGE = new Color(245, 128, 37);
// default colors
- private static final Color DEFAULT_PEN_COLOR = BLACK;
- private static final Color DEFAULT_CLEAR_COLOR = WHITE;
+ private static final Color DEFAULT_PEN_COLOR = BLACK;
+ private static final Color DEFAULT_BACKGROUND_COLOR = WHITE;
+
// boundary of drawing canvas, 0% border
private static final double BORDER = 0.0;
@@ -197,30 +256,39 @@ public final class Draw implements ActionListener, MouseListener, MouseMotionLis
// default font
private static final Font DEFAULT_FONT = new Font("SansSerif", Font.PLAIN, 16);
+ // default title of drawing window
+ private static final String DEFAULT_WINDOW_TITLE = "Draw";
+
// current pen color
- private Color penColor;
+ private Color penColor = DEFAULT_PEN_COLOR;
+
+ // background color
+ private Color backgroundColor = DEFAULT_BACKGROUND_COLOR;
+
+ // current title of drawing window
+ private String windowTitle = DEFAULT_WINDOW_TITLE;
// canvas size
private int width = DEFAULT_SIZE;
private int height = DEFAULT_SIZE;
// current pen radius
- private double penRadius;
+ private double penRadius = DEFAULT_PEN_RADIUS;
// show we draw immediately or wait until next show?
private boolean defer = false;
- private double xmin, ymin, xmax, ymax;
-
- // name of window
- private String name = "Draw";
+ private double xmin = DEFAULT_XMIN;
+ private double xmax = DEFAULT_XMAX;
+ private double ymin = DEFAULT_YMIN;
+ private double ymax = DEFAULT_YMAX;
// for synchronization
private final Object mouseLock = new Object();
private final Object keyLock = new Object();
// current font
- private Font font;
+ private Font font = DEFAULT_FONT;
// the JLabel for drawing
private JLabel draw;
@@ -230,7 +298,10 @@ public final class Draw implements ActionListener, MouseListener, MouseMotionLis
private Graphics2D offscreen, onscreen;
// the frame for drawing to the screen
- private JFrame frame = new JFrame();
+ private JFrame frame;
+
+ // is the JFrame visible (upon calling draw())?
+ private static boolean isJFrameVisible = true;
// mouse state
private boolean isMousePressed = false;
@@ -244,68 +315,86 @@ public final class Draw implements ActionListener, MouseListener, MouseMotionLis
// event-based listeners
private final ArrayList
+ * @param callsPerSecond calls per second
+ */
+ public void enableTimer(int callsPerSecond) {
+ disableTimer();
+ timer = new Timer();
+ timer.schedule(new MyTimerTask(), 0, (int) Math.round(1000.0 / callsPerSecond));
+ }
+ public void disableTimer() {
+ if (timer != null) timer.cancel();
+ }
+ private class MyTimerTask extends TimerTask {
+ public void run() {
+ for (DrawListener listener : listeners)
+ listener.update();
+ }
+ }
+
+ /***************************************************************************
+ * For improved resolution on Mac Retina displays.
+ ***************************************************************************/
+
+ private static class RetinaImageIcon extends ImageIcon {
+
+ public RetinaImageIcon(Image image) {
+ super(image);
+ }
+
+ public int getIconWidth() {
+ return super.getIconWidth() / 2;
+ }
+
+ /**
+ * Returns the height of the icon.
+ *
+ * @return the height in pixels of this icon
+ */
+ public int getIconHeight() {
+ return super.getIconHeight() / 2;
+ }
+
+ public synchronized void paintIcon(Component c, Graphics g, int x, int y) {
+ Graphics2D g2 = (Graphics2D) g.create();
+ g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
+ g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
+ g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+ g2.scale(0.5, 0.5);
+ super.paintIcon(c, g2, x * 2, y * 2);
+ g2.dispose();
+ }
+ }
/**
* Test client.
@@ -1398,36 +1851,38 @@ public void keyReleased(KeyEvent e) {
public static void main(String[] args) {
// create one drawing window
- Draw draw1 = new Draw("Test client 1");
- draw1.square(.2, .8, .1);
- draw1.filledSquare(.8, .8, .2);
- draw1.circle(.8, .2, .2);
+ Draw draw1 = new Draw();
+ draw1.setTitle("Test client 1");
+ draw1.square(0.2, 0.8, 0.1);
+ draw1.filledSquare(0.8, 0.8, 0.2);
+ draw1.circle(0.8, 0.2, 0.2);
draw1.setPenColor(Draw.MAGENTA);
- draw1.setPenRadius(.02);
- draw1.arc(.8, .2, .1, 200, 45);
+ draw1.setPenRadius(0.02);
+ draw1.arc(0.8, 0.2, 0.1, 200, 45);
// create another one
- Draw draw2 = new Draw("Test client 2");
+ Draw draw2 = new Draw();
draw2.setCanvasSize(900, 200);
+ draw2.setTitle("Test client 2");
// draw a blue diamond
draw2.setPenRadius();
draw2.setPenColor(Draw.BLUE);
- double[] x = { .1, .2, .3, .2 };
- double[] y = { .2, .3, .2, .1 };
+ double[] x = { 0.1, 0.2, 0.3, 0.2 };
+ double[] y = { 0.2, 0.3, 0.2, 0.1 };
draw2.filledPolygon(x, y);
// text
draw2.setPenColor(Draw.BLACK);
- draw2.text(0.2, 0.5, "bdfdfdfdlack text");
+ draw2.text(0.2, 0.5, "black text");
draw2.setPenColor(Draw.WHITE);
- draw2.text(0.8, 0.8, "white text");
+ draw2.text(0.2, 0.2, "white text");
}
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/DrawListener.java b/src/main/java/edu/princeton/cs/algs4/DrawListener.java
index 3cfc4f4d8..fdd2468b2 100644
--- a/src/main/java/edu/princeton/cs/algs4/DrawListener.java
+++ b/src/main/java/edu/princeton/cs/algs4/DrawListener.java
@@ -8,6 +8,22 @@
package edu.princeton.cs.algs4;
+/**
+ * The
+ * For additional documentation, see
+ * Section 3.1 of
+ * Computer Science: An Interdisciplinary Approach
+ * by Robert Sedgewick and Kevin Wayne.
+ *
+ * @author Robert Sedgewick
+ * @author Kevin Wayne
+ */
+
public interface DrawListener {
/**
@@ -16,7 +32,9 @@ public interface DrawListener {
* @param x the x-coordinate of the mouse
* @param y the y-coordinate of the mouse
*/
- void mousePressed(double x, double y);
+ default void mousePressed(double x, double y) {
+ // does nothing by default
+ }
/**
* Invoked when the mouse has been dragged.
@@ -24,7 +42,9 @@ public interface DrawListener {
* @param x the x-coordinate of the mouse
* @param y the y-coordinate of the mouse
*/
- void mouseDragged(double x, double y);
+ default void mouseDragged(double x, double y) {
+ // does nothing by default
+ }
/**
* Invoked when the mouse has been released.
@@ -32,32 +52,63 @@ public interface DrawListener {
* @param x the x-coordinate of the mouse
* @param y the y-coordinate of the mouse
*/
- void mouseReleased(double x, double y);
+ default void mouseReleased(double x, double y) {
+ // does nothing by default
+ }
+
+ /**
+ * Invoked when the mouse has been clicked (pressed and released).
+ * A mouse click is triggered only if the user presses a mouse button
+ * and then releases it quickly, without moving the mouse.
+ * It does not work with touch events.
+ * The {@link mousePressed} method is generally preferred for
+ * detecting mouse clicks.
+ *
+ * @param x the x-coordinate of the mouse
+ * @param y the y-coordinate of the mouse
+ */
+ default void mouseClicked(double x, double y) {
+ // does nothing by default
+ }
/**
* Invoked when a key has been typed.
*
* @param c the character typed
*/
- void keyTyped(char c);
+ default void keyTyped(char c) {
+ // does nothing by default
+ }
/**
* Invoked when a key has been pressed.
*
* @param keycode the key combination pressed
*/
- void keyPressed(int keycode);
+ default void keyPressed(int keycode) {
+ // does nothing by default
+ }
/**
* Invoked when a key has been released.
*
* @param keycode the key combination released
*/
- void keyReleased(int keycode);
+ default void keyReleased(int keycode) {
+ // does nothing by default
+ }
+
+ /**
+ * Gets called at regular time intervals.
+ */
+ default void update() {
+ // does nothing by default
+ }
+
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/Edge.java b/src/main/java/edu/princeton/cs/algs4/Edge.java
index 984f3b87b..3983530c9 100644
--- a/src/main/java/edu/princeton/cs/algs4/Edge.java
+++ b/src/main/java/edu/princeton/cs/algs4/Edge.java
@@ -10,7 +10,7 @@
package edu.princeton.cs.algs4;
/**
- * The {@code Edge} class represents a weighted edge in an
+ * The {@code Edge} class represents a weighted edge in an
* {@link EdgeWeightedGraph}. Each edge consists of two integers
* (naming the two vertices) and a real-value weight. The data type
* provides methods for accessing the two endpoints of the edge and
@@ -23,7 +23,7 @@
* @author Robert Sedgewick
* @author Kevin Wayne
*/
-public class Edge implements Comparable
- * This implementation uses an adjacency-lists representation, which
+ * This implementation uses an adjacency-lists representation, which
* is a vertex-indexed array of {@link Bag} objects.
- * All operations take constant time (in the worst case) except
- * iterating over the edges incident from a given vertex, which takes
- * time proportional to the number of such edges.
+ * It uses Θ(E + V) space, where E is
+ * the number of edges and V is the number of vertices.
+ * All instance methods take Θ(1) time. (Though, iterating over
+ * the edges returned by {@link #adj(int)} takes time proportional
+ * to the outdegree of the vertex.)
+ * Constructing an empty edge-weighted digraph with V vertices
+ * takes Θ(V) time; constructing an edge-weighted digraph
+ * with E edges and V vertices takes
+ * Θ(E + V) time.
*
* For additional documentation,
* see Section 4.4 of
@@ -42,7 +51,7 @@ public class EdgeWeightedDigraph {
private int E; // number of edges in this digraph
private Bag
- * This implementation uses depth-first search.
- * The constructor takes time proportional to V + E
- * (in the worst case),
- * where V is the number of vertices and E is the number of edges.
- * Afterwards, the hasCycle operation takes constant time;
- * the cycle operation takes time proportional
- * to the length of the cycle.
+ * This implementation uses depth-first search.
+ * The constructor takes Θ(V + E) time in the
+ * worst case, where V is the number of vertices and
+ * E is the number of edges.
+ * Each instance method takes Θ(1) time.
+ * It uses Θ(V) extra space (not including the
+ * edge-weighted digraph).
*
- * See {@link Topological} to compute a topological order if the edge-weighted
- * digraph is acyclic.
+ * See {@link Topological} to compute a topological order if the
+ * edge-weighted digraph is acyclic.
*
- * For additional documentation,
- * see Section 4.4 of
- * Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
+ * For additional documentation,
+ * see Section 4.4 of
+ * Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
@@ -130,6 +130,13 @@ private boolean check() {
last = e;
}
+ // cycle() contains no edges
+ if (first == null || last == null) {
+ System.err.printf("cycle contains no edges\n");
+ return false;
+ }
+
+ // first and last edges in cycle are not incident
if (last.to() != first.from()) {
System.err.printf("cycle edges %s and %s not incident\n", last, first);
return false;
@@ -159,18 +166,18 @@ public static void main(String[] args) {
for (int i = 0; i < E; i++) {
int v, w;
do {
- v = StdRandom.uniform(V);
- w = StdRandom.uniform(V);
+ v = StdRandom.uniformInt(V);
+ w = StdRandom.uniformInt(V);
} while (v >= w);
- double weight = StdRandom.uniform();
+ double weight = StdRandom.uniformDouble(0.0, 1.0);
G.addEdge(new DirectedEdge(v, w, weight));
}
// add F extra edges
for (int i = 0; i < F; i++) {
- int v = StdRandom.uniform(V);
- int w = StdRandom.uniform(V);
- double weight = StdRandom.uniform(0.0, 1.0);
+ int v = StdRandom.uniformInt(V);
+ int w = StdRandom.uniformInt(V);
+ double weight = StdRandom.uniformDouble(0.0, 1.0);
G.addEdge(new DirectedEdge(v, w, weight));
}
@@ -186,7 +193,7 @@ public static void main(String[] args) {
StdOut.println();
}
- // or give topologial sort
+ // or give topological sort
else {
StdOut.println("No directed cycle");
}
@@ -195,7 +202,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/EdgeWeightedGraph.java b/src/main/java/edu/princeton/cs/algs4/EdgeWeightedGraph.java
index 99de0e21b..5c74ee718 100644
--- a/src/main/java/edu/princeton/cs/algs4/EdgeWeightedGraph.java
+++ b/src/main/java/edu/princeton/cs/algs4/EdgeWeightedGraph.java
@@ -9,14 +9,14 @@
* An edge-weighted undirected graph, implemented using adjacency lists.
* Parallel edges and self-loops are permitted.
*
- * % java EdgeWeightedGraph tinyEWG.txt
+ * % java EdgeWeightedGraph tinyEWG.txt
* 8 16
- * 0: 6-0 0.58000 0-2 0.26000 0-4 0.38000 0-7 0.16000
- * 1: 1-3 0.29000 1-2 0.36000 1-7 0.19000 1-5 0.32000
- * 2: 6-2 0.40000 2-7 0.34000 1-2 0.36000 0-2 0.26000 2-3 0.17000
- * 3: 3-6 0.52000 1-3 0.29000 2-3 0.17000
- * 4: 6-4 0.93000 0-4 0.38000 4-7 0.37000 4-5 0.35000
- * 5: 1-5 0.32000 5-7 0.28000 4-5 0.35000
+ * 0: 6-0 0.58000 0-2 0.26000 0-4 0.38000 0-7 0.16000
+ * 1: 1-3 0.29000 1-2 0.36000 1-7 0.19000 1-5 0.32000
+ * 2: 6-2 0.40000 2-7 0.34000 1-2 0.36000 0-2 0.26000 2-3 0.17000
+ * 3: 3-6 0.52000 1-3 0.29000 2-3 0.17000
+ * 4: 6-4 0.93000 0-4 0.38000 4-7 0.37000 4-5 0.35000
+ * 5: 1-5 0.32000 5-7 0.28000 4-5 0.35000
* 6: 6-4 0.93000 6-0 0.58000 3-6 0.52000 6-2 0.40000
* 7: 2-7 0.34000 1-7 0.19000 0-7 0.16000 5-7 0.28000 4-7 0.37000
*
@@ -24,23 +24,32 @@
package edu.princeton.cs.algs4;
+import java.util.NoSuchElementException;
+
/**
* The {@code EdgeWeightedGraph} class represents an edge-weighted
* graph of vertices named 0 through V – 1, where each
* undirected edge is of type {@link Edge} and has a real-valued weight.
* It supports the following two primary operations: add an edge to the graph,
* iterate over all of the edges incident to a vertex. It also provides
- * methods for returning the number of vertices V and the number
- * of edges E. Parallel edges and self-loops are permitted.
+ * methods for returning the degree of a vertex, the number of vertices
+ * V in the graph, and the number of edges E in the graph.
+ * Parallel edges and self-loops are permitted.
* By convention, a self-loop v-v appears in the
* adjacency list of v twice and contributes two to the degree
* of v.
*
- * This implementation uses an adjacency-lists representation, which
+ * This implementation uses an adjacency-lists representation, which
* is a vertex-indexed array of {@link Bag} objects.
- * All operations take constant time (in the worst case) except
- * iterating over the edges incident to a given vertex, which takes
- * time proportional to the number of such edges.
+ * It uses Θ(E + V) space, where E is
+ * the number of edges and V is the number of vertices.
+ * All instance methods take Θ(1) time. (Though, iterating over
+ * the edges returned by {@link #adj(int)} takes time proportional
+ * to the degree of the vertex.)
+ * Constructing an empty edge-weighted graph with V vertices takes
+ * Θ(V) time; constructing an edge-weighted graph with
+ * E edges and V vertices takes
+ * Θ(E + V) time.
*
* For additional documentation,
* see Section 4.3 of
@@ -55,7 +64,7 @@ public class EdgeWeightedGraph {
private final int V;
private int E;
private Bag
* This implementation uses a nonrecursive depth-first search.
- * The constructor runs in O(E + V) time,
- * and uses O(E + V) extra space, where E is the
- * number of edges and V the number of vertices
- * All other methods take O(1) time.
+ * The constructor takes Θ(E + V) time in the worst
+ * case, where E is the number of edges and V is the
+ * number of vertices
+ * Each instance method takes Θ(1) time.
+ * It uses Θ(E + V) extra space in the worst case
+ * (not including the graph).
*
* To compute Eulerian paths in graphs, see {@link EulerianPath}.
* To compute Eulerian cycles and paths in digraphs, see
@@ -34,7 +36,7 @@
* For additional documentation,
* see Section 4.1 of
* Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
- *
+ *
* @author Robert Sedgewick
* @author Kevin Wayne
* @author Nate Liu
@@ -64,7 +66,7 @@ public int other(int vertex) {
/**
* Computes an Eulerian cycle in the specified graph, if one exists.
- *
+ *
* @param G the graph
*/
public EulerianCycle(Graph G) {
@@ -73,8 +75,8 @@ public EulerianCycle(Graph G) {
if (G.E() == 0) return;
// necessary condition: all vertices have even degree
- // (this test is needed or it might find an Eulerian path instead of cycle)
- for (int v = 0; v < G.V(); v++)
+ // (this test is needed, or it might find an Eulerian path instead of cycle)
+ for (int v = 0; v < G.V(); v++)
if (G.degree(v) % 2 != 0)
return;
@@ -133,7 +135,7 @@ else if (v < w) {
/**
* Returns the sequence of vertices on an Eulerian cycle.
- *
+ *
* @return the sequence of vertices on an Eulerian cycle;
* {@code null} if no such cycle
*/
@@ -143,7 +145,7 @@ public Iterable
* This implementation uses a nonrecursive depth-first search.
- * The constructor runs in O(E + V) time,
- * and uses O(E + V) extra space,
- * where E is the number of edges and V the number of vertices
- * All other methods take O(1) time.
+ * The constructor takes Θ(E + V) time in the worst
+ * case, where E is the number of edges and V is
+ * the number of vertices.
+ * Each instance method takes Θ(1) time.
+ * It uses Θ(E + V) extra space in the worst case
+ * (not including the digraph).
*
* To compute Eulerian cycles in graphs, see {@link EulerianCycle}.
* To compute Eulerian cycles and paths in digraphs, see
@@ -28,7 +30,7 @@
* For additional documentation,
* see Section 4.1 of
* Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
- *
+ *
* @author Robert Sedgewick
* @author Kevin Wayne
* @author Nate Liu
@@ -58,7 +60,7 @@ public int other(int vertex) {
/**
* Computes an Eulerian path in the specified graph, if one exists.
- *
+ *
* @param G the graph
*/
public EulerianPath(Graph G) {
@@ -136,7 +138,7 @@ else if (v < w) {
/**
* Returns the sequence of vertices on an Eulerian path.
- *
+ *
* @return the sequence of vertices on an Eulerian path;
* {@code null} if no such path
*/
@@ -146,7 +148,7 @@ public Iterable
@@ -71,11 +71,16 @@
* n must be a power of 2.
* Our goal is to optimize the clarity of the code, rather than performance.
* It is not the most memory efficient implementation because it uses
- * objects to represents complex numbers and it it re-allocates memory
- * for the subarray, instead of doing in-place or reusing a single temporary array.
- *
+ * objects to represent complex numbers and it re-allocates memory
+ * for the subarray, instead of doing in-place or reusing a single
+ * temporary array.
+ *
+ * This computes correct results if all arithmetic performed is
+ * without floating-point rounding error or arithmetic overflow.
+ * In practice, there will be floating-point rounding error.
*
- * For additional documentation, see Section 9.9 of
+ * For additional documentation,
+ * see Section 9.9 of
* Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
*
* @author Robert Sedgewick
@@ -116,7 +121,7 @@ public static Complex[] fft(Complex[] x) {
Complex[] q = fft(even);
// fft of odd terms
- Complex[] odd = even; // reuse the array
+ Complex[] odd = even; // reuse the array
for (int k = 0; k < n/2; k++) {
odd[k] = x[2*k + 1];
}
@@ -245,14 +250,14 @@ private static void show(Complex[] x, String title) {
*
* @param args the command-line arguments
*/
- public static void main(String[] args) {
+ public static void main(String[] args) {
int n = Integer.parseInt(args[0]);
Complex[] x = new Complex[n];
// original data
for (int i = 0; i < n; i++) {
x[i] = new Complex(i, 0);
- x[i] = new Complex(StdRandom.uniform(-1.0, 1.0), 0);
+ x[i] = new Complex(StdRandom.uniformDouble(-1.0, 1.0), 0);
}
show(x, "x");
@@ -276,7 +281,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/FarthestPair.java b/src/main/java/edu/princeton/cs/algs4/FarthestPair.java
index b6b45e8c5..e5f21c2b1 100644
--- a/src/main/java/edu/princeton/cs/algs4/FarthestPair.java
+++ b/src/main/java/edu/princeton/cs/algs4/FarthestPair.java
@@ -4,7 +4,7 @@
* Dependencies: GrahamScan.java Point2D.java
* Data files: https://algs4.cs.princeton.edu/99hull/rs1423.txt
* https://algs4.cs.princeton.edu/99hull/kw1260.txt
- *
+ *
* Given a set of n points in the plane, find the farthest pair
* (equivalently, compute the diameter of the set of points).
*
@@ -134,7 +134,7 @@ public Point2D other() {
}
/**
- * Returns the Eucliden distance between the farthest pair of points.
+ * Returns the Euclidean distance between the farthest pair of points.
* This quantity is also known as the diameter of the set of points.
*
* @return the Euclidean distance between the farthest pair of points
@@ -169,7 +169,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/FenwickTree.java b/src/main/java/edu/princeton/cs/algs4/FenwickTree.java
index ae7f92877..abf5f3fc5 100644
--- a/src/main/java/edu/princeton/cs/algs4/FenwickTree.java
+++ b/src/main/java/edu/princeton/cs/algs4/FenwickTree.java
@@ -188,7 +188,7 @@ else if (line[0].equals("rsq")) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/FibonacciMinPQ.java b/src/main/java/edu/princeton/cs/algs4/FibonacciMinPQ.java
index a846194ea..85b22ff12 100644
--- a/src/main/java/edu/princeton/cs/algs4/FibonacciMinPQ.java
+++ b/src/main/java/edu/princeton/cs/algs4/FibonacciMinPQ.java
@@ -27,6 +27,8 @@
* The delete-the-minimum operation takes amortized logarithmic time.
* The insert, min-key, is-empty, size, union and constructor take constant time.
*
+ * WARNING: THIS VERSION HAS AT LEAST ONE BUG.
+ *
* @author Tristan Claverie
*/
public class FibonacciMinPQ
* For additional documentation, see Section 3.5 of
* Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
- *
+ *
* @author Robert Sedgewick
* @author Kevin Wayne
*/
-public class FileIndex {
+public class FileIndex {
// Do not instantiate.
private FileIndex() { }
@@ -81,7 +81,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/FlowEdge.java b/src/main/java/edu/princeton/cs/algs4/FlowEdge.java
index 9d325f9f8..8624cf22c 100644
--- a/src/main/java/edu/princeton/cs/algs4/FlowEdge.java
+++ b/src/main/java/edu/princeton/cs/algs4/FlowEdge.java
@@ -10,7 +10,7 @@
package edu.princeton.cs.algs4;
/**
- * The {@code FlowEdge} class represents a capacitated edge with a
+ * The {@code FlowEdge} class represents a capacitated edge with a
* flow in a {@link FlowNetwork}. Each edge consists of two integers
* (naming the two vertices), a real-valued capacity, and a real-valued
* flow. The data type provides methods for accessing the two endpoints
@@ -26,10 +26,10 @@
*/
public class FlowEdge {
// to deal with floating-point roundoff errors
- private static final double FLOATING_POINT_EPSILON = 1E-10;
+ private static final double FLOATING_POINT_EPSILON = 1.0E-10;
private final int v; // from
- private final int w; // to
+ private final int w; // to
private final double capacity; // capacity
private double flow; // flow
@@ -48,7 +48,7 @@ public FlowEdge(int v, int w, double capacity) {
if (w < 0) throw new IllegalArgumentException("vertex index must be a non-negative integer");
if (!(capacity >= 0.0)) throw new IllegalArgumentException("Edge capacity must be non-negative");
this.v = v;
- this.w = w;
+ this.w = w;
this.capacity = capacity;
this.flow = 0.0;
}
@@ -63,7 +63,7 @@ public FlowEdge(int v, int w, double capacity) {
* @throws IllegalArgumentException if either {@code v} or {@code w}
* is a negative integer
* @throws IllegalArgumentException if {@code capacity} is negative
- * @throws IllegalArgumentException unless {@code flow} is between
+ * @throws IllegalArgumentException unless {@code flow} is between
* {@code 0.0} and {@code capacity}.
*/
public FlowEdge(int v, int w, double capacity, double flow) {
@@ -73,7 +73,7 @@ public FlowEdge(int v, int w, double capacity, double flow) {
if (!(flow <= capacity)) throw new IllegalArgumentException("flow exceeds capacity");
if (!(flow >= 0.0)) throw new IllegalArgumentException("flow must be non-negative");
this.v = v;
- this.w = w;
+ this.w = w;
this.capacity = capacity;
this.flow = flow;
}
@@ -95,7 +95,7 @@ public FlowEdge(FlowEdge e) {
*/
public int from() {
return v;
- }
+ }
/**
* Returns the head vertex of the edge.
@@ -103,7 +103,7 @@ public int from() {
*/
public int to() {
return w;
- }
+ }
/**
* Returns the capacity of the edge.
@@ -154,18 +154,18 @@ public double residualCapacityTo(int vertex) {
/**
* Increases the flow on the edge in the direction to the given vertex.
- * If {@code vertex} is the tail vertex, this increases the flow on the edge by {@code delta};
- * if {@code vertex} is the head vertex, this decreases the flow on the edge by {@code delta}.
+ * If {@code vertex} is the tail vertex, this increases the flow on the edge by {@code delta};
+ * if {@code vertex} is the head vertex, this decreases the flow on the edge by {@code delta}.
* @param vertex one endpoint of the edge
* @param delta amount by which to increase flow
* @throws IllegalArgumentException if {@code vertex} is not one of the endpoints
- * of the edge
- * @throws IllegalArgumentException if {@code delta} makes the flow on
- * on the edge either negative or larger than its capacity
+ * of the edge
+ * @throws IllegalArgumentException if {@code delta} makes the flow
+ * on the edge either negative or larger than its capacity
* @throws IllegalArgumentException if {@code delta} is {@code NaN}
*/
public void addResidualFlowTo(int vertex, double delta) {
- if (!(delta >= 0.0)) throw new IllegalArgumentException("Delta must be nonnegative");
+ if (!(delta >= 0.0)) throw new IllegalArgumentException("Delta must be non-negative");
if (vertex == v) flow -= delta; // backward edge
else if (vertex == w) flow += delta; // forward edge
@@ -204,7 +204,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/FlowNetwork.java b/src/main/java/edu/princeton/cs/algs4/FlowNetwork.java
index b4d767c27..bc7f1378f 100644
--- a/src/main/java/edu/princeton/cs/algs4/FlowNetwork.java
+++ b/src/main/java/edu/princeton/cs/algs4/FlowNetwork.java
@@ -20,7 +20,7 @@
* methods for returning the number of vertices V and the number
* of edges E. Parallel edges and self-loops are permitted.
*
- * This implementation uses an adjacency-lists representation, which
+ * This implementation uses an adjacency-lists representation, which
* is a vertex-indexed array of {@link Bag} objects.
* All operations take constant time (in the worst case) except
* iterating over the edges incident to a given vertex, which takes
@@ -39,14 +39,14 @@ public class FlowNetwork {
private final int V;
private int E;
private Bag
* This implementation uses the Floyd-Warshall algorithm.
- * The constructor takes time proportional to V3 in the
- * worst case, where V is the number of vertices.
- * Afterwards, the {@code dist()}, {@code hasPath()}, and {@code hasNegativeCycle()}
- * methods take constant time; the {@code path()} and {@code negativeCycle()}
- * method takes time proportional to the number of edges returned.
+ * The constructor takes Θ(V3) time,
+ * where V is the number of vertices.
+ * Each instance method takes Θ(1) time.
+ * It uses Θ(V2) extra space
+ * (not including the edge-weighted digraph).
*
- * For additional documentation,
- * see Section 4.4 of
- * Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
+ * This correctly computes shortest paths if all arithmetic performed is
+ * without floating-point rounding error or arithmetic overflow.
+ * This is the case if all edge weights are integers and if none of the
+ * intermediate results exceeds 252. Since all intermediate
+ * results are sums of edge weights, they are bounded by V C,
+ * where V is the number of vertices and C is the maximum
+ * absolute value of any edge weight.
+ *
+ * For additional documentation,
+ * see Section 4.4 of
+ * Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
@@ -45,7 +53,7 @@ public class FloydWarshall {
private DirectedEdge[][] edgeTo; // edgeTo[v][w] = last edge on shortest v->w path
/**
- * Computes a shortest paths tree from each vertex to to every other vertex in
+ * Computes a shortest paths tree from each vertex to every other vertex in
* the edge-weighted digraph {@code G}. If no such shortest path exists for
* some pair of vertices, it computes a negative cycle.
* @param G the edge-weighted digraph
@@ -219,9 +227,9 @@ public static void main(String[] args) {
int E = Integer.parseInt(args[1]);
AdjMatrixEdgeWeightedDigraph G = new AdjMatrixEdgeWeightedDigraph(V);
for (int i = 0; i < E; i++) {
- int v = StdRandom.uniform(V);
- int w = StdRandom.uniform(V);
- double weight = Math.round(100 * (StdRandom.uniform() - 0.15)) / 100.0;
+ int v = StdRandom.uniformInt(V);
+ int w = StdRandom.uniformInt(V);
+ double weight = 0.01 * StdRandom.uniformInt(-15, 100);
if (v == w) G.addEdge(new DirectedEdge(v, w, Math.abs(weight)));
else G.addEdge(new DirectedEdge(v, w, weight));
}
@@ -276,7 +284,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/FordFulkerson.java b/src/main/java/edu/princeton/cs/algs4/FordFulkerson.java
index 0d9287d70..304aed9f1 100644
--- a/src/main/java/edu/princeton/cs/algs4/FordFulkerson.java
+++ b/src/main/java/edu/princeton/cs/algs4/FordFulkerson.java
@@ -4,7 +4,7 @@
* Dependencies: FlowNetwork.java FlowEdge.java Queue.java
* Data files: https://algs4.cs.princeton.edu/65maxflow/tinyFN.txt
*
- * Ford-Fulkerson algorithm for computing a max flow and
+ * Ford-Fulkerson algorithm for computing a max flow and
* a min cut using shortest augmenting path rule.
*
******************************************************************************/
@@ -18,34 +18,33 @@
*
* This implementation uses the Ford-Fulkerson algorithm with
* the shortest augmenting path heuristic.
- * The constructor takes time proportional to E V (E + V)
- * in the worst case and extra space (not including the network)
- * proportional to V, where V is the number of vertices
- * and E is the number of edges. In practice, the algorithm will
- * run much faster.
- * Afterwards, the {@code inCut()} and {@code value()} methods take
- * constant time.
+ * The constructor takes O(E V (E + V))
+ * time, where V is the number of vertices and E is
+ * the number of edges. In practice, the algorithm will run much faster.
+ * The {@code inCut()} and {@code value()} methods take Θ(1) time.
+ * It uses Θ(V) extra space (not including the network).
*
- * If the capacities and initial flow values are all integers, then this
- * implementation guarantees to compute an integer-valued maximum flow.
- * If the capacities and floating-point numbers, then floating-point
- * roundoff error can accumulate.
+ * This correctly computes the maxflow and mincut if all arithmetic
+ * performed is without floating-point rounding error or arithmetic
+ * overflow. This is guaranteed to be the case if all edge capacities
+ * and initial flow values are integers and the value of the maxflow
+ * does not exceed 252.
*
- * For additional documentation,
- * see Section 6.4 of
+ * For additional documentation, see
+ * Section 6.4 of
* Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class FordFulkerson {
- private static final double FLOATING_POINT_EPSILON = 1E-11;
+ private static final double FLOATING_POINT_EPSILON = 1.0E-11;
private final int V; // number of vertices
private boolean[] marked; // marked[v] = true iff s->v path in residual graph
private FlowEdge[] edgeTo; // edgeTo[v] = last edge on shortest residual s->v path
private double value; // current value of max flow
-
+
/**
* Compute a maximum flow and minimum cut in the network {@code G}
* from vertex {@code s} to vertex {@code t}.
@@ -77,7 +76,7 @@ public FordFulkerson(FlowNetwork G, int s, int t) {
// augment flow
for (int v = t; v != s; v = edgeTo[v].other(v)) {
- edgeTo[v].addResidualFlowTo(v, bottle);
+ edgeTo[v].addResidualFlowTo(v, bottle);
}
value += bottle;
@@ -100,7 +99,7 @@ public double value() {
* Returns true if the specified vertex is on the {@code s} side of the mincut.
*
* @param v vertex
- * @return {@code true} if vertex {@code v} is on the {@code s} side of the micut;
+ * @return {@code true} if vertex {@code v} is on the {@code s} side of the mincut;
* {@code false} otherwise
* @throws IllegalArgumentException unless {@code 0 <= v < V}
*/
@@ -109,14 +108,14 @@ public boolean inCut(int v) {
return marked[v];
}
- // throw an IllegalArgumentException if v is outside prescibed range
+ // throw an IllegalArgumentException if v is outside prescribed range
private void validate(int v) {
if (v < 0 || v >= V)
throw new IllegalArgumentException("vertex " + v + " is not between 0 and " + (V-1));
}
- // is there an augmenting path?
+ // is there an augmenting path?
// if so, upon termination edgeTo[] will contain a parent-link representation of such a path
// this implementation finds a shortest augmenting path (fewest number of edges),
// which performs well both in theory and in practice
@@ -271,7 +270,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/FrequencyCounter.java b/src/main/java/edu/princeton/cs/algs4/FrequencyCounter.java
index df02efd38..1db88fc0f 100644
--- a/src/main/java/edu/princeton/cs/algs4/FrequencyCounter.java
+++ b/src/main/java/edu/princeton/cs/algs4/FrequencyCounter.java
@@ -2,7 +2,7 @@
* Compilation: javac FrequencyCounter.java
* Execution: java FrequencyCounter L < input.txt
* Dependencies: ST.java StdIn.java StdOut.java
- * Data files: https://algs4.cs.princeton.edu/31elementary/tnyTale.txt
+ * Data files: https://algs4.cs.princeton.edu/31elementary/tinyTale.txt
* https://algs4.cs.princeton.edu/31elementary/tale.txt
* https://algs4.cs.princeton.edu/31elementary/leipzig100K.txt
* https://algs4.cs.princeton.edu/31elementary/leipzig300K.txt
@@ -27,7 +27,7 @@
package edu.princeton.cs.algs4;
/**
- * The {@code FrequencyCounter} class provides a client for
+ * The {@code FrequencyCounter} class provides a client for
* reading in a sequence of words and printing a word (exceeding
* a given length) that occurs most frequently. It is useful as
* a test client for various symbol table implementations.
@@ -86,7 +86,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/GREP.java b/src/main/java/edu/princeton/cs/algs4/GREP.java
index d93989f58..52b21a41b 100644
--- a/src/main/java/edu/princeton/cs/algs4/GREP.java
+++ b/src/main/java/edu/princeton/cs/algs4/GREP.java
@@ -6,7 +6,7 @@
*
* This program takes an RE as a command-line argument and prints
* the lines from standard input having some substring that
- * is in the language described by the RE.
+ * is in the language described by the RE.
*
* % more tinyL.txt
* AC
@@ -52,20 +52,20 @@ private GREP() { }
*
* @param args the command-line arguments
*/
- public static void main(String[] args) {
+ public static void main(String[] args) {
String regexp = "(.*" + args[0] + ".*)";
NFA nfa = new NFA(regexp);
- while (StdIn.hasNextLine()) {
+ while (StdIn.hasNextLine()) {
String line = StdIn.readLine();
if (nfa.recognizes(line)) {
StdOut.println(line);
}
}
- }
-}
+ }
+}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/GabowSCC.java b/src/main/java/edu/princeton/cs/algs4/GabowSCC.java
index 83aa455c7..75e85ef99 100644
--- a/src/main/java/edu/princeton/cs/algs4/GabowSCC.java
+++ b/src/main/java/edu/princeton/cs/algs4/GabowSCC.java
@@ -6,43 +6,43 @@
* https://algs4.cs.princeton.edu/42digraph/mediumDG.txt
* https://algs4.cs.princeton.edu/42digraph/largeDG.txt
*
- * Compute the strongly-connected components of a digraph using
+ * Compute the strongly-connected components of a digraph using
* Gabow's algorithm (aka Cheriyan-Mehlhorn algorithm).
*
* Runs in O(E + V) time.
*
* % java GabowSCC tinyDG.txt
* 5 components
- * 1
+ * 1
* 0 2 3 4 5
* 9 10 11 12
* 6 8
- * 7
+ * 7
*
******************************************************************************/
package edu.princeton.cs.algs4;
/**
- * The {@code GabowSCC} class represents a data type for
+ * The {@code GabowSCC} class represents a data type for
* determining the strong components in a digraph.
* The id operation determines in which strong component
* a given vertex lies; the areStronglyConnected operation
* determines whether two vertices are in the same strong component;
* and the count operation determines the number of strong
* components.
-
- * The component identifier of a component is one of the
- * vertices in the strong component: two vertices have the same component
- * identifier if and only if they are in the same strong component.
-
+ *
+ * The component identifier of a vertex is an integer between
+ * 0 and k–1, where k is the number of strong components.
+ * Two vertices have the same component identifier if and only if they
+ * are in the same strong component.
*
* This implementation uses the Gabow's algorithm.
- * The constructor takes time proportional to V + E
- * (in the worst case),
- * where V is the number of vertices and E is the number of edges.
- * Afterwards, the id, count, and areStronglyConnected
- * operations take constant time.
- * For alternate implementations of the same API, see
+ * The constructor takes Θ(V + E) time,
+ * where V is the number of vertices and E is
+ * the number of edges.
+ * Each instance method takes Θ(1) time.
+ * It uses Θ(V) extra space (not including the digraph).
+ * For alternative implementations of the same API, see
* {@link KosarajuSharirSCC} and {@link TarjanSCC}.
*
* For additional documentation,
@@ -71,7 +71,7 @@ public GabowSCC(Digraph G) {
marked = new boolean[G.V()];
stack1 = new Stack
* This implementation uses Gauss-Jordan elimination with partial pivoting.
* See {@link GaussianElimination} for an implementation that uses
* Gaussian elimination (but does not provide the certificate of infeasibility).
* For an industrial-strength numerical linear algebra library,
- * see JAMA.
+ * see JAMA.
+ *
+ * This computes correct results if all arithmetic performed is
+ * without floating-point rounding error or arithmetic overflow.
+ * In practice, there will be floating-point rounding error;
+ * partial pivoting helps prevent accumulated floating-point rounding
+ * errors from growing out of control (though it does not
+ * provide any guarantees).
*
* For additional documentation, see
* Section 9.9
@@ -153,7 +160,7 @@ private void pivot(int p, int q) {
/**
* Returns a solution to the linear system of equations Ax = b.
- *
+ *
* @return a solution x to the linear system of equations
* Ax = b; {@code null} if no such solution
*/
@@ -171,7 +178,7 @@ else if (Math.abs(a[i][n+n]) > EPSILON)
/**
* Returns a solution to the linear system of equations yA = 0,
* yb ≠ 0.
- *
+ *
* @return a solution y to the linear system of equations
* yA = 0, yb ≠ 0; {@code null} if no such solution
*/
@@ -190,7 +197,7 @@ public double[] dual() {
/**
* Returns true if there exists a solution to the linear system of
* equations Ax = b.
- *
+ *
* @return {@code true} if there exists a solution to the linear system
* of equations Ax = b; {@code false} otherwise
*/
@@ -322,7 +329,7 @@ private static void test3() {
test("test 3", A, b);
}
- // 5-by-5 singluar: infinitely many solutions
+ // 5-by-5 singular: infinitely many solutions
private static void test4() {
double[][] A = {
{ 2, -3, -1, 2, 3 },
@@ -377,10 +384,10 @@ public static void main(String[] args) {
double[][] A = new double[n][n];
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
- A[i][j] = StdRandom.uniform(1000);
+ A[i][j] = StdRandom.uniformInt(1000);
double[] b = new double[n];
for (int i = 0; i < n; i++)
- b[i] = StdRandom.uniform(1000);
+ b[i] = StdRandom.uniformInt(1000);
test("random " + n + "-by-" + n + " (likely full rank)", A, b);
@@ -388,23 +395,23 @@ public static void main(String[] args) {
A = new double[n][n];
for (int i = 0; i < n-1; i++)
for (int j = 0; j < n; j++)
- A[i][j] = StdRandom.uniform(1000);
+ A[i][j] = StdRandom.uniformInt(1000);
for (int i = 0; i < n-1; i++) {
- double alpha = StdRandom.uniform(11) - 5.0;
+ double alpha = StdRandom.uniformInt(-5, 5);
for (int j = 0; j < n; j++) {
A[n-1][j] += alpha * A[i][j];
}
}
b = new double[n];
for (int i = 0; i < n; i++)
- b[i] = StdRandom.uniform(1000);
+ b[i] = StdRandom.uniformInt(1000);
test("random " + n + "-by-" + n + " (likely infeasible)", A, b);
}
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/GaussianElimination.java b/src/main/java/edu/princeton/cs/algs4/GaussianElimination.java
index 62fd2d6d5..7fb58e7a0 100644
--- a/src/main/java/edu/princeton/cs/algs4/GaussianElimination.java
+++ b/src/main/java/edu/princeton/cs/algs4/GaussianElimination.java
@@ -2,7 +2,7 @@
* Compilation: javac GaussianElimination.java
* Execution: java GaussianElimination m n
* Dependencies: StdOut.java
- *
+ *
* Gaussian elimination with partial pivoting for m-by-n system.
*
* % java GaussianElimination m n
@@ -13,7 +13,7 @@
* 3.000000
* -1.000000
* -2.000000
- *
+ *
* System is infeasible
*
* -6.250000
@@ -47,6 +47,13 @@
* For an industrial-strength numerical linear algebra library,
* see JAMA.
*
+ * This computes correct results if all arithmetic performed is
+ * without floating-point rounding error or arithmetic overflow.
+ * In practice, there will be floating-point rounding error;
+ * partial pivoting helps prevent accumulated floating-point rounding
+ * errors from growing out of control (though it does not
+ * provide any guarantees).
+ *
* For additional documentation, see
* Section 9.9
* Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
@@ -55,7 +62,7 @@
* @author Kevin Wayne
*/
public class GaussianElimination {
- private static final double EPSILON = 1e-8;
+ private static final double EPSILON = 1.0E-8;
private final int m; // number of rows
private final int n; // number of columns
@@ -134,7 +141,7 @@ private void pivot(int p) {
/**
* Returns a solution to the linear system of equations Ax = b.
- *
+ *
* @return a solution x to the linear system of equations
* Ax = b; {@code null} if no such solution
*/
@@ -168,7 +175,7 @@ else if (Math.abs(a[i][n] - sum) > EPSILON)
/**
* Returns true if there exists a solution to the linear system of
* equations Ax = b.
- *
+ *
* @return {@code true} if there exists a solution to the linear system
* of equations Ax = b; {@code false} otherwise
*/
@@ -344,10 +351,10 @@ public static void main(String[] args) {
double[][] A = new double[n][n];
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
- A[i][j] = StdRandom.uniform(1000);
+ A[i][j] = StdRandom.uniformInt(1000);
double[] b = new double[n];
for (int i = 0; i < n; i++)
- b[i] = StdRandom.uniform(1000);
+ b[i] = StdRandom.uniformInt(1000);
test(n + "-by-" + n + " (probably nonsingular)", A, b);
}
@@ -355,7 +362,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/Genome.java b/src/main/java/edu/princeton/cs/algs4/Genome.java
index a1e11c0fe..a3ac4fabf 100644
--- a/src/main/java/edu/princeton/cs/algs4/Genome.java
+++ b/src/main/java/edu/princeton/cs/algs4/Genome.java
@@ -22,7 +22,7 @@
* and expanding a genomic sequence using a 2-bit code.
*
* For additional documentation,
- * see Section 5.5 of
+ * see Section 5.5 of
* Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
*
* @author Robert Sedgewick
@@ -38,19 +38,19 @@ private Genome() { }
* { A, C, T, G } from standard input; compresses them using two bits per
* character; and writes the results to standard output.
*/
- public static void compress() {
+ public static void compress() {
Alphabet DNA = Alphabet.DNA;
String s = BinaryStdIn.readString();
int n = s.length();
BinaryStdOut.write(n);
- // Write two-bit code for char.
+ // Write two-bit code for char.
for (int i = 0; i < n; i++) {
int d = DNA.toIndex(s.charAt(i));
BinaryStdOut.write(d, 2);
}
BinaryStdOut.close();
- }
+ }
/**
* Reads a binary sequence from standard input; converts each two bits
@@ -60,7 +60,7 @@ public static void compress() {
public static void expand() {
Alphabet DNA = Alphabet.DNA;
int n = BinaryStdIn.readInt();
- // Read two bits; write char.
+ // Read two bits; write char.
for (int i = 0; i < n; i++) {
char c = BinaryStdIn.readChar(2);
BinaryStdOut.write(DNA.toChar(c), 8);
@@ -84,7 +84,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/GlobalMincut.java b/src/main/java/edu/princeton/cs/algs4/GlobalMincut.java
index c65b88136..60f3387f2 100644
--- a/src/main/java/edu/princeton/cs/algs4/GlobalMincut.java
+++ b/src/main/java/edu/princeton/cs/algs4/GlobalMincut.java
@@ -1,20 +1,20 @@
/******************************************************************************
* Compilation: javac GlobalMincut.java
* Execution: java GlobalMincut filename.txt
- * Dependencies: EdgeWeightedGraph.java Edge.java UF.java
- * IndexMaxPQ.java FlowNetwork.java FlowEdge.java
+ * Dependencies: EdgeWeightedGraph.java Edge.java UF.java
+ * IndexMaxPQ.java FlowNetwork.java FlowEdge.java
* FordFulkerson.java In.java StdOut.java
* Data files: https://algs4.cs.princeton.edu/43mst/tinyEWG.txt
* https://algs4.cs.princeton.edu/43mst/mediumEWG.txt
*
* Computes a minimum cut using Stoer-Wagner's algorithm.
*
- * % java GlobalMincut tinyEWG.txt
- * Min cut: 5
+ * % java GlobalMincut tinyEWG.txt
+ * Min cut: 5
* Min cut weight = 0.9500000000000001
- *
- * % java GlobalMincut mediumEWG.txt
- * Min cut: 25 60 63 96 199 237
+ *
+ * % java GlobalMincut mediumEWG.txt
+ * Min cut: 25 60 63 96 199 237
* Min cut weight = 0.14021
*
******************************************************************************/
@@ -22,43 +22,33 @@
package edu.princeton.cs.algs4;
/**
- * The {@code GlobalMincut} class represents a data type for computing a
- * global minimum cut in an edge-weighted graph where the edge
- * weights are nonnegative. A cut is a partition of the set
- * of vertices of a graph into two nonempty subsets. An edge that has one
- * endpoint in each subset of a cut is a crossing edge. The weight
- * of a cut is the sum of the weights of its crossing edges.
- * A global minimum cut is a cut for which the weight is not
- * larger than the weight of any other cut.
- *
- * The {@code weight()} method returns the weight of the minimum cut and the
- * {@code cut(int v)} method determines if a vertex {@code v} is on the first or
- * on the second subset of vertices of the minimum cut.
- *
- * This is an implementation of Stoer–Wagner's algorithm using an index
- * priority queue and the union-find data type in order to simplify dealing with
- * contracting edges. Precisely, the index priority queue is an instance of
- * {@link IndexMaxPQ} which is based on a binary heap. As a consequence, the
- * constructor takes O(V (V + E ) log
- * V ) time and O(V) extra space (not including the
- * graph), where V is the number of vertices and E is the
- * number of edges. However, this time can be reduced to O(V E
- * + V2 log V) by using an index priority queue
- * implemented using Fibonacci heaps.
- *
- * Afterwards, the {@code weight()} and {@code cut(int v)} methods take constant
- * time.
- *
- * For additional documentation, see
- *
+ * This is an implementation of Stoer-Wagner's algorithm.
+ * The constructor takes
+ * O(V (V + E) log V) time,
+ * where V is the number of vertices and E is the
+ * number of edges.
+ * The weight and isCut methods take Θ(1) time.
+ * It uses Θ(V) extra space (not including the graph).
+ *
+ * For additional documentation, see
+ *
- * This implementation uses an adjacency-lists representation, which
+ * This implementation uses an adjacency-lists representation, which
* is a vertex-indexed array of {@link Bag} objects.
- * All operations take constant time (in the worst case) except
- * iterating over the vertices adjacent to a given vertex, which takes
- * time proportional to the number of such vertices.
+ * It uses Θ(E + V) space, where E is
+ * the number of edges and V is the number of vertices.
+ * All instance methods take Θ(1) time. (Though, iterating over
+ * the vertices returned by {@link #adj(int)} takes time proportional
+ * to the degree of the vertex.)
+ * Constructing an empty graph with V vertices takes
+ * Θ(V) time; constructing a graph with E edges
+ * and V vertices takes Θ(E + V) time.
*
- * For additional documentation, see Section 4.1
+ * For additional documentation, see
+ * Section 4.1
* of Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
*
* @author Robert Sedgewick
@@ -67,7 +74,7 @@ public class Graph {
private final int V;
private int E;
private Bag
+ * Pixel (col, row) is column col and row row.
+ * By default, the origin (0, 0) is the pixel in the top-left corner.
+ * These are common conventions in image processing and consistent with Java's
+ * {@link java.awt.image.BufferedImage} data type.
+ * The method {@link #setOriginLowerLeft()} change the origin to the lower left.
+ *
+ * The {@code get()} and {@code set()} methods use {@link Color} objects to get
+ * or set the color of the specified pixel. The {@link Color} objects are converted
+ * to grayscale if they have different values for the R, G, and B channels.
+ * The {@code getGrayscale()} and {@code setGrayscale()} methods use an
+ * 8-bit {@code int} to encode the grayscale value, thereby avoiding the need to
+ * create temporary {@code Color} objects.
+ *
+ * A W-by-H picture uses ~ 4 W H bytes of memory,
+ * since the color of each pixel is encoded as a 32-bit
+ * For additional documentation, see
+ * Section 3.1 of
+ * Computer Science: An Interdisciplinary Approach
+ * by Robert Sedgewick and Kevin Wayne.
+ * See {@link Picture} for a version that supports 32-bit RGB color images.
+ *
+ * @author Robert Sedgewick
+ * @author Kevin Wayne
+ */
+public final class GrayscalePicture implements ActionListener {
+ private BufferedImage image; // the rasterized image
+ private JFrame frame; // on-screen view
+ private String title; // name of file
+ private boolean isOriginUpperLeft = true; // location of origin
+ private boolean isVisible = false; // is the frame visible?
+ private final int width, height; // width and height
+
+ /**
+ * Creates a {@code width}-by-{@code height} picture, with {@code width} columns
+ * and {@code height} rows, where each pixel is black.
+ *
+ * @param width the width of the picture
+ * @param height the height of the picture
+ * @throws IllegalArgumentException if {@code width} is negative
+ * @throws IllegalArgumentException if {@code height} is negative
+ */
+ public GrayscalePicture(int width, int height) {
+ if (width < 0) throw new IllegalArgumentException("width must be non-negative");
+ if (height < 0) throw new IllegalArgumentException("height must be non-negative");
+ this.width = width;
+ this.height = height;
+ image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
+ }
+
+ /**
+ * Creates a new grayscale picture that is a deep copy of the argument picture.
+ *
+ * @param picture the picture to copy
+ * @throws IllegalArgumentException if {@code picture} is {@code null}
+ */
+ public GrayscalePicture(GrayscalePicture picture) {
+ if (picture == null) throw new IllegalArgumentException("constructor argument is null");
+
+ width = picture.width();
+ height = picture.height();
+ image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
+ title = picture.title;
+ isOriginUpperLeft = picture.isOriginUpperLeft;
+ for (int col = 0; col < width(); col++)
+ for (int row = 0; row < height(); row++)
+ image.setRGB(col, row, picture.image.getRGB(col, row));
+ }
+
+ /**
+ * Creates a grayscale picture by reading an image from a file or URL.
+ *
+ * @param filename the name of the file (.png, .gif, or .jpg) or URL.
+ * @throws IllegalArgumentException if {@code filename} is {@code null}
+ * @throws IllegalArgumentException if cannot read image from file or URL
+ */
+ public GrayscalePicture(String filename) {
+ if (filename == null) throw new IllegalArgumentException("constructor argument is null");
+ title = filename;
+ try {
+ // try to read from file in working directory
+ File file = new File(filename);
+ if (file.isFile()) {
+ image = ImageIO.read(file);
+ }
+
+ else {
+
+ // resource relative to .class file
+ URL url = getClass().getResource(filename);
+
+ // resource relative to classloader root
+ if (url == null) {
+ url = getClass().getClassLoader().getResource(filename);
+ }
+
+ // or URL from web or jar
+ if (url == null) {
+ URI uri = new URI(filename);
+ if (uri.isAbsolute()) url = uri.toURL();
+ else throw new IllegalArgumentException("could not read image: '" + filename + "'");
+ }
+
+ image = ImageIO.read(url);
+ }
+
+ if (image == null) {
+ throw new IllegalArgumentException("could not read image: '" + filename + "'");
+ }
+
+ width = image.getWidth(null);
+ height = image.getHeight(null);
+
+ // convert to grayscale in-place
+ for (int col = 0; col < width; col++) {
+ for (int row = 0; row < height; row++) {
+ Color color = new Color(image.getRGB(col, row));
+ Color gray = toGray(color);
+ image.setRGB(col, row, gray.getRGB());
+ }
+ }
+ }
+ catch (IOException | URISyntaxException e) {
+ throw new IllegalArgumentException("could not open image: " + filename, e);
+ }
+ }
+
+ // Returns a grayscale version of the given color as a Color object.
+ private static Color toGray(Color color) {
+ int r = color.getRed();
+ int g = color.getGreen();
+ int b = color.getBlue();
+ int y = (int) (Math.round(0.299*r + 0.587*g + 0.114*b));
+ return new Color(y, y, y);
+ }
+
+ /**
+ * Returns a {@link JLabel} containing this picture, for embedding in a {@link JPanel},
+ * {@link JFrame} or other GUI widget.
+ *
+ * @return the {@code JLabel}
+ */
+ public JLabel getJLabel() {
+ if (image == null) return null; // no image available
+ ImageIcon icon = new ImageIcon(image);
+ return new JLabel(icon);
+ }
+
+ /**
+ * Sets the origin to be the upper left pixel. This is the default.
+ */
+ public void setOriginUpperLeft() {
+ isOriginUpperLeft = true;
+ }
+
+ /**
+ * Sets the origin to be the lower left pixel.
+ */
+ public void setOriginLowerLeft() {
+ isOriginUpperLeft = false;
+ }
+
+ /**
+ * Displays the picture in a window on the screen.
+ */
+ public void show() {
+
+ // create the GUI for viewing the image if needed
+ if (frame == null) {
+ frame = new JFrame();
+
+ JMenuBar menuBar = new JMenuBar();
+ JMenu menu = new JMenu("File");
+ menuBar.add(menu);
+ JMenuItem menuItem1 = new JMenuItem(" Save... ");
+ menuItem1.addActionListener(this);
+ // Java 11: use getMenuShortcutKeyMaskEx()
+ // Java 8: use getMenuShortcutKeyMask()
+ menuItem1.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S,
+ Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx()));
+ menu.add(menuItem1);
+ frame.setJMenuBar(menuBar);
+
+
+
+ frame.setContentPane(getJLabel());
+ // f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
+ if (title == null) frame.setTitle(width + "-by-" + height);
+ else frame.setTitle(title);
+ frame.setResizable(false);
+ frame.pack();
+ }
+
+ // draw
+ frame.setVisible(true);
+ isVisible = true;
+ frame.repaint();
+ }
+
+ /**
+ * Hides the window on the screen.
+ */
+ public void hide() {
+ if (frame != null) {
+ isVisible = false;
+ frame.setVisible(false);
+ }
+ }
+
+ /**
+ * Is the window containing the picture visible?
+ * @return {@code true} if the picture is visible, and {@code false} otherwise
+ */
+ public boolean isVisible() {
+ return isVisible;
+ }
+
+ /**
+ * Returns the height of the picture.
+ *
+ * @return the height of the picture (in pixels)
+ */
+ public int height() {
+ return height;
+ }
+
+ /**
+ * Returns the width of the picture.
+ *
+ * @return the width of the picture (in pixels)
+ */
+ public int width() {
+ return width;
+ }
+
+ private void validateRowIndex(int row) {
+ if (row < 0 || row >= height())
+ throw new IndexOutOfBoundsException("row index must be between 0 and " + (height() - 1) + ": " + row);
+ }
+
+ private void validateColumnIndex(int col) {
+ if (col < 0 || col >= width())
+ throw new IndexOutOfBoundsException("column index must be between 0 and " + (width() - 1) + ": " + col);
+ }
+
+ private void validateGrayscaleValue(int gray) {
+ if (gray < 0 || gray >= 256)
+ throw new IllegalArgumentException("grayscale value must be between 0 and 255");
+ }
+
+ /**
+ * Returns the grayscale value of pixel ({@code col}, {@code row}) as a {@link java.awt.Color}.
+ *
+ * @param col the column index
+ * @param row the row index
+ * @return the grayscale value of pixel ({@code col}, {@code row})
+ * @throws IndexOutOfBoundsException unless both {@code 0 <= col < width} and {@code 0 <= row < height}
+ */
+ public Color get(int col, int row) {
+ validateColumnIndex(col);
+ validateRowIndex(row);
+ Color color = new Color(image.getRGB(col, row));
+ return toGray(color);
+ }
+
+ /**
+ * Returns the grayscale value of pixel ({@code col}, {@code row}) as an {@code int}
+ * between 0 and 255.
+ * Using this method can be more efficient than {@link #get(int, int)} because
+ * it does not create a {@code Color} object.
+ *
+ * @param col the column index
+ * @param row the row index
+ * @return the 8-bit integer representation of the grayscale value of pixel ({@code col}, {@code row})
+ * @throws IndexOutOfBoundsException unless both {@code 0 <= col < width} and {@code 0 <= row < height}
+ */
+ public int getGrayscale(int col, int row) {
+ validateColumnIndex(col);
+ validateRowIndex(row);
+ if (isOriginUpperLeft) return image.getRGB(col, row) & 0xFF;
+ else return image.getRGB(col, height - row - 1) & 0xFF;
+ }
+
+ /**
+ * Sets the color of pixel ({@code col}, {@code row}) to the given grayscale value.
+ *
+ * @param col the column index
+ * @param row the row index
+ * @param color the color (converts to grayscale if color is not a shade of gray)
+ * @throws IndexOutOfBoundsException unless both {@code 0 <= col < width} and {@code 0 <= row < height}
+ * @throws IllegalArgumentException if {@code color} is {@code null}
+ */
+ public void set(int col, int row, Color color) {
+ validateColumnIndex(col);
+ validateRowIndex(row);
+ if (color == null) throw new IllegalArgumentException("color argument is null");
+ Color gray = toGray(color);
+ image.setRGB(col, row, gray.getRGB());
+ }
+
+ /**
+ * Sets the color of pixel ({@code col}, {@code row}) to the given grayscale value
+ * between 0 and 255.
+ *
+ * @param col the column index
+ * @param row the row index
+ * @param gray the 8-bit integer representation of the grayscale value
+ * @throws IndexOutOfBoundsException unless both {@code 0 <= col < width} and {@code 0 <= row < height}
+ */
+ public void setGrayscale(int col, int row, int gray) {
+ validateColumnIndex(col);
+ validateRowIndex(row);
+ validateGrayscaleValue(gray);
+ int rgb = gray | (gray << 8) | (gray << 16);
+ if (isOriginUpperLeft) image.setRGB(col, row, rgb);
+ else image.setRGB(col, height - row - 1, rgb);
+ }
+
+ /**
+ * Returns true if this picture is equal to the argument picture.
+ *
+ * @param other the other picture
+ * @return {@code true} if this picture is the same dimension as {@code other}
+ * and if all pixels have the same color; {@code false} otherwise
+ */
+ public boolean equals(Object other) {
+ if (other == this) return true;
+ if (other == null) return false;
+ if (other.getClass() != this.getClass()) return false;
+ GrayscalePicture that = (GrayscalePicture) other;
+ if (this.width() != that.width()) return false;
+ if (this.height() != that.height()) return false;
+ for (int col = 0; col < width(); col++)
+ for (int row = 0; row < height(); row++)
+ if (this.getGrayscale(col, row) != that.getGrayscale(col, row)) return false;
+ return true;
+ }
+
+ /**
+ * Returns a string representation of this picture.
+ * The result is a
+ * This implementation takes Θ(n log n) time
+ * to sort any array of length n (assuming comparisons
+ * take constant time). It makes at most
+ * 2 n log2 n compares.
+ *
+ * This sorting algorithm is not stable.
+ * It uses Θ(1) extra memory (not including the input array).
*
- * For additional documentation, see Section 2.4 of
+ * For additional documentation, see
+ * Section 2.4 of
* Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
*
* @author Robert Sedgewick
@@ -44,11 +53,16 @@ private Heap() { }
*/
public static void sort(Comparable[] pq) {
int n = pq.length;
+
+ // heapify phase
for (int k = n/2; k >= 1; k--)
sink(pq, k, n);
- while (n > 1) {
- exch(pq, 1, n--);
- sink(pq, 1, n);
+
+ // sortdown phase
+ int k = n;
+ while (k > 1) {
+ exch(pq, 1, k--);
+ sink(pq, 1, k);
}
}
@@ -88,8 +102,8 @@ private static void show(Comparable[] a) {
}
/**
- * Reads in a sequence of strings from standard input; heapsorts them;
- * and prints them to standard output in ascending order.
+ * Reads in a sequence of strings from standard input; heapsorts them;
+ * and prints them to standard output in ascending order.
*
* @param args the command-line arguments
*/
@@ -101,7 +115,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/HexDump.java b/src/main/java/edu/princeton/cs/algs4/HexDump.java
index 24a21f840..48484a8de 100644
--- a/src/main/java/edu/princeton/cs/algs4/HexDump.java
+++ b/src/main/java/edu/princeton/cs/algs4/HexDump.java
@@ -3,7 +3,7 @@
* Execution: java HexDump < file
* Dependencies: BinaryStdIn.java StdOut.java
* Data file: https://algs4.cs.princeton.edu/55compression/abra.txt
- *
+ *
* Reads in a binary file and writes out the bytes in hex, 16 per line.
*
* % more abra.txt
@@ -18,7 +18,7 @@
* --------------------------
* - Similar to the Unix utilities od (octal dump) or hexdump (hexadecimal dump).
*
- * % od -t x1 < abra.txt
+ * % od -t x1 < abra.txt
* 0000000 41 42 52 41 43 41 44 41 42 52 41 21
* 0000014
*
@@ -31,7 +31,7 @@
* of a binary file in hexadecimal.
*
* For additional documentation,
- * see Section 5.5 of
+ * see Section 5.5 of
* Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
*
* See also {@link BinaryDump} and {@link PictureDump}.
@@ -49,7 +49,7 @@ private HexDump() { }
/**
* Reads in a sequence of bytes from standard input and writes
- * them to standard output using hexademical notation, k hex digits
+ * them to standard output using hexadecimal notation, k hex digits
* per line, where k is given as a command-line integer (defaults
* to 16 if no integer is specified); also writes the number
* of bits.
@@ -80,7 +80,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/HopcroftKarp.java b/src/main/java/edu/princeton/cs/algs4/HopcroftKarp.java
index 9ce7983cb..5a7442e02 100644
--- a/src/main/java/edu/princeton/cs/algs4/HopcroftKarp.java
+++ b/src/main/java/edu/princeton/cs/algs4/HopcroftKarp.java
@@ -26,7 +26,7 @@
* A vertex cover in a graph is a subset of its vertices such that
* every edge is incident to at least one vertex. A minimum vertex cover
* is a vertex cover with the minimum number of vertices.
- * By Konig's theorem, in any biparite
+ * By Konig's theorem, in any bipartite
* graph, the maximum number of edges in matching equals the minimum number
* of vertices in a vertex cover.
* The maximum matching problem in nonbipartite graphs is
@@ -292,7 +292,7 @@ private void validate(int v) {
}
/**************************************************************************
- *
+ *
* The code below is solely for testing correctness of the data type.
*
**************************************************************************/
@@ -349,8 +349,8 @@ private boolean certifySolution(Graph G) {
return true;
}
- /**
- * Unit tests the {@code HopcroftKarp} data type.
+ /**
+ * Unit tests the {@code HopcroftKarp} data type.
* Takes three command-line arguments {@code V1}, {@code V2}, and {@code E};
* creates a random bipartite graph with {@code V1} + {@code V2} vertices
* and {@code E} edges; computes a maximum matching and minimum vertex cover;
@@ -395,7 +395,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/Huffman.java b/src/main/java/edu/princeton/cs/algs4/Huffman.java
index 639e9eee7..56930b2fd 100644
--- a/src/main/java/edu/princeton/cs/algs4/Huffman.java
+++ b/src/main/java/edu/princeton/cs/algs4/Huffman.java
@@ -28,7 +28,7 @@
* ASCII alphabet.
*
* For additional documentation,
- * see Section 5.5 of
+ * see Section 5.5 of
* Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
*
* @author Robert Sedgewick
@@ -116,17 +116,11 @@ else if (code.charAt(j) == '1') {
// build the Huffman trie given frequencies
private static Node buildTrie(int[] freq) {
- // initialze priority queue with singleton trees
+ // initialize priority queue with singleton trees
MinPQ
* The Locale used is: language = English, country = US. This is consistent
* with the formatting conventions with Java floating-point literals,
* command-line arguments (via {@link Double#parseDouble(String)})
- * and standard output.
+ * and standard output.
*
- * For additional documentation, see
+ * For additional documentation, see
* Section 3.1 of
- * Computer Science: An Interdisciplinary Approach
+ * Computer Science: An Interdisciplinary Approach
* by Robert Sedgewick and Kevin Wayne.
*
* Like {@link Scanner}, reading a token also consumes preceding Java
* whitespace, reading a full line consumes
- * the following end-of-line delimeter, while reading a character consumes
- * nothing extra.
+ * the following end-of-line delimiter, while reading a character consumes
+ * nothing extra.
*
* Whitespace is defined in {@link Character#isWhitespace(char)}. Newlines
* consist of \n, \r, \r\n, and Unicode hex code points 0x2028, 0x2029, 0x0085;
@@ -54,20 +57,20 @@
* @author Kevin Wayne
*/
public final class In {
-
+
///// begin: section (1 of 2) of code duplicated from In to StdIn.
-
+
// assume Unicode UTF-8 encoding
private static final String CHARSET_NAME = "UTF-8";
// assume language = English, country = US for consistency with System.out.
private static final Locale LOCALE = Locale.US;
- // the default token separator; we maintain the invariant that this value
+ // the default token separator; we maintain the invariant that this value
// is held by the scanner's delimiter between calls
private static final Pattern WHITESPACE_PATTERN = Pattern.compile("\\p{javaWhitespace}+");
- // makes whitespace characters significant
+ // makes whitespace characters significant
private static final Pattern EMPTY_PATTERN = Pattern.compile("");
// used to read the entire input. source:
@@ -101,7 +104,7 @@ public In(Socket socket) {
scanner.useLocale(LOCALE);
}
catch (IOException ioe) {
- throw new IllegalArgumentException("Could not open " + socket, ioe);
+ throw new IllegalArgumentException("could not open socket: " + socket, ioe);
}
}
@@ -121,7 +124,7 @@ public In(URL url) {
scanner.useLocale(LOCALE);
}
catch (IOException ioe) {
- throw new IllegalArgumentException("Could not open " + url, ioe);
+ throw new IllegalArgumentException("could not read URL: '" + url + "'", ioe);
}
}
@@ -141,8 +144,8 @@ public In(File file) {
scanner = new Scanner(new BufferedInputStream(fis), CHARSET_NAME);
scanner.useLocale(LOCALE);
}
- catch (IOException ioe) {
- throw new IllegalArgumentException("Could not open " + file, ioe);
+ catch (IOException ioe) {;
+ throw new IllegalArgumentException("could not read file: " + file, ioe);
}
}
@@ -157,6 +160,7 @@ public In(File file) {
*/
public In(String name) {
if (name == null) throw new IllegalArgumentException("argument is null");
+ if (name.length() == 0) throw new IllegalArgumentException("argument is the empty string");
try {
// first try to read file from local file system
File file = new File(name);
@@ -169,16 +173,19 @@ public In(String name) {
return;
}
- // next try for files included in jar
+ // resource relative to .class file
URL url = getClass().getResource(name);
- // try this as well
+ // resource relative to classloader root
if (url == null) {
url = getClass().getClassLoader().getResource(name);
}
// or URL from web
if (url == null) {
+ URI uri = new URI(name);
+ if (uri.isAbsolute()) url = uri.toURL();
+ else throw new IllegalArgumentException("could not read: '" + name + "'");
url = new URL(name);
}
@@ -192,17 +199,17 @@ public In(String name) {
scanner = new Scanner(new BufferedInputStream(is), CHARSET_NAME);
scanner.useLocale(LOCALE);
}
- catch (IOException ioe) {
- throw new IllegalArgumentException("Could not open " + name, ioe);
+ catch (IOException | URISyntaxException e) {
+ throw new IllegalArgumentException("could not read: '" + name + "'");
}
}
/**
- * Initializes an input stream from a given {@link Scanner} source; use with
+ * Initializes an input stream from a given {@link Scanner} source; use with
* {@code new Scanner(String)} to read from a string.
*
* Note that this does not create a defensive copy, so the
- * scanner will be mutated as you read on.
+ * scanner will be mutated as you read on.
*
* @param scanner the scanner
* @throws IllegalArgumentException if {@code scanner} is {@code null}
@@ -220,14 +227,14 @@ public In(Scanner scanner) {
public boolean exists() {
return scanner != null;
}
-
+
//// begin: section (2 of 2) of code duplicated from In to StdIn,
//// with all methods changed from "public" to "public static".
/**
* Returns true if input stream is empty (except possibly whitespace).
- * Use this to know whether the next call to {@link #readString()},
- * {@link #readDouble()}, etc will succeed.
+ * Use this to know whether the next call to {@link #readString()},
+ * {@link #readDouble()}, etc. will succeed.
*
* @return {@code true} if this input stream is empty (except possibly whitespace);
* {@code false} otherwise
@@ -236,7 +243,7 @@ public boolean isEmpty() {
return !scanner.hasNext();
}
- /**
+ /**
* Returns true if this input stream has a next line.
* Use this method to know whether the
* next call to {@link #readLine()} will succeed.
@@ -253,9 +260,9 @@ public boolean hasNextLine() {
* Returns true if this input stream has more input (including whitespace).
* Use this method to know whether the next call to {@link #readChar()} will succeed.
* This method is functionally equivalent to {@link #hasNextLine()}.
- *
+ *
* @return {@code true} if this input stream has more input (including whitespace);
- * {@code false} otherwise
+ * {@code false} otherwise
*/
public boolean hasNextChar() {
scanner.useDelimiter(EMPTY_PATTERN);
@@ -300,7 +307,7 @@ public char readChar() {
throw new NoSuchElementException("attempts to read a 'char' value from the input stream, "
+ "but no more tokens are available");
}
- }
+ }
/**
@@ -529,7 +536,7 @@ public String[] readAllLines() {
while (hasNextLine()) {
lines.add(readLine());
}
- return lines.toArray(new String[lines.size()]);
+ return lines.toArray(new String[0]);
}
@@ -574,14 +581,14 @@ public double[] readAllDoubles() {
vals[i] = Double.parseDouble(fields[i]);
return vals;
}
-
+
///// end: section (2 of 2) of code duplicated from In to StdIn */
/**
* Closes this input stream.
*/
public void close() {
- scanner.close();
+ scanner.close();
}
/**
@@ -628,7 +635,7 @@ public static String[] readStrings(String filename) {
* an array of integers.
*
* @return the integers on standard input
- * @deprecated Replaced by {@link StdIn#readAllInts()}.
+ * @deprecated Replaced by {@code new In()}.{@link #readAllInts()}.
*/
@Deprecated
public static int[] readInts() {
@@ -640,7 +647,7 @@ public static int[] readInts() {
* an array of doubles.
*
* @return the doubles on standard input
- * @deprecated Replaced by {@link StdIn#readAllDoubles()}.
+ * @deprecated Replaced by {@code new In()}.{@link #readAllDoubles()}.
*/
@Deprecated
public static double[] readDoubles() {
@@ -652,13 +659,13 @@ public static double[] readDoubles() {
* an array of strings.
*
* @return the strings on standard input
- * @deprecated Replaced by {@link StdIn#readAllStrings()}.
+ * @deprecated Replaced by {@code new In()}.{@link #readAllStrings()}.
*/
@Deprecated
public static String[] readStrings() {
return new In().readAllStrings();
}
-
+
/**
* Unit tests the {@code In} data type.
*
@@ -666,7 +673,7 @@ public static String[] readStrings() {
*/
public static void main(String[] args) {
In in;
- String urlName = "https://introcs.cs.princeton.edu/stdlib/InTest.txt";
+ String urlName = "https://introcs.cs.princeton.edu/java/stdlib/InTest.txt";
// read from a URL
System.out.println("readAll() from URL " + urlName);
@@ -761,8 +768,8 @@ public static void main(String[] args) {
// read one line at a time from absolute OS X / Linux path
System.out.println("readLine() from absolute OS X / Linux path");
System.out.println("---------------------------------------------------------------------------");
- in = new In("/n/fs/introcs/www/java/stdlib/InTest.txt");
try {
+ in = new In("/n/fs/introcs/www/java/stdlib/InTest.txt");
while (!in.isEmpty()) {
String s = in.readLine();
System.out.println(s);
@@ -795,7 +802,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/IndexBinomialMinPQ.java b/src/main/java/edu/princeton/cs/algs4/IndexBinomialMinPQ.java
index 8ac359050..102c5f65b 100644
--- a/src/main/java/edu/princeton/cs/algs4/IndexBinomialMinPQ.java
+++ b/src/main/java/edu/princeton/cs/algs4/IndexBinomialMinPQ.java
@@ -502,7 +502,7 @@ public int compare(Key key1, Key key2) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/IndexFibonacciMinPQ.java b/src/main/java/edu/princeton/cs/algs4/IndexFibonacciMinPQ.java
index fd2cf2d16..70aa0063a 100644
--- a/src/main/java/edu/princeton/cs/algs4/IndexFibonacciMinPQ.java
+++ b/src/main/java/edu/princeton/cs/algs4/IndexFibonacciMinPQ.java
@@ -32,6 +32,8 @@
* The delete, increase-key, delete-the-minimum, change-key take amortized logarithmic time.
* Construction takes time proportional to the specified capacity
*
+ * WARNING: THIS VERSION HAS AT LEAST ONE BUG.
+ *
* @author Tristan Claverie
*/
public class IndexFibonacciMinPQ
- * This implementation uses a binary heap along with an array to associate
- * keys with integers in the given range.
+ * This implementation uses a binary heap along with an
+ * array to associate keys with integers in the given range.
* The insert, delete-the-maximum, delete,
* change-key, decrease-key, and increase-key
- * operations take logarithmic time.
- * The is-empty, size, max-index, max-key,
- * and key-of operations take constant time.
+ * operations take Θ(log n) time in the worst case,
+ * where n is the number of elements in the priority queue.
* Construction takes time proportional to the specified capacity.
*
- * For additional documentation, see Section 2.4 of
+ * For additional documentation, see
+ * Section 2.4 of
* Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
*
* @author Robert Sedgewick
@@ -42,6 +42,7 @@
* @param
- * For additional documentation, see Section 2.4 of
+ * For additional documentation, see
+ * Section 2.4 of
* Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
*
* @author Robert Sedgewick
@@ -85,7 +85,7 @@ public boolean isEmpty() {
* @throws IllegalArgumentException unless {@code 0 <= i < maxN}
*/
public boolean contains(int i) {
- if (i < 0 || i >= maxN) throw new IllegalArgumentException();
+ validateIndex(i);
return qp[i] != -1;
}
@@ -108,7 +108,7 @@ public int size() {
* with index {@code i}
*/
public void insert(int i, Key key) {
- if (i < 0 || i >= maxN) throw new IllegalArgumentException();
+ validateIndex(i);
if (contains(i)) throw new IllegalArgumentException("index is already in the priority queue");
n++;
qp[i] = n;
@@ -165,7 +165,7 @@ public int delMin() {
* @throws NoSuchElementException no key is associated with index {@code i}
*/
public Key keyOf(int i) {
- if (i < 0 || i >= maxN) throw new IllegalArgumentException();
+ validateIndex(i);
if (!contains(i)) throw new NoSuchElementException("index is not in the priority queue");
else return keys[i];
}
@@ -179,7 +179,7 @@ public Key keyOf(int i) {
* @throws NoSuchElementException no key is associated with index {@code i}
*/
public void changeKey(int i, Key key) {
- if (i < 0 || i >= maxN) throw new IllegalArgumentException();
+ validateIndex(i);
if (!contains(i)) throw new NoSuchElementException("index is not in the priority queue");
keys[i] = key;
swim(qp[i]);
@@ -209,10 +209,12 @@ public void change(int i, Key key) {
* @throws NoSuchElementException no key is associated with index {@code i}
*/
public void decreaseKey(int i, Key key) {
- if (i < 0 || i >= maxN) throw new IllegalArgumentException();
+ validateIndex(i);
if (!contains(i)) throw new NoSuchElementException("index is not in the priority queue");
- if (keys[i].compareTo(key) <= 0)
- throw new IllegalArgumentException("Calling decreaseKey() with given argument would not strictly decrease the key");
+ if (keys[i].compareTo(key) == 0)
+ throw new IllegalArgumentException("Calling decreaseKey() with a key equal to the key in the priority queue");
+ if (keys[i].compareTo(key) < 0)
+ throw new IllegalArgumentException("Calling decreaseKey() with a key strictly greater than the key in the priority queue");
keys[i] = key;
swim(qp[i]);
}
@@ -227,10 +229,12 @@ public void decreaseKey(int i, Key key) {
* @throws NoSuchElementException no key is associated with index {@code i}
*/
public void increaseKey(int i, Key key) {
- if (i < 0 || i >= maxN) throw new IllegalArgumentException();
+ validateIndex(i);
if (!contains(i)) throw new NoSuchElementException("index is not in the priority queue");
- if (keys[i].compareTo(key) >= 0)
- throw new IllegalArgumentException("Calling increaseKey() with given argument would not strictly increase the key");
+ if (keys[i].compareTo(key) == 0)
+ throw new IllegalArgumentException("Calling increaseKey() with a key equal to the key in the priority queue");
+ if (keys[i].compareTo(key) > 0)
+ throw new IllegalArgumentException("Calling increaseKey() with a key strictly less than the key in the priority queue");
keys[i] = key;
sink(qp[i]);
}
@@ -243,7 +247,7 @@ public void increaseKey(int i, Key key) {
* @throws NoSuchElementException no key is associated with index {@code i}
*/
public void delete(int i) {
- if (i < 0 || i >= maxN) throw new IllegalArgumentException();
+ validateIndex(i);
if (!contains(i)) throw new NoSuchElementException("index is not in the priority queue");
int index = qp[i];
exch(index, n--);
@@ -253,6 +257,11 @@ public void delete(int i) {
qp[i] = -1;
}
+ // throw an IllegalArgumentException if i is an invalid index
+ private void validateIndex(int i) {
+ if (i < 0) throw new IllegalArgumentException("index is negative: " + i);
+ if (i >= maxN) throw new IllegalArgumentException("index >= capacity: " + i);
+ }
/***************************************************************************
* General helper functions.
@@ -364,7 +373,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/IndexMultiwayMinPQ.java b/src/main/java/edu/princeton/cs/algs4/IndexMultiwayMinPQ.java
index 5b58c33f4..8411a06aa 100644
--- a/src/main/java/edu/princeton/cs/algs4/IndexMultiwayMinPQ.java
+++ b/src/main/java/edu/princeton/cs/algs4/IndexMultiwayMinPQ.java
@@ -371,7 +371,7 @@ public int compare(Key key1, Key key2) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/InplaceMSD.java b/src/main/java/edu/princeton/cs/algs4/InplaceMSD.java
index cb42b8a17..cf940e0ae 100644
--- a/src/main/java/edu/princeton/cs/algs4/InplaceMSD.java
+++ b/src/main/java/edu/princeton/cs/algs4/InplaceMSD.java
@@ -1,13 +1,13 @@
/******************************************************************************
* Compilation: javac InplaceMSD.java
* Execution: java InplaceMSD < input.txt
- * Dependencies: StdIn.java StdOut.java
+ * Dependencies: StdIn.java StdOut.java
* Data files: https://algs4.cs.princeton.edu/51radix/words3.txt
* https://algs4.cs.princeton.edu/51radix/shells.txt
*
* Sort an array of strings or integers using in-place MSD radix sort.
*
- * % java InplaceMSD < shells.txt
+ * % java InplaceMSD < shells.txt
* are
* by
* sea
@@ -43,7 +43,7 @@ public class InplaceMSD {
private static final int CUTOFF = 15; // cutoff to insertion sort
// do not instantiate
- private InplaceMSD() { }
+ private InplaceMSD() { }
/**
* Rearranges the array of extended ASCII strings in ascending order.
@@ -98,7 +98,7 @@ private static void sort(String[] a, int lo, int hi, int d) {
heads[r]++;
}
}
-
+
// recursively sort for each character (excludes sentinel -1)
for (int r = 0; r < R; r++)
sort(a, tails[r], tails[r+1] - 1, d+1);
@@ -147,7 +147,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/Insertion.java b/src/main/java/edu/princeton/cs/algs4/Insertion.java
index 927ee9c3a..a8d28103a 100644
--- a/src/main/java/edu/princeton/cs/algs4/Insertion.java
+++ b/src/main/java/edu/princeton/cs/algs4/Insertion.java
@@ -4,7 +4,7 @@
* Dependencies: StdOut.java StdIn.java
* Data files: https://algs4.cs.princeton.edu/21elementary/tiny.txt
* https://algs4.cs.princeton.edu/21elementary/words3.txt
- *
+ *
* Sorts a sequence of strings from standard input using insertion sort.
*
* % more tiny.txt
@@ -29,13 +29,15 @@
* The {@code Insertion} class provides static methods for sorting an
* array using insertion sort.
*
- * This implementation makes ~ 1/2 n^2 compares and exchanges in
- * the worst case, so it is not suitable for sorting large arbitrary arrays.
- * More precisely, the number of exchanges is exactly equal to the number
- * of inversions. So, for example, it sorts a partially-sorted array
+ * In the worst case, this implementation makes ~ ½ n2
+ * compares and ~ ½ n2 exchanges to sort an array
+ * of length n. So, it is not suitable for sorting large arbitrary
+ * arrays. More precisely, the number of exchanges is exactly equal to the
+ * number of inversions. So, for example, it sorts a partially-sorted array
* in linear time.
*
- * The sorting algorithm is stable and uses O(1) extra memory.
+ * This sorting algorithm is stable.
+ * It uses Θ(1) extra memory (not including the input array).
*
* See InsertionPedantic.java
* for a version that eliminates the compiler warning.
@@ -57,7 +59,7 @@ private Insertion() { }
*/
public static void sort(Comparable[] a) {
int n = a.length;
- for (int i = 0; i < n; i++) {
+ for (int i = 1; i < n; i++) {
for (int j = i; j > 0 && less(a[j], a[j-1]); j--) {
exch(a, j, j-1);
}
@@ -73,7 +75,7 @@ public static void sort(Comparable[] a) {
* @param hi right endpoint (exclusive)
*/
public static void sort(Comparable[] a, int lo, int hi) {
- for (int i = lo; i < hi; i++) {
+ for (int i = lo + 1; i < hi; i++) {
for (int j = i; j > lo && less(a[j], a[j-1]); j--) {
exch(a, j, j-1);
}
@@ -88,7 +90,7 @@ public static void sort(Comparable[] a, int lo, int hi) {
*/
public static void sort(Object[] a, Comparator comparator) {
int n = a.length;
- for (int i = 0; i < n; i++) {
+ for (int i = 1; i < n; i++) {
for (int j = i; j > 0 && less(a[j], a[j-1], comparator); j--) {
exch(a, j, j-1);
}
@@ -105,7 +107,7 @@ public static void sort(Object[] a, Comparator comparator) {
* @param comparator the comparator specifying the order
*/
public static void sort(Object[] a, int lo, int hi, Comparator comparator) {
- for (int i = lo; i < hi; i++) {
+ for (int i = lo + 1; i < hi; i++) {
for (int j = i; j > lo && less(a[j], a[j-1], comparator); j--) {
exch(a, j, j-1);
}
@@ -128,7 +130,7 @@ public static int[] indexSort(Comparable[] a) {
for (int i = 0; i < n; i++)
index[i] = i;
- for (int i = 0; i < n; i++)
+ for (int i = 1; i < n; i++)
for (int j = i; j > 0 && less(a[index[j]], a[index[j-1]]); j--)
exch(index, j, j-1);
@@ -138,7 +140,7 @@ public static int[] indexSort(Comparable[] a) {
/***************************************************************************
* Helper sorting functions.
***************************************************************************/
-
+
// is v < w ?
private static boolean less(Comparable v, Comparable w) {
return v.compareTo(w) < 0;
@@ -148,7 +150,7 @@ private static boolean less(Comparable v, Comparable w) {
private static boolean less(Object v, Object w, Comparator comparator) {
return comparator.compare(v, w) < 0;
}
-
+
// exchange a[i] and a[j]
private static void exch(Object[] a, int i, int j) {
Object swap = a[i];
@@ -172,7 +174,7 @@ private static boolean isSorted(Comparable[] a) {
// is the array a[lo..hi) sorted
private static boolean isSorted(Comparable[] a, int lo, int hi) {
- for (int i = lo+1; i < hi; i++)
+ for (int i = lo + 1; i < hi; i++)
if (less(a[i], a[i-1])) return false;
return true;
}
@@ -183,7 +185,7 @@ private static boolean isSorted(Object[] a, Comparator comparator) {
// is the array a[lo..hi) sorted
private static boolean isSorted(Object[] a, int lo, int hi, Comparator comparator) {
- for (int i = lo+1; i < hi; i++)
+ for (int i = lo + 1; i < hi; i++)
if (less(a[i], a[i-1], comparator)) return false;
return true;
}
@@ -209,7 +211,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/InsertionX.java b/src/main/java/edu/princeton/cs/algs4/InsertionX.java
index 504072195..57210d99a 100644
--- a/src/main/java/edu/princeton/cs/algs4/InsertionX.java
+++ b/src/main/java/edu/princeton/cs/algs4/InsertionX.java
@@ -4,9 +4,9 @@
* Dependencies: StdOut.java StdIn.java
* Data files: https://algs4.cs.princeton.edu/21elementary/tiny.txt
* https://algs4.cs.princeton.edu/21elementary/words3.txt
- *
+ *
* Sorts a sequence of strings from standard input using an optimized
- * version of insertion sort that uses half exchanges instead of
+ * version of insertion sort that uses half exchanges instead of
* full exchanges to reduce data movement..
*
* % more tiny.txt
@@ -29,7 +29,16 @@
* an array using an optimized version of insertion sort (with half exchanges
* and a sentinel).
*
- * For additional documentation, see Section 2.1 of
+ * In the worst case, this implementation makes ~ 1/2 n2
+ * compares to sort an array of length n.
+ * So, it is not suitable for sorting large arrays
+ * (unless the number of inversions is small).
+ *
+ * This sorting algorithm is stable.
+ * It uses Θ(1) extra memory (not including the input array).
+ *
+ * For additional documentation, see
+ * Section 2.1 of
* Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
*
* @author Robert Sedgewick
@@ -77,12 +86,12 @@ public static void sort(Comparable[] a) {
/***************************************************************************
* Helper sorting functions.
***************************************************************************/
-
+
// is v < w ?
private static boolean less(Comparable v, Comparable w) {
return v.compareTo(w) < 0;
}
-
+
// exchange a[i] and a[j]
private static void exch(Object[] a, int i, int j) {
Object swap = a[i];
@@ -122,7 +131,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/Interval1D.java b/src/main/java/edu/princeton/cs/algs4/Interval1D.java
index 3c74c3089..460f5ff59 100644
--- a/src/main/java/edu/princeton/cs/algs4/Interval1D.java
+++ b/src/main/java/edu/princeton/cs/algs4/Interval1D.java
@@ -2,7 +2,7 @@
* Compilation: javac Interval1D.java
* Execution: java Interval1D
* Dependencies: StdOut.java
- *
+ *
* 1-dimensional interval data type.
*
******************************************************************************/
@@ -19,9 +19,9 @@
* The class {@code Interval1D} includes methods for checking whether
* an interval contains a point and determining whether two intervals intersect.
*
- * For additional documentation,
- * see Section 1.2 of
- * Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
+ * For additional documentation,
+ * see Section 1.2 of
+ * Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
@@ -81,7 +81,7 @@ public Interval1D(double min, double max) {
* @deprecated Replaced by {@link #min()}.
*/
@Deprecated
- public double left() {
+ public double left() {
return min;
}
@@ -91,7 +91,7 @@ public double left() {
* @deprecated Replaced by {@link #max()}.
*/
@Deprecated
- public double right() {
+ public double right() {
return max;
}
@@ -100,7 +100,7 @@ public double right() {
*
* @return the min endpoint of this interval
*/
- public double min() {
+ public double min() {
return min;
}
@@ -109,7 +109,7 @@ public double min() {
*
* @return the max endpoint of this interval
*/
- public double max() {
+ public double max() {
return max;
}
@@ -126,6 +126,17 @@ public boolean intersects(Interval1D that) {
return true;
}
+ /**
+ * Returns true if this interval contains the specified interval.
+ *
+ * @param that the other interval
+ * @return {@code true} if this interval contains the argument interval;
+ * {@code false} otherwise
+ */
+ public boolean contains(Interval1D that) {
+ return (this.max >= that.max) && (this.min <= that.min);
+ }
+
/**
* Returns true if this interval contains the specified value.
*
@@ -233,7 +244,7 @@ public static void main(String[] args) {
for (int i = 0; i < intervals.length; i++)
StdOut.println(intervals[i]);
StdOut.println();
-
+
StdOut.println("Sort by min endpoint");
Arrays.sort(intervals, Interval1D.MIN_ENDPOINT_ORDER);
for (int i = 0; i < intervals.length; i++)
@@ -255,7 +266,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/Interval2D.java b/src/main/java/edu/princeton/cs/algs4/Interval2D.java
index 9767fb448..34189ebf0 100644
--- a/src/main/java/edu/princeton/cs/algs4/Interval2D.java
+++ b/src/main/java/edu/princeton/cs/algs4/Interval2D.java
@@ -2,7 +2,7 @@
* Compilation: javac Interval2D.java
* Execution: java Interval2D
* Dependencies: StdOut.java Interval1D.java StdDraw.java
- *
+ *
* 2-dimensional interval data type.
*
******************************************************************************/
@@ -19,9 +19,9 @@
* a two-dimensional interval contains a point and determining whether
* two two-dimensional intervals intersect.
*
- * For additional documentation,
- * see Section 1.2 of
- * Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
+ * For additional documentation,
+ * see Section 1.2 of
+ * Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
@@ -52,6 +52,16 @@ public boolean intersects(Interval2D that) {
return true;
}
+ /**
+ * Does this two-dimensional interval contain that two-dimensional interval?
+ * @param that the other two-dimensional interval
+ * @return true if this two-dimensional interval contains
+ * that two-dimensional interval; false otherwise
+ */
+ public boolean contains(Interval2D that) {
+ return this.x.contains(that.x) && this.y.contains(that.y);
+ }
+
/**
* Does this two-dimensional interval contain the point p?
* @param p the two-dimensional point
@@ -68,7 +78,7 @@ public boolean contains(Point2D p) {
public double area() {
return x.length() * y.length();
}
-
+
/**
* Returns a string representation of this two-dimensional interval.
* @return a string representation of this two-dimensional interval
@@ -91,10 +101,10 @@ public boolean equals(Object other) {
return this.x.equals(that.x) && this.y.equals(that.y);
}
-
+
/**
- * Returns an integer hash code for this interval.
- * @return an integer hash code for this interval
+ * Returns an integer hash code for this interval.
+ * @return an integer hash code for this interval
*/
public int hashCode() {
int hash1 = x.hashCode();
@@ -130,8 +140,8 @@ public static void main(String[] args) {
Counter counter = new Counter("hits");
for (int t = 0; t < trials; t++) {
- double x = StdRandom.uniform(0.0, 1.0);
- double y = StdRandom.uniform(0.0, 1.0);
+ double x = StdRandom.uniformDouble(0.0, 1.0);
+ double y = StdRandom.uniformDouble(0.0, 1.0);
Point2D point = new Point2D(x, y);
if (box.contains(point)) counter.increment();
@@ -144,7 +154,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/Inversions.java b/src/main/java/edu/princeton/cs/algs4/Inversions.java
index e5a4f64e8..0c5c70660 100644
--- a/src/main/java/edu/princeton/cs/algs4/Inversions.java
+++ b/src/main/java/edu/princeton/cs/algs4/Inversions.java
@@ -2,7 +2,7 @@
* Compilation: javac Inversions.java
* Execution: java Inversions < input.txt
* Dependencies: StdIn.java StdOut.java
- *
+ *
* Read array of n integers and count number of inversions in n log n time.
*
******************************************************************************/
@@ -10,16 +10,18 @@
package edu.princeton.cs.algs4;
/**
- * The {@code Inversions} class provides static methods to count the
+ * The {@code Inversions} class provides static methods to count the
* number of inversions in either an array of integers or comparables.
* An inversion in an array {@code a[]} is a pair of indicies {@code i} and
* {@code j} such that {@code i < j} and {@code a[i] > a[j]}.
*
* This implementation uses a generalization of mergesort. The count
- * operation takes time proportional to n log n,
- * where n is the number of keys in the array.
+ * operation takes Θ(n log n) time to count the
+ * number of inversions in any array of length n (assuming
+ * comparisons take constant time).
*
- * For additional documentation, see Section 2.2
+ * For additional documentation, see
+ * Section 2.2
* of Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
*
* @author Robert Sedgewick
@@ -36,7 +38,7 @@ private static long merge(int[] a, int[] aux, int lo, int mid, int hi) {
// copy to aux[]
for (int k = lo; k <= hi; k++) {
- aux[k] = a[k];
+ aux[k] = a[k];
}
// merge back to a[]
@@ -56,7 +58,7 @@ private static long count(int[] a, int[] b, int[] aux, int lo, int hi) {
long inversions = 0;
if (hi <= lo) return 0;
int mid = lo + (hi - lo) / 2;
- inversions += count(a, b, aux, lo, mid);
+ inversions += count(a, b, aux, lo, mid);
inversions += count(a, b, aux, mid+1, hi);
inversions += merge(b, aux, lo, mid, hi);
assert inversions == brute(a, lo, hi);
@@ -68,7 +70,7 @@ private static long count(int[] a, int[] b, int[] aux, int lo, int hi) {
* Returns the number of inversions in the integer array.
* The argument array is not modified.
* @param a the array
- * @return the number of inversions in the array. An inversion is a pair of
+ * @return the number of inversions in the array. An inversion is a pair of
* indicies {@code i} and {@code j} such that {@code i < j}
* and {@code a[i] > a[j]}.
*/
@@ -89,7 +91,7 @@ private static
+ * The component identifier of a vertex is an integer between
+ * 0 and k–1, where k is the number of strong components.
+ * Two vertices have the same component identifier if and only if they
+ * are in the same strong component.
*
* This implementation uses the Kosaraju-Sharir algorithm.
- * The constructor takes time proportional to V + E
- * (in the worst case),
- * where V is the number of vertices and E is the number of edges.
- * Afterwards, the id, count, and areStronglyConnected
- * operations take constant time.
- * For alternate implementations of the same API, see
+ * The constructor takes Θ(V + E) time,
+ * where V is the number of vertices and E
+ * is the number of edges.
+ * Each instance method takes Θ(1) time.
+ * It uses Θ(V) extra space (not including the digraph).
+ * For alternative implementations of the same API, see
* {@link TarjanSCC} and {@link GabowSCC}.
*
- * For additional documentation,
- * see Section 4.2 of
+ * For additional documentation, see
+ * Section 4.2 of
* Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
*
* @author Robert Sedgewick
@@ -123,7 +123,7 @@ public KosarajuSharirSCC(Digraph G) {
}
// DFS on graph G
- private void dfs(Digraph G, int v) {
+ private void dfs(Digraph G, int v) {
marked[v] = true;
id[v] = count;
for (int w : G.adj(v)) {
@@ -220,7 +220,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/KruskalMST.java b/src/main/java/edu/princeton/cs/algs4/KruskalMST.java
index ae710d4a3..bb80cb057 100644
--- a/src/main/java/edu/princeton/cs/algs4/KruskalMST.java
+++ b/src/main/java/edu/princeton/cs/algs4/KruskalMST.java
@@ -1,7 +1,7 @@
/******************************************************************************
* Compilation: javac KruskalMST.java
* Execution: java KruskalMST filename.txt
- * Dependencies: EdgeWeightedGraph.java Edge.java Queue.java
+ * Dependencies: EdgeWeightedGraph.java Edge.java Queue.java MinPQ.java
* UF.java In.java StdOut.java
* Data files: https://algs4.cs.princeton.edu/43mst/tinyEWG.txt
* https://algs4.cs.princeton.edu/43mst/mediumEWG.txt
@@ -9,7 +9,7 @@
*
* Compute a minimum spanning forest using Kruskal's algorithm.
*
- * % java KruskalMST tinyEWG.txt
+ * % java KruskalMST tinyEWG.txt
* 0-7 0.16000
* 2-3 0.17000
* 1-7 0.19000
@@ -36,23 +36,30 @@
package edu.princeton.cs.algs4;
+import java.util.Arrays;
+
/**
* The {@code KruskalMST} class represents a data type for computing a
* minimum spanning tree in an edge-weighted graph.
* The edge weights can be positive, zero, or negative and need not
* be distinct. If the graph is not connected, it computes a minimum
* spanning forest, which is the union of minimum spanning trees
- * in each connected component. The {@code weight()} method returns the
+ * in each connected component. The {@code weight()} method returns the
* weight of a minimum spanning tree and the {@code edges()} method
* returns its edges.
*
- * This implementation uses Krusal's algorithm and the
+ * This implementation uses Kruskal's algorithm and the
* union-find data type.
- * The constructor takes time proportional to E log E
- * and extra space (not including the graph) proportional to V,
- * where V is the number of vertices and E is the number of edges.
- * Afterwards, the {@code weight()} method takes constant time
- * and the {@code edges()} method takes time proportional to V.
+ * The constructor takes Θ(E log E) time in
+ * the worst case.
+ * Each instance method takes Θ(1) time.
+ * It uses Θ(E) extra space (not including the graph).
+ *
+ * This {@code weight()} method correctly computes the weight of the MST
+ * if all arithmetic performed is without floating-point rounding error
+ * or arithmetic overflow.
+ * This is the case if all edge weights are non-negative integers
+ * and the weight of the MST does not exceed 252.
*
* For additional documentation,
* see Section 4.3 of
@@ -64,7 +71,7 @@
* @author Kevin Wayne
*/
public class KruskalMST {
- private static final double FLOATING_POINT_EPSILON = 1E-12;
+ private static final double FLOATING_POINT_EPSILON = 1.0E-12;
private double weight; // weight of MST
private Queue
+ * WARNING: Starting with Oracle Java 7u6, the substring method takes time and
+ * space linear in the length of the extracted substring (instead of constant
+ * time an space as in earlier versions). As a result, compression takes
+ * quadratic time. TODO: fix.
+ * See this article
+ * for more details.
+ *
* For additional documentation,
- * see Section 5.5 of
+ * see Section 5.5 of
* Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
*
- * @author Robert Sedgewick
+ * @author Robert Sedgewick
* @author Kevin Wayne
*/
public class LZW {
@@ -45,11 +45,14 @@ private LZW() { }
* them using LZW compression with 12-bit codewords; and writes the results
* to standard output.
*/
- public static void compress() {
+ public static void compress() {
String input = BinaryStdIn.readString();
TST
* This implementation uses a lazy version of Prim's algorithm
* with a binary heap of edges.
- * The constructor takes time proportional to E log E
- * and extra space (not including the graph) proportional to E,
- * where V is the number of vertices and E is the number of edges.
- * Afterwards, the {@code weight()} method takes constant time
- * and the {@code edges()} method takes time proportional to V.
+ * The constructor takes Θ(E log E) time in
+ * the worst case, where V is the number of vertices and
+ * E is the number of edges.
+ * Each instance method takes Θ(1) time.
+ * It uses Θ(E) extra space in the worst case
+ * (not including the edge-weighted graph).
*
* For additional documentation,
* see Section 4.3 of
@@ -69,7 +70,7 @@
* @author Kevin Wayne
*/
public class LazyPrimMST {
- private static final double FLOATING_POINT_EPSILON = 1E-12;
+ private static final double FLOATING_POINT_EPSILON = 1.0E-12;
private double weight; // total weight of MST
private Queue
* The data type supplies methods for determining the optimal primal and
* dual solutions.
*
* This is a bare-bones implementation of the simplex algorithm.
- * It uses Bland's rule to determing the entering and leaving variables.
- * It is not suitable for use on large inputs. It is also not robust
- * in the presence of floating-point roundoff error.
+ * It uses Bland's rule to determine the entering and leaving variables.
+ * It is not suitable for use on large inputs.
+ *
+ * This computes correct results if all arithmetic performed is
+ * without floating-point rounding error or arithmetic overflow.
+ * In practice, there will be floating-point rounding error
+ * and this implementation is not robust in the presence of
+ * such errors.
*
* For additional documentation, see
* Section 6.5
@@ -48,7 +53,7 @@ public class LinearProgramming {
/**
* Determines an optimal solution to the linear program
- * { max cx : Ax ≤ b, x ≥ 0 }, where A is a m-by-n
+ * { max cx : Ax ≤ b, x ≥ 0 }, where A is an m-by-n
* matrix, b is an m-length vector, and c is an n-length vector.
*
* @param A the m-by-b matrix
@@ -56,7 +61,7 @@ public class LinearProgramming {
* @param c the n-length cost vector
* @throws IllegalArgumentException unless {@code b[i] >= 0} for each {@code i}
* @throws ArithmeticException if the linear program is unbounded
- */
+ */
public LinearProgramming(double[][] A, double[] b, double[] c) {
m = b.length;
n = c.length;
@@ -140,7 +145,7 @@ private void pivot(int p, int q) {
// everything but row p and column q
for (int i = 0; i <= m; i++)
for (int j = 0; j <= m+n; j++)
- if (i != p && j != q) a[i][j] -= a[p][j] * a[i][q] / a[p][q];
+ if (i != p && j != q) a[i][j] -= a[p][j] * (a[i][q] / a[p][q]);
// zero out column q
for (int i = 0; i <= m; i++)
@@ -181,8 +186,10 @@ public double[] primal() {
*/
public double[] dual() {
double[] y = new double[m];
- for (int i = 0; i < m; i++)
+ for (int i = 0; i < m; i++) {
y[i] = -a[m][n+i];
+ if (y[i] == -0.0) y[i] = 0.0;
+ }
return y;
}
@@ -193,7 +200,7 @@ private boolean isPrimalFeasible(double[][] A, double[] b) {
// check that x >= 0
for (int j = 0; j < x.length; j++) {
- if (x[j] < 0.0) {
+ if (x[j] < -EPSILON) {
StdOut.println("x[" + j + "] = " + x[j] + " is negative");
return false;
}
@@ -220,7 +227,7 @@ private boolean isDualFeasible(double[][] A, double[] c) {
// check that y >= 0
for (int i = 0; i < y.length; i++) {
- if (y[i] < 0.0) {
+ if (y[i] < -EPSILON) {
StdOut.println("y[" + i + "] = " + y[i] + " is negative");
return false;
}
@@ -383,12 +390,12 @@ public static void main(String[] args) {
double[] b = new double[m];
double[][] A = new double[m][n];
for (int j = 0; j < n; j++)
- c[j] = StdRandom.uniform(1000);
+ c[j] = StdRandom.uniformInt(1000);
for (int i = 0; i < m; i++)
- b[i] = StdRandom.uniform(1000);
+ b[i] = StdRandom.uniformInt(1000);
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++)
- A[i][j] = StdRandom.uniform(100);
+ A[i][j] = StdRandom.uniformInt(100);
LinearProgramming lp = new LinearProgramming(A, b, c);
test(A, b, c);
}
@@ -396,7 +403,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/LinearRegression.java b/src/main/java/edu/princeton/cs/algs4/LinearRegression.java
index 9e2157f4c..90f516bb2 100644
--- a/src/main/java/edu/princeton/cs/algs4/LinearRegression.java
+++ b/src/main/java/edu/princeton/cs/algs4/LinearRegression.java
@@ -2,7 +2,7 @@
* Compilation: javac LinearRegression.java
* Execution: java LinearRegression
* Dependencies: none
- *
+ *
* Compute least squares solution to y = beta * x + alpha.
* Simple linear regression.
*
@@ -154,7 +154,7 @@ public String toString() {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/LinkedBag.java b/src/main/java/edu/princeton/cs/algs4/LinkedBag.java
index f1b54e87e..971466a51 100644
--- a/src/main/java/edu/princeton/cs/algs4/LinkedBag.java
+++ b/src/main/java/edu/princeton/cs/algs4/LinkedBag.java
@@ -5,7 +5,7 @@
*
* A generic bag or multiset, implemented using a singly linked list.
*
- * % more tobe.txt
+ * % more tobe.txt
* to be or not to - be - - that - - - is
*
* % java LinkedBag < tobe.txt
@@ -33,8 +33,8 @@
import java.util.NoSuchElementException;
/**
- * The {@code LinkedBag} class represents a bag (or multiset) of
- * generic items. It supports insertion and iterating over the
+ * The {@code LinkedBag} class represents a bag (or multiset) of
+ * generic items. It supports insertion and iterating over the
* items in arbitrary order.
*
* This implementation uses a singly linked list with a non-static nested class Node.
@@ -99,15 +99,15 @@ public void add(Item item) {
* Returns an iterator that iterates over the items in the bag.
*/
public Iterator
- * This implementation uses a singly linked list with a non-static nested class
+ * This implementation uses a singly linked list with a non-static nested class
* for linked-list nodes. See {@link Queue} for a version that uses a static nested class.
* The enqueue, dequeue, peek, size, and is-empty
* operations all take constant time in the worst case.
@@ -69,7 +69,7 @@ public boolean isEmpty() {
* @return the number of items in this queue
*/
public int size() {
- return n;
+ return n;
}
/**
@@ -121,7 +121,7 @@ public String toString() {
for (Item item : this)
s.append(item + " ");
return s.toString();
- }
+ }
// check internal invariants
private boolean check() {
@@ -159,28 +159,29 @@ else if (n == 1) {
}
return true;
- }
-
+ }
+
/**
* Returns an iterator that iterates over the items in this queue in FIFO order.
* @return an iterator that iterates over the items in this queue in FIFO order
*/
public Iterator
- * This implementation uses a singly linked list with a non-static nested class for
+ * This implementation uses a singly linked list with a non-static nested class for
* linked-list nodes. See {@link Stack} for a version that uses a static nested class.
* The push, pop, peek, size, and is-empty
* operations all take constant time in the worst case.
@@ -123,25 +123,27 @@ public String toString() {
s.append(item + " ");
return s.toString();
}
-
+
/**
* Returns an iterator to this stack that iterates through the items in LIFO order.
* @return an iterator to this stack that iterates through the items in LIFO order.
*/
public Iterator
- *
+ *
* @author Robert Sedgewick
* @author Kevin Wayne
*/
@@ -73,7 +73,7 @@ public static String lcs(String s, String t) {
SuffixArray suffix1 = new SuffixArray(s);
SuffixArray suffix2 = new SuffixArray(t);
- // find longest common substring by "merging" sorted suffixes
+ // find longest common substring by "merging" sorted suffixes
String lcs = "";
int i = 0, j = 0;
while (i < s.length() && j < t.length()) {
@@ -106,7 +106,7 @@ public static void main(String[] args) {
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/LongestRepeatedSubstring.java b/src/main/java/edu/princeton/cs/algs4/LongestRepeatedSubstring.java
index c47150000..2c32a7608 100644
--- a/src/main/java/edu/princeton/cs/algs4/LongestRepeatedSubstring.java
+++ b/src/main/java/edu/princeton/cs/algs4/LongestRepeatedSubstring.java
@@ -5,17 +5,17 @@
* Data files: https://algs4.cs.princeton.edu/63suffix/tale.txt
* https://algs4.cs.princeton.edu/63suffix/tinyTale.txt
* https://algs4.cs.princeton.edu/63suffix/mobydick.txt
- *
- * Reads a text string from stdin, replaces all consecutive blocks of
- * whitespace with a single space, and then computes the longest
+ *
+ * Reads a text string from standard input, replaces all consecutive blocks
+ * of whitespace with a single space, and then computes the longest
* repeated substring in that text using a suffix array.
- *
- * % java LongestRepeatedSubstring < tinyTale.txt
+ *
+ * % java LongestRepeatedSubstring < tinyTale.txt
* 'st of times it was the '
*
* % java LongestRepeatedSubstring < mobydick.txt
* ',- Such a funny, sporty, gamy, jesty, joky, hoky-poky lad, is the Ocean, oh! Th'
- *
+ *
* % java LongestRepeatedSubstring
* aaaaaaaaa
* 'aaaaaaaa'
@@ -89,7 +89,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/LookupCSV.java b/src/main/java/edu/princeton/cs/algs4/LookupCSV.java
index 190614925..15b1477a7 100644
--- a/src/main/java/edu/princeton/cs/algs4/LookupCSV.java
+++ b/src/main/java/edu/princeton/cs/algs4/LookupCSV.java
@@ -8,23 +8,23 @@
* https://algs4.cs.princeton.edu/35applications/elements.csv
* https://algs4.cs.princeton.edu/35applications/ip.csv
* https://algs4.cs.princeton.edu/35applications/morse.csv
- *
+ *
* Reads in a set of key-value pairs from a two-column CSV file
* specified on the command line; then, reads in keys from standard
* input and prints out corresponding values.
- *
- * % java LookupCSV amino.csv 0 3 % java LookupCSV ip.csv 0 1
- * TTA www.google.com
- * Leucine 216.239.41.99
- * ABC
- * Not found % java LookupCSV ip.csv 1 0
- * TCT 216.239.41.99
- * Serine www.google.com
- *
- * % java LookupCSV amino.csv 3 0 % java LookupCSV DJIA.csv 0 1
- * Glycine 29-Oct-29
- * GGG 252.38
- * 20-Oct-87
+ *
+ * % java LookupCSV amino.csv 0 3 % java LookupCSV ip.csv 0 1
+ * TTA www.google.com
+ * Leucine 216.239.41.99
+ * ABC
+ * Not found % java LookupCSV ip.csv 1 0
+ * TCT 216.239.41.99
+ * Serine www.google.com
+ *
+ * % java LookupCSV amino.csv 3 0 % java LookupCSV DJIA.csv 0 1
+ * Glycine 29-Oct-29
+ * GGG 252.38
+ * 20-Oct-87
* 1738.74
*
*
@@ -40,7 +40,7 @@
*
* For additional documentation, see Section 3.5 of
* Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
- *
+ *
* @author Robert Sedgewick
* @author Kevin Wayne
*/
@@ -75,7 +75,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/LookupIndex.java b/src/main/java/edu/princeton/cs/algs4/LookupIndex.java
index bcda021e4..86180e45d 100644
--- a/src/main/java/edu/princeton/cs/algs4/LookupIndex.java
+++ b/src/main/java/edu/princeton/cs/algs4/LookupIndex.java
@@ -44,11 +44,11 @@
*
* For additional documentation, see Section 3.5 of
* Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
- *
+ *
* @author Robert Sedgewick
* @author Kevin Wayne
*/
-public class LookupIndex {
+public class LookupIndex {
// Do not instantiate.
private LookupIndex() { }
@@ -79,10 +79,10 @@ public static void main(String[] args) {
// read queries from standard input, one per line
while (!StdIn.isEmpty()) {
String query = StdIn.readLine();
- if (st.contains(query))
+ if (st.contains(query))
for (String vals : st.get(query))
StdOut.println(" " + vals);
- if (ts.contains(query))
+ if (ts.contains(query))
for (String keys : ts.get(query))
StdOut.println(" " + keys);
}
@@ -92,7 +92,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/MSD.java b/src/main/java/edu/princeton/cs/algs4/MSD.java
index f0603aec5..9fd1c2cf6 100644
--- a/src/main/java/edu/princeton/cs/algs4/MSD.java
+++ b/src/main/java/edu/princeton/cs/algs4/MSD.java
@@ -1,13 +1,13 @@
/******************************************************************************
* Compilation: javac MSD.java
* Execution: java MSD < input.txt
- * Dependencies: StdIn.java StdOut.java
+ * Dependencies: StdIn.java StdOut.java
* Data files: https://algs4.cs.princeton.edu/51radix/words3.txt
* https://algs4.cs.princeton.edu/51radix/shells.txt
*
* Sort an array of strings or integers using MSD radix sort.
*
- * % java MSD < shells.txt
+ * % java MSD < shells.txt
* are
* by
* sea
@@ -40,12 +40,12 @@
*/
public class MSD {
private static final int BITS_PER_BYTE = 8;
- private static final int BITS_PER_INT = 32; // each Java int is 32 bits
+ private static final int BITS_PER_INT = 32; // each Java int is 32 bits
private static final int R = 256; // extended ASCII alphabet size
private static final int CUTOFF = 15; // cutoff to insertion sort
// do not instantiate
- private MSD() { }
+ private MSD() { }
/**
* Rearranges the array of extended ASCII strings in ascending order.
@@ -81,7 +81,7 @@ private static void sort(String[] a, int lo, int hi, int d, String[] aux) {
count[c+2]++;
}
- // transform counts to indicies
+ // transform counts to indices
for (int r = 0; r < R+1; r++)
count[r+1] += count[r];
@@ -92,7 +92,7 @@ private static void sort(String[] a, int lo, int hi, int d, String[] aux) {
}
// copy back
- for (int i = lo; i <= hi; i++)
+ for (int i = lo; i <= hi; i++)
a[i] = aux[i - lo];
@@ -144,7 +144,7 @@ private static void sort(int[] a, int lo, int hi, int d, int[] aux) {
// cutoff to insertion sort for small subarrays
if (hi <= lo + CUTOFF) {
- insertion(a, lo, hi, d);
+ insertion(a, lo, hi);
return;
}
@@ -157,21 +157,21 @@ private static void sort(int[] a, int lo, int hi, int d, int[] aux) {
count[c + 1]++;
}
- // transform counts to indicies
+ // transform counts to indices
for (int r = 0; r < R; r++)
count[r+1] += count[r];
-/************* BUGGGY CODE.
// for most significant byte, 0x80-0xFF comes before 0x00-0x7F
if (d == 0) {
int shift1 = count[R] - count[R/2];
int shift2 = count[R/2];
+ count[R] = shift1 + count[1]; // to simplify recursive calls later
for (int r = 0; r < R/2; r++)
count[r] += shift1;
for (int r = R/2; r < R; r++)
count[r] -= shift2;
}
-************************************/
+
// distribute
for (int i = lo; i <= hi; i++) {
int c = (a[i] >> shift) & mask;
@@ -179,22 +179,29 @@ private static void sort(int[] a, int lo, int hi, int d, int[] aux) {
}
// copy back
- for (int i = lo; i <= hi; i++)
+ for (int i = lo; i <= hi; i++)
a[i] = aux[i - lo];
// no more bits
- if (d == 4) return;
+ if (d == 3) return;
- // recursively sort for each character
- if (count[0] > 0)
+ // special case for most significant byte
+ if (d == 0 && count[R/2] > 0)
+ sort(a, lo, lo + count[R/2] - 1, d+1, aux);
+
+ // special case for other bytes
+ if (d != 0 && count[0] > 0)
sort(a, lo, lo + count[0] - 1, d+1, aux);
+
+ // recursively sort for each character
+ // (could skip r = R/2 for d = 0 and skip r = R for d > 0)
for (int r = 0; r < R; r++)
if (count[r+1] > count[r])
sort(a, lo + count[r], lo + count[r+1] - 1, d+1, aux);
}
- // TODO: insertion sort a[lo..hi], starting at dth character
- private static void insertion(int[] a, int lo, int hi, int d) {
+ // insertion sort a[lo..hi]
+ private static void insertion(int[] a, int lo, int hi) {
for (int i = lo; i <= hi; i++)
for (int j = i; j > lo && a[j] < a[j-1]; j--)
exch(a, j, j-1);
@@ -225,7 +232,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/MaxPQ.java b/src/main/java/edu/princeton/cs/algs4/MaxPQ.java
index fe70deab1..ccba82f7f 100644
--- a/src/main/java/edu/princeton/cs/algs4/MaxPQ.java
+++ b/src/main/java/edu/princeton/cs/algs4/MaxPQ.java
@@ -3,12 +3,12 @@
* Execution: java MaxPQ < input.txt
* Dependencies: StdIn.java StdOut.java
* Data files: https://algs4.cs.princeton.edu/24pq/tinyPQ.txt
- *
+ *
* Generic max priority queue implementation with a binary heap.
* Can be used with a comparator instead of the natural order,
* but the generic Key type must still be Comparable.
*
- * % java MaxPQ < tinyPQ.txt
+ * % java MaxPQ < tinyPQ.txt
* Q X P (6 left on pq)
*
* We use a one-based array to simplify parent and child calculations.
@@ -31,14 +31,18 @@
* testing if the priority queue is empty, and iterating through
* the keys.
*
- * This implementation uses a binary heap.
+ * This implementation uses a binary heap.
* The insert and delete-the-maximum operations take
- * logarithmic amortized time.
- * The max, size, and is-empty operations take constant time.
- * Construction takes time proportional to the specified capacity or the number of
- * items used to initialize the data structure.
+ * Θ(log n) amortized time, where n is the number
+ * of elements in the priority queue. This is an amortized bound
+ * (and not a worst-case bound) because of array resizing operations.
+ * The min, size, and is-empty operations take
+ * Θ(1) time in the worst case.
+ * Construction takes time proportional to the specified capacity or the
+ * number of items used to initialize the data structure.
*
- * For additional documentation, see Section 2.4 of
+ * For additional documentation, see
+ * Section 2.4 of
* Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
*
* @author Robert Sedgewick
@@ -106,7 +110,7 @@ public MaxPQ(Key[] keys) {
sink(k);
assert isMaxHeap();
}
-
+
/**
@@ -139,7 +143,7 @@ public Key max() {
return pq[1];
}
- // helper function to double the size of the heap array
+ // resize the underlying array to have the given capacity
private void resize(int capacity) {
assert capacity > n;
Key[] temp = (Key[]) new Object[capacity];
@@ -177,7 +181,7 @@ public Key delMax() {
Key max = pq[1];
exch(1, n--);
sink(1);
- pq[n+1] = null; // to avoid loiterig and help with garbage collection
+ pq[n+1] = null; // to avoid loitering and help with garbage collection
if ((n > 0) && (n == (pq.length - 1) / 4)) resize(pq.length / 2);
assert isMaxHeap();
return max;
@@ -190,7 +194,7 @@ public Key delMax() {
private void swim(int k) {
while (k > 1 && less(k/2, k)) {
- exch(k, k/2);
+ exch(k/2, k);
k = k/2;
}
}
@@ -223,19 +227,26 @@ private void exch(int i, int j) {
pq[j] = swap;
}
- // is pq[1..N] a max heap?
+ // is pq[1..n] a max heap?
private boolean isMaxHeap() {
- return isMaxHeap(1);
+ for (int i = 1; i <= n; i++) {
+ if (pq[i] == null) return false;
+ }
+ for (int i = n+1; i < pq.length; i++) {
+ if (pq[i] != null) return false;
+ }
+ if (pq[0] != null) return false;
+ return isMaxHeapOrdered(1);
}
// is subtree of pq[1..n] rooted at k a max heap?
- private boolean isMaxHeap(int k) {
+ private boolean isMaxHeapOrdered(int k) {
if (k > n) return true;
int left = 2*k;
int right = 2*k + 1;
if (left <= n && less(k, left)) return false;
if (right <= n && less(k, right)) return false;
- return isMaxHeap(left) && isMaxHeap(right);
+ return isMaxHeapOrdered(left) && isMaxHeapOrdered(right);
}
@@ -295,7 +306,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/Merge.java b/src/main/java/edu/princeton/cs/algs4/Merge.java
index beb6ee8a4..af519bcc1 100644
--- a/src/main/java/edu/princeton/cs/algs4/Merge.java
+++ b/src/main/java/edu/princeton/cs/algs4/Merge.java
@@ -4,30 +4,40 @@
* Dependencies: StdOut.java StdIn.java
* Data files: https://algs4.cs.princeton.edu/22mergesort/tiny.txt
* https://algs4.cs.princeton.edu/22mergesort/words3.txt
- *
+ *
* Sorts a sequence of strings from standard input using mergesort.
- *
+ *
* % more tiny.txt
* S O R T E X A M P L E
*
* % java Merge < tiny.txt
* A E E L M O P R S T X [ one string per line ]
- *
+ *
* % more words3.txt
* bed bug dad yes zoo ... all bad yet
- *
+ *
* % java Merge < words3.txt
* all bad bed bug dad ... yes yet zoo [ one string per line ]
- *
+ *
******************************************************************************/
package edu.princeton.cs.algs4;
/**
* The {@code Merge} class provides static methods for sorting an
- * array using mergesort.
+ * array using a top-down, recursive version of mergesort.
*
- * For additional documentation, see Section 2.2 of
+ * This implementation takes Θ(n log n) time
+ * to sort any array of length n (assuming comparisons
+ * take constant time). It makes between
+ * ~ ½ n log2 n and
+ * ~ 1 n log2 n compares.
+ *
+ * This sorting algorithm is stable.
+ * It uses Θ(n) extra memory (not including the input array).
+ *
+ * For additional documentation, see
+ * Section 2.2 of
* Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
* For an optimized version, see {@link MergeX}.
*
@@ -47,7 +57,7 @@ private static void merge(Comparable[] a, Comparable[] aux, int lo, int mid, int
// copy to aux[]
for (int k = lo; k <= hi; k++) {
- aux[k] = a[k];
+ aux[k] = a[k];
}
// merge back to a[]
@@ -86,12 +96,12 @@ public static void sort(Comparable[] a) {
/***************************************************************************
* Helper sorting function.
***************************************************************************/
-
+
// is v < w ?
private static boolean less(Comparable v, Comparable w) {
return v.compareTo(w) < 0;
}
-
+
/***************************************************************************
* Check if array is sorted - useful for debugging.
***************************************************************************/
@@ -114,7 +124,7 @@ private static void merge(Comparable[] a, int[] index, int[] aux, int lo, int mi
// copy to aux[]
for (int k = lo; k <= hi; k++) {
- aux[k] = index[k];
+ aux[k] = index[k];
}
// merge back to a[]
@@ -131,7 +141,7 @@ private static void merge(Comparable[] a, int[] index, int[] aux, int lo, int mi
* Returns a permutation that gives the elements in the array in ascending order.
* @param a the array
* @return a permutation {@code p[]} such that {@code a[p[0]]}, {@code a[p[1]]},
- * ..., {@code a[p[N-1]]} are in ascending order
+ * ..., {@code a[p[n-1]]} are in ascending order
*/
public static int[] indexSort(Comparable[] a) {
int n = a.length;
@@ -161,8 +171,8 @@ private static void show(Comparable[] a) {
}
/**
- * Reads in a sequence of strings from standard input; mergesorts them;
- * and prints them to standard output in ascending order.
+ * Reads in a sequence of strings from standard input; mergesorts them;
+ * and prints them to standard output in ascending order.
*
* @param args the command-line arguments
*/
@@ -174,7 +184,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/MergeBU.java b/src/main/java/edu/princeton/cs/algs4/MergeBU.java
index e87b72895..711aa7fa0 100644
--- a/src/main/java/edu/princeton/cs/algs4/MergeBU.java
+++ b/src/main/java/edu/princeton/cs/algs4/MergeBU.java
@@ -4,19 +4,19 @@
* Dependencies: StdOut.java StdIn.java
* Data files: https://algs4.cs.princeton.edu/22mergesort/tiny.txt
* https://algs4.cs.princeton.edu/22mergesort/words3.txt
- *
+ *
* Sorts a sequence of strings from standard input using
* bottom-up mergesort.
- *
+ *
* % more tiny.txt
* S O R T E X A M P L E
*
* % java MergeBU < tiny.txt
* A E E L M O P R S T X [ one string per line ]
- *
+ *
* % more words3.txt
* bed bug dad yes zoo ... all bad yet
- *
+ *
* % java MergeBU < words3.txt
* all bad bed bug dad ... yes yet zoo [ one string per line ]
*
@@ -26,9 +26,19 @@
/**
* The {@code MergeBU} class provides static methods for sorting an
- * array using bottom-up mergesort.
+ * array using bottom-up mergesort. It is non-recursive.
*
- * For additional documentation, see Section 2.1 of
+ * This implementation takes Θ(n log n) time
+ * to sort any array of length n (assuming comparisons
+ * take constant time). It makes between
+ * ~ ½ n log2 n and
+ * ~ 1 n log2 n compares.
+ *
+ * This sorting algorithm is stable.
+ * It uses Θ(n) extra memory (not including the input array).
+ *
+ * For additional documentation, see
+ * Section 2.1 of
* Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
*
* @author Robert Sedgewick
@@ -44,13 +54,13 @@ private static void merge(Comparable[] a, Comparable[] aux, int lo, int mid, int
// copy to aux[]
for (int k = lo; k <= hi; k++) {
- aux[k] = a[k];
+ aux[k] = a[k];
}
// merge back to a[]
int i = lo, j = mid+1;
for (int k = lo; k <= hi; k++) {
- if (i > mid) a[k] = aux[j++]; // this copying is unneccessary
+ if (i > mid) a[k] = aux[j++]; // this copying is unnecessary
else if (j > hi) a[k] = aux[i++];
else if (less(aux[j], aux[i])) a[k] = aux[j++];
else a[k] = aux[i++];
@@ -78,7 +88,7 @@ public static void sort(Comparable[] a) {
/***********************************************************************
* Helper sorting functions.
***************************************************************************/
-
+
// is v < w ?
private static boolean less(Comparable v, Comparable w) {
return v.compareTo(w) < 0;
@@ -103,7 +113,7 @@ private static void show(Comparable[] a) {
/**
* Reads in a sequence of strings from standard input; bottom-up
- * mergesorts them; and prints them to standard output in ascending order.
+ * mergesorts them; and prints them to standard output in ascending order.
*
* @param args the command-line arguments
*/
@@ -115,7 +125,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/MergeX.java b/src/main/java/edu/princeton/cs/algs4/MergeX.java
index 62ae118e9..72f9b23d3 100644
--- a/src/main/java/edu/princeton/cs/algs4/MergeX.java
+++ b/src/main/java/edu/princeton/cs/algs4/MergeX.java
@@ -4,19 +4,19 @@
* Dependencies: StdOut.java StdIn.java
* Data files: https://algs4.cs.princeton.edu/22mergesort/tiny.txt
* https://algs4.cs.princeton.edu/22mergesort/words3.txt
- *
+ *
* Sorts a sequence of strings from standard input using an
* optimized version of mergesort.
- *
+ *
* % more tiny.txt
* S O R T E X A M P L E
*
* % java MergeX < tiny.txt
* A E E L M O P R S T X [ one string per line ]
- *
+ *
* % more words3.txt
* bed bug dad yes zoo ... all bad yet
- *
+ *
* % java MergeX < words3.txt
* all bad bed bug dad ... yes yet zoo [ one string per line ]
*
@@ -30,7 +30,15 @@
* The {@code MergeX} class provides static methods for sorting an
* array using an optimized version of mergesort.
*
- * For additional documentation, see Section 2.2 of
+ * In the worst case, this implementation takes
+ * Θ(n log n) time to sort an array of
+ * length n (assuming comparisons take constant time).
+ *
+ * This sorting algorithm is stable.
+ * It uses Θ(n) extra memory (not including the input array).
+ *
+ * For additional documentation, see
+ * Section 2.2 of
* Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
*
* @author Robert Sedgewick
@@ -62,7 +70,7 @@ private static void merge(Comparable[] src, Comparable[] dst, int lo, int mid, i
private static void sort(Comparable[] src, Comparable[] dst, int lo, int hi) {
// if (hi <= lo) return;
- if (hi <= lo + CUTOFF) {
+ if (hi <= lo + CUTOFF) {
insertionSort(dst, lo, hi);
return;
}
@@ -90,7 +98,7 @@ private static void sort(Comparable[] src, Comparable[] dst, int lo, int hi) {
*/
public static void sort(Comparable[] a) {
Comparable[] aux = a.clone();
- sort(aux, a, 0, a.length-1);
+ sort(aux, a, 0, a.length-1);
assert isSorted(a);
}
@@ -161,7 +169,7 @@ private static void merge(Object[] src, Object[] dst, int lo, int mid, int hi, C
private static void sort(Object[] src, Object[] dst, int lo, int hi, Comparator comparator) {
// if (hi <= lo) return;
- if (hi <= lo + CUTOFF) {
+ if (hi <= lo + CUTOFF) {
insertionSort(dst, lo, hi, comparator);
return;
}
@@ -218,8 +226,8 @@ private static void show(Object[] a) {
/**
* Reads in a sequence of strings from standard input; mergesorts them
- * (using an optimized version of mergesort);
- * and prints them to standard output in ascending order.
+ * (using an optimized version of mergesort);
+ * and prints them to standard output in ascending order.
*
* @param args the command-line arguments
*/
@@ -231,7 +239,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/MinPQ.java b/src/main/java/edu/princeton/cs/algs4/MinPQ.java
index 29005daab..5d75e578e 100644
--- a/src/main/java/edu/princeton/cs/algs4/MinPQ.java
+++ b/src/main/java/edu/princeton/cs/algs4/MinPQ.java
@@ -3,7 +3,7 @@
* Execution: java MinPQ < input.txt
* Dependencies: StdIn.java StdOut.java
* Data files: https://algs4.cs.princeton.edu/24pq/tinyPQ.txt
- *
+ *
* Generic min priority queue implementation with a binary heap.
* Can be used with a comparator instead of the natural order.
*
@@ -30,14 +30,18 @@
* testing if the priority queue is empty, and iterating through
* the keys.
*
- * This implementation uses a binary heap.
+ * This implementation uses a binary heap.
* The insert and delete-the-minimum operations take
- * logarithmic amortized time.
- * The min, size, and is-empty operations take constant time.
- * Construction takes time proportional to the specified capacity or the number of
- * items used to initialize the data structure.
+ * Θ(log n) amortized time, where n is the number
+ * of elements in the priority queue. This is an amortized bound
+ * (and not a worst-case bound) because of array resizing operations.
+ * The min, size, and is-empty operations take
+ * Θ(1) time in the worst case.
+ * Construction takes time proportional to the specified capacity or the
+ * number of items used to initialize the data structure.
*
- * For additional documentation, see Section 2.4 of
+ * For additional documentation, see
+ * Section 2.4 of
* Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
*
* @author Robert Sedgewick
@@ -136,7 +140,7 @@ public Key min() {
return pq[1];
}
- // helper function to double the size of the heap array
+ // resize the underlying array to have the given capacity
private void resize(int capacity) {
assert capacity > n;
Key[] temp = (Key[]) new Object[capacity];
@@ -172,7 +176,7 @@ public Key delMin() {
Key min = pq[1];
exch(1, n--);
sink(1);
- pq[n+1] = null; // to avoid loiterig and help with garbage collection
+ pq[n+1] = null; // to avoid loitering and help with garbage collection
if ((n > 0) && (n == (pq.length - 1) / 4)) resize(pq.length / 2);
assert isMinHeap();
return min;
@@ -185,7 +189,7 @@ public Key delMin() {
private void swim(int k) {
while (k > 1 && greater(k/2, k)) {
- exch(k, k/2);
+ exch(k/2, k);
k = k/2;
}
}
@@ -218,19 +222,26 @@ private void exch(int i, int j) {
pq[j] = swap;
}
- // is pq[1..N] a min heap?
+ // is pq[1..n] a min heap?
private boolean isMinHeap() {
- return isMinHeap(1);
+ for (int i = 1; i <= n; i++) {
+ if (pq[i] == null) return false;
+ }
+ for (int i = n+1; i < pq.length; i++) {
+ if (pq[i] != null) return false;
+ }
+ if (pq[0] != null) return false;
+ return isMinHeapOrdered(1);
}
// is subtree of pq[1..n] rooted at k a min heap?
- private boolean isMinHeap(int k) {
+ private boolean isMinHeapOrdered(int k) {
if (k > n) return true;
int left = 2*k;
int right = 2*k + 1;
if (left <= n && greater(k, left)) return false;
if (right <= n && greater(k, right)) return false;
- return isMinHeap(left) && isMinHeap(right);
+ return isMinHeapOrdered(left) && isMinHeapOrdered(right);
}
@@ -286,7 +297,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/Multiway.java b/src/main/java/edu/princeton/cs/algs4/Multiway.java
index dff2ff12a..6d64e5458 100644
--- a/src/main/java/edu/princeton/cs/algs4/Multiway.java
+++ b/src/main/java/edu/princeton/cs/algs4/Multiway.java
@@ -5,21 +5,21 @@
* Data files: https://algs4.cs.princeton.edu/24pq/m1.txt
* https://algs4.cs.princeton.edu/24pq/m2.txt
* https://algs4.cs.princeton.edu/24pq/m3.txt
- *
+ *
* Merges together the sorted input stream given as command-line arguments
* into a single sorted output stream on standard output.
*
- * % more m1.txt
+ * % more m1.txt
* A B C F G I I Z
*
- * % more m2.txt
+ * % more m2.txt
* B D H P Q Q
- *
- * % more m3.txt
+ *
+ * % more m3.txt
* A B E F J N
*
- * % java Multiway m1.txt m2.txt m3.txt
- * A A B B B C D E F F G H I I J N P Q Q Z
+ * % java Multiway m1.txt m2.txt m3.txt
+ * A A B B B C D E F F G H I I J N P Q Q Z
*
******************************************************************************/
@@ -30,7 +30,7 @@
* sorted text files and merging them together into a single sorted
* text stream.
* This implementation uses a {@link IndexMinPQ} to perform the multiway
- * merge.
+ * merge.
*
* For additional documentation, see Section 2.4
* of Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
@@ -39,7 +39,7 @@
* @author Kevin Wayne
*/
-public class Multiway {
+public class Multiway {
// This class should not be instantiated.
private Multiway() { }
@@ -52,7 +52,7 @@ private static void merge(In[] streams) {
if (!streams[i].isEmpty())
pq.insert(i, streams[i].readString());
- // Extract and print min and read next from its stream.
+ // Extract and print min and read next from its stream.
while (!pq.isEmpty()) {
StdOut.print(pq.minKey() + " ");
int i = pq.delMin();
@@ -81,7 +81,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/MultiwayMinPQ.java b/src/main/java/edu/princeton/cs/algs4/MultiwayMinPQ.java
index 65d3f63d4..fae2520d2 100644
--- a/src/main/java/edu/princeton/cs/algs4/MultiwayMinPQ.java
+++ b/src/main/java/edu/princeton/cs/algs4/MultiwayMinPQ.java
@@ -305,7 +305,7 @@ public int compare(Key key1, Key key2) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/NFA.java b/src/main/java/edu/princeton/cs/algs4/NFA.java
index 2686af151..575d62a38 100644
--- a/src/main/java/edu/princeton/cs/algs4/NFA.java
+++ b/src/main/java/edu/princeton/cs/algs4/NFA.java
@@ -36,7 +36,7 @@
* closure, binary or, and parentheses.
* It does not support mutiway or, character classes,
* metacharacters (either in the text or pattern),
- * capturing capabilities, greedy or relucantant
+ * capturing capabilities, greedy or reluctant
* modifiers, and other features in industrial-strength implementations
* such as {@link java.util.regex.Pattern} and {@link java.util.regex.Matcher}.
*
@@ -54,7 +54,7 @@
* @author Robert Sedgewick
* @author Kevin Wayne
*/
-public class NFA {
+public class NFA {
private Digraph graph; // digraph of epsilon transitions
private String regexp; // regular expression
@@ -68,17 +68,17 @@ public class NFA {
public NFA(String regexp) {
this.regexp = regexp;
m = regexp.length();
- Stack
* This implementation uses a nonrecursive version of depth-first search
* with an explicit stack.
- * The constructor takes time proportional to V + E,
- * where V is the number of vertices and E is the number of edges.
- * It uses extra space (not including the graph) proportional to V.
+ * See {@link DepthFirstSearch} for the classic recursive version.
+ * The constructor takes Θ(V + E) time in the worst
+ * case, where V is the number of vertices and E is the
+ * number of edges.
+ * The {@link #marked(int)} instance method takes Θ(1) time.
+ * It uses Θ(V) extra space (not including the graph).
*
- * For additional documentation, see Section 4.1
+ * For additional documentation,
+ * see Section 4.1
* of Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
*
* @author Robert Sedgewick
@@ -133,7 +142,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/NonrecursiveDirectedDFS.java b/src/main/java/edu/princeton/cs/algs4/NonrecursiveDirectedDFS.java
index 58773e7ad..52f6c46f9 100644
--- a/src/main/java/edu/princeton/cs/algs4/NonrecursiveDirectedDFS.java
+++ b/src/main/java/edu/princeton/cs/algs4/NonrecursiveDirectedDFS.java
@@ -6,7 +6,7 @@
* https://algs4.cs.princeton.edu/42digraph/mediumDG.txt
* https://algs4.cs.princeton.edu/42digraph/largeDG.txt
*
- * Run nonrecurisve depth-first search on an directed graph.
+ * Run nonrecurisve depth-first search on a directed graph.
* Runs in O(E + V) time.
*
* Explores the vertices in exactly the same order as DirectedDFS.java.
@@ -30,9 +30,11 @@
*
* This implementation uses a nonrecursive version of depth-first search
* with an explicit stack.
- * The constructor takes time proportional to V + E,
- * where V is the number of vertices and E is the number of edges.
- * It uses extra space (not including the digraph) proportional to V.
+ * The constructor takes Θ(V + E) time in the
+ * worst case, where V is the number of vertices and E
+ * is the number of edges.
+ * Each instance method takes Θ(1) time.
+ * It uses Θ(V) extra space (not including the digraph).
*
* For additional documentation,
* see Section 4.2 of
@@ -43,6 +45,7 @@
*/
public class NonrecursiveDirectedDFS {
private boolean[] marked; // marked[v] = is there an s->v path?
+
/**
* Computes the vertices reachable from the source vertex {@code s} in the digraph {@code G}.
* @param G the digraph
@@ -121,7 +124,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/Out.java b/src/main/java/edu/princeton/cs/algs4/Out.java
index 1ad379ee3..8c1284d66 100644
--- a/src/main/java/edu/princeton/cs/algs4/Out.java
+++ b/src/main/java/edu/princeton/cs/algs4/Out.java
@@ -16,11 +16,13 @@
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
import java.util.Locale;
/**
- * This class provides methods for writing strings and numbers to
- * various output streams, including standard output, file, and sockets.
+ * The
* For additional documentation, see
* Section 3.1 of
@@ -33,7 +35,7 @@
public class Out {
// force Unicode UTF-8 encoding; otherwise it's system dependent
- private static final String CHARSET_NAME = "UTF-8";
+ private static final Charset CHARSET = StandardCharsets.UTF_8;
// assume language = English, country = US for consistency with In
private static final Locale LOCALE = Locale.US;
@@ -46,13 +48,8 @@ public class Out {
* @param os the {@code OutputStream}
*/
public Out(OutputStream os) {
- try {
- OutputStreamWriter osw = new OutputStreamWriter(os, CHARSET_NAME);
- out = new PrintWriter(osw, true);
- }
- catch (IOException e) {
- e.printStackTrace();
- }
+ OutputStreamWriter osw = new OutputStreamWriter(os, CHARSET);
+ out = new PrintWriter(osw, true);
}
/**
@@ -66,15 +63,20 @@ public Out() {
* Initializes an output stream from a socket.
*
* @param socket the socket
+ * @throws IllegalArgumentException if {@code filename} is {@code null}
+ * @throws IllegalArgumentException if cannot create output stream from socket
*/
public Out(Socket socket) {
+ if (socket == null) {
+ throw new IllegalArgumentException("socket argument is null");
+ }
try {
OutputStream os = socket.getOutputStream();
- OutputStreamWriter osw = new OutputStreamWriter(os, CHARSET_NAME);
+ OutputStreamWriter osw = new OutputStreamWriter(os, CHARSET);
out = new PrintWriter(osw, true);
}
catch (IOException e) {
- e.printStackTrace();
+ throw new IllegalArgumentException("could not create output stream from socket", e);
}
}
@@ -82,15 +84,26 @@ public Out(Socket socket) {
* Initializes an output stream from a file.
*
* @param filename the name of the file
+ * @throws IllegalArgumentException if {@code filename} is {@code null}
+ * @throws IllegalArgumentException if {@code filename} is the empty string
+ * @throws IllegalArgumentException if cannot write the file {@code filename}
*/
public Out(String filename) {
+ if (filename == null) {
+ throw new IllegalArgumentException("filename argument is null");
+ }
+
+ if (filename.length() == 0) {
+ throw new IllegalArgumentException("filename argument is the empty string");
+ }
+
try {
OutputStream os = new FileOutputStream(filename);
- OutputStreamWriter osw = new OutputStreamWriter(os, CHARSET_NAME);
+ OutputStreamWriter osw = new OutputStreamWriter(os, CHARSET);
out = new PrintWriter(osw, true);
}
catch (IOException e) {
- e.printStackTrace();
+ throw new IllegalArgumentException("could not create file '" + filename + "' for writing", e);
}
}
@@ -193,7 +206,7 @@ public void print() {
/**
* Prints an object to this output stream and flushes this output stream.
- *
+ *
* @param x the object to print
*/
public void print(Object x) {
@@ -203,7 +216,7 @@ public void print(Object x) {
/**
* Prints a boolean to this output stream and flushes this output stream.
- *
+ *
* @param x the boolean to print
*/
public void print(boolean x) {
@@ -213,7 +226,7 @@ public void print(boolean x) {
/**
* Prints a character to this output stream and flushes this output stream.
- *
+ *
* @param x the character to print
*/
public void print(char x) {
@@ -223,7 +236,7 @@ public void print(char x) {
/**
* Prints a double to this output stream and flushes this output stream.
- *
+ *
* @param x the double to print
*/
public void print(double x) {
@@ -233,7 +246,7 @@ public void print(double x) {
/**
* Prints a float to this output stream and flushes this output stream.
- *
+ *
* @param x the float to print
*/
public void print(float x) {
@@ -243,7 +256,7 @@ public void print(float x) {
/**
* Prints an integer to this output stream and flushes this output stream.
- *
+ *
* @param x the integer to print
*/
public void print(int x) {
@@ -253,7 +266,7 @@ public void print(int x) {
/**
* Prints a long integer to this output stream and flushes this output stream.
- *
+ *
* @param x the long integer to print
*/
public void print(long x) {
@@ -263,7 +276,7 @@ public void print(long x) {
/**
* Prints a byte to this output stream and flushes this output stream.
- *
+ *
* @param x the byte to print
*/
public void print(byte x) {
@@ -319,7 +332,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/Particle.java b/src/main/java/edu/princeton/cs/algs4/Particle.java
index a86356b0f..6568e0a31 100644
--- a/src/main/java/edu/princeton/cs/algs4/Particle.java
+++ b/src/main/java/edu/princeton/cs/algs4/Particle.java
@@ -2,7 +2,7 @@
* Compilation: javac Particle.java
* Execution: none
* Dependencies: StdDraw.java
- *
+ *
* A particle moving in the unit box with a given position, velocity,
* radius, and mass.
*
@@ -19,9 +19,9 @@
* collisions with vertical walls, horizontal walls, and other particles.
* This data type is mutable because the position and velocity change.
*
- * For additional documentation,
- * see Section 6.1 of
- * Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
+ * For additional documentation,
+ * see Section 6.1 of
+ * Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
@@ -49,6 +49,10 @@ public class Particle {
* @param color the color
*/
public Particle(double rx, double ry, double vx, double vy, double radius, double mass, Color color) {
+ if (!(radius > 0.0)) throw new IllegalArgumentException("radius must be positive");
+ if (!(mass > 0.0)) throw new IllegalArgumentException("mass must be positive");
+ if (rx - radius < -1.0 || rx + radius > 1.0) throw new IllegalArgumentException("out-of-bounds rx");
+ if (ry - radius < -1.0 || ry + radius > 1.0) throw new IllegalArgumentException("out-of-bounds ry");
this.vx = vx;
this.vy = vy;
this.rx = rx;
@@ -57,18 +61,18 @@ public Particle(double rx, double ry, double vx, double vy, double radius, doubl
this.mass = mass;
this.color = color;
}
-
+
/**
* Initializes a particle with a random position and velocity.
* The position is uniform in the unit box; the velocity in
* either direciton is chosen uniformly at random.
*/
public Particle() {
- rx = StdRandom.uniform(0.0, 1.0);
- ry = StdRandom.uniform(0.0, 1.0);
- vx = StdRandom.uniform(-0.005, 0.005);
- vy = StdRandom.uniform(-0.005, 0.005);
- radius = 0.01;
+ rx = StdRandom.uniformDouble(0.0, 1.0);
+ ry = StdRandom.uniformDouble(0.0, 1.0);
+ vx = StdRandom.uniformDouble(-0.005, 0.005);
+ vy = StdRandom.uniformDouble(-0.005, 0.005);
+ radius = 0.02;
mass = 0.5;
color = Color.BLACK;
}
@@ -112,7 +116,7 @@ public int count() {
*
* @param that the other particle
* @return the amount of time for this particle to collide with the specified
- * particle, assuming no interening collisions;
+ * particle, assuming no interening collisions;
* {@code Double.POSITIVE_INFINITY} if the particles will not collide
*/
public double timeToHit(Particle that) {
@@ -124,12 +128,19 @@ public double timeToHit(Particle that) {
double dvdr = dx*dvx + dy*dvy;
if (dvdr > 0) return INFINITY;
double dvdv = dvx*dvx + dvy*dvy;
+ if (dvdv == 0) return INFINITY;
double drdr = dx*dx + dy*dy;
double sigma = this.radius + that.radius;
- double d = (dvdr*dvdr) - dvdv * (drdr - sigma*sigma);
+ double d = (dvdr*dvdr) - dvdv * (drdr - sigma*sigma);
// if (drdr < sigma*sigma) StdOut.println("overlapping particles");
if (d < 0) return INFINITY;
- return -(dvdr + Math.sqrt(d)) / dvdv;
+ double t = -(dvdr + Math.sqrt(d)) / dvdv;
+
+ // should't happen, but seems to be needed for some extreme inputs
+ // (floating-point precision when dvdv is close to 0, I think)
+ if (t <= 0) return INFINITY;
+
+ return t;
}
/**
@@ -137,13 +148,13 @@ public double timeToHit(Particle that) {
* wall, assuming no interening collisions.
*
* @return the amount of time for this particle to collide with a vertical wall,
- * assuming no interening collisions;
+ * assuming no interening collisions;
* {@code Double.POSITIVE_INFINITY} if the particle will not collide
* with a vertical wall
*/
public double timeToHitVerticalWall() {
if (vx > 0) return (1.0 - rx - radius) / vx;
- else if (vx < 0) return (radius - rx) / vx;
+ else if (vx < 0) return (radius - rx) / vx;
else return INFINITY;
}
@@ -152,7 +163,7 @@ public double timeToHitVerticalWall() {
* wall, assuming no interening collisions.
*
* @return the amount of time for this particle to collide with a horizontal wall,
- * assuming no interening collisions;
+ * assuming no interening collisions;
* {@code Double.POSITIVE_INFINITY} if the particle will not collide
* with a horizontal wall
*/
@@ -228,7 +239,7 @@ public double kineticEnergy() {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/PatriciaSET.java b/src/main/java/edu/princeton/cs/algs4/PatriciaSET.java
index e76ca2011..25ddbecdc 100644
--- a/src/main/java/edu/princeton/cs/algs4/PatriciaSET.java
+++ b/src/main/java/edu/princeton/cs/algs4/PatriciaSET.java
@@ -81,7 +81,7 @@
* implementation performs well, the source code was written with an emphasis
* on clarity, and not performance. PATRICIA performs admirably when its
* bit-testing loops are well tuned. Consider using the source code as a guide,
- * should you need to produce an optimized implementation, for anther key type,
+ * should you need to produce an optimized implementation, for another key type,
* or in another programming language.
*
* Other resources for PATRICIA:
* Other resources for PATRICIA:
- * Pixel (col, row) is column col and row row.
- * By default, the origin (0, 0) is the pixel in the top-left corner,
- * which is a common convention in image processing.
- * The method {@link #setOriginLowerLeft()} change the origin to the lower left.
+ * Use in the curriculum.
+ * The {@code Picture} class is intended for use in the
+ * curriculum once objects are introduced.
+ * The {@link StdPicture} class is intended for earlier use in
+ * the curriculum, before objects (but it can support only one
+ * picture at a time).
+ * See {@link GrayscalePicture} for a version that supports
+ * grayscale images.
+ *
+ *
+ * Getting started.
+ * To use this class, you must have {@code Picture} in your Java classpath.
+ * Here are three possible ways to do this:
+ *
+ * As a test, cut-and-paste the following short program into your editor:
+ *
+ * If you compile and execute the program, you should see a picture of a mandrill
+ * (a colorful monkey native to west-central Africa) in a window.
+ *
+ *
+ * Anatomy of an image.
+ * An image is a width-by-height grid of pixels, with pixel (0, 0)
+ * in the upper-left corner.
+ * Each pixel has a color that is represented using the RGB color model,
+ * which specifies the levels of red (R), green (G), and blue (B)
+ * on an integer scale from 0 to 255.
+ *
+ *
+ * Creating pictures.
+ * You can use the following constructors to create new {@code Picture} objects:
+ *
- * The {@code get()} and {@code set()} methods use {@link Color} objects to get
- * or set the color of the specified pixel.
- * The {@code getRGB()} and {@code setRGB()} methods use a 32-bit {@code int}
- * to encode the color, thereby avoiding the need to create temporary
- * {@code Color} objects. The red (R), green (G), and blue (B) components
- * are encoded using the least significant 24 bits.
+ * The first constructor read an image in a supported file format
+ * (typically JPEG, PNG, GIF, TIFF, and BMP)
+ * and initializes the picture to that image.
+ * The second constructor creates a width-by-height picture,
+ * with each pixel black.
+ *
+ *
+ * Getting and setting the colors of the individual pixels.
+ * You can use the following methods to get and set the color of a
+ * specified pixel:
+ *
+ * The first method returns the color of pixel (col, row)
+ * as a {@code Color} object.
+ * The second method sets the color of pixel (col, row) to
+ * the specified color.
+ *
+ * Iterating over the pixels.
+ * A common operation in image processing is to iterate over and process
+ * all of the pixels in an image.
+ * Here is a prototypical example that creates a grayscale version of a color image,
+ * using the NTSC formula
+ * Y = 0.299r + 0.587g + 0.114b.
+ * Note that if the red, green, and blue components of an RGB color
+ * are all equal, the color is a shade of gray.
+ * Transparency.
+ * Both the {@link Color} and {@code Picture} classes support
+ * transparency, using the alpha channel.
+ * The alpha value defines the transparency of a color, with 0 corresponding to
+ * completely transparent and 255 to completely opaque. If transparency is not
+ * explicitly used, the alpha values is 255.
+ *
+ * 32-bit color.
+ * Sometimes it is more convenient (or efficient) to manipulate the
+ * color of a pixel as a single 32-bit integers instead of four 8-bit components.
+ * The following methods support this:
+ *
+ * The alpha (A), red (R), green (G), and blue (B) components
+ * are encoded as a single 32-bit integer.
* Given a 32-bit {@code int} encoding the color, the following code extracts
- * the RGB components:
+ * the ARGB components:
*
- * A W-by- Coordinates.
+ * Pixel (col, row) is column col and row row.
+ * By default, the origin (0, 0) is the pixel in the upper-left corner.
+ * These are common conventions in image processing and consistent with Java's
+ * {@link java.awt.image.BufferedImage} data type. The following
+ * two methods allow you to change this convention:
+ * Saving files.
+ * The {@code Picture} class supports writing images to a supported
+ * file format (typically JPEG, PNG, GIF, TIFF, and BMP).
+ * You can save the picture to a file using these two methods:
+ * Alternatively, you can save the picture interactively
+ * by using the menu option File → Save from the picture window.
+ *
+ * File formats.
+ * The {@code Picture} class supports reading and writing images to any of the
+ * file formats supported by {@link javax.imageio} (typically JPEG, PNG,
+ * GIF, TIFF, and BMP).
+ * The file extensions corresponding to JPEG, PNG, GIF, TIFF, and BMP,
+ * are {@code .jpg}, {@code .png}, {@code .gif}, {@code .tif},
+ * and {@code .bmp}, respectively.
+ * The file formats JPEG and BMP do not support transparency.
+ *
+ * Memory usage.
+ * A W-by-H picture uses ~ 4 W H bytes of memory,
* since the color of each pixel is encoded as a 32-bit
+ *
+ * Additional documentation.
* For additional documentation, see
* Section 3.1 of
* Computer Science: An Interdisciplinary Approach
@@ -87,9 +236,11 @@
*/
public final class Picture implements ActionListener {
private BufferedImage image; // the rasterized image
- private JFrame frame; // on-screen view
- private String filename; // name of file
+ private JFrame jframe; // on-screen view
+ private String title; // window title (typically the name of the file)
private boolean isOriginUpperLeft = true; // location of origin
+ private boolean isVisible = false; // is the frame visible?
+ private boolean isDisposed = false; // has the window been disposed?
private final int width, height; // width and height
/**
@@ -98,16 +249,16 @@ public final class Picture implements ActionListener {
*
* @param width the width of the picture
* @param height the height of the picture
- * @throws IllegalArgumentException if {@code width} is negative
- * @throws IllegalArgumentException if {@code height} is negative
+ * @throws IllegalArgumentException if {@code width} is negative or zero
+ * @throws IllegalArgumentException if {@code height} is negative or zero
*/
public Picture(int width, int height) {
- if (width < 0) throw new IllegalArgumentException("width must be non-negative");
- if (height < 0) throw new IllegalArgumentException("height must be non-negative");
+ if (width <= 0) throw new IllegalArgumentException("width must be positive");
+ if (height <= 0) throw new IllegalArgumentException("height must be positive");
this.width = width;
this.height = height;
- image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
- // set to TYPE_INT_ARGB here and in next constructor to support transparency
+ this.title = width + "-by-" + height;
+ image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
}
/**
@@ -121,8 +272,8 @@ public Picture(Picture picture) {
width = picture.width();
height = picture.height();
- image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
- filename = picture.filename;
+ image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
+ title = picture.title;
isOriginUpperLeft = picture.isOriginUpperLeft;
for (int col = 0; col < width(); col++)
for (int row = 0; row < height(); row++)
@@ -130,46 +281,72 @@ public Picture(Picture picture) {
}
/**
- * Creates a picture by reading an image from a file or URL.
+ * Creates a picture by reading a JPEG, PNG, GIF , BMP, or TIFF image
+ * from a file or URL.
+ * The filetype extension must be {@code .jpg}, {@code .png}, {@code .gif},
+ * {@code .bmp}, or {@code .tif}.
*
- * @param filename the name of the file (.png, .gif, or .jpg) or URL.
- * @throws IllegalArgumentException if cannot read image
+ * @param filename the name of the file or URL
* @throws IllegalArgumentException if {@code filename} is {@code null}
+ * @throws IllegalArgumentException if cannot read image from file or URL
*/
public Picture(String filename) {
if (filename == null) throw new IllegalArgumentException("constructor argument is null");
+ if (filename.length() == 0) throw new IllegalArgumentException("constructor argument is the empty string");
- this.filename = filename;
+ title = filename;
try {
// try to read from file in working directory
File file = new File(filename);
if (file.isFile()) {
+ title = file.getName();
image = ImageIO.read(file);
}
- // now try to read from file in same directory as this .class file
else {
+
+ // resource relative to .class file
URL url = getClass().getResource(filename);
+
+ // resource relative to classloader root
+ if (url == null) {
+ url = getClass().getClassLoader().getResource(filename);
+ }
+
+ // or URL from web or jar
if (url == null) {
- url = new URL(filename);
+ URI uri = new URI(filename);
+ if (uri.isAbsolute()) url = uri.toURL();
+ else throw new IllegalArgumentException("could not read image: '" + filename + "'");
}
+
image = ImageIO.read(url);
}
if (image == null) {
- throw new IllegalArgumentException("could not read image file: " + filename);
+ throw new IllegalArgumentException("could not read image: '" + filename + "'");
}
width = image.getWidth(null);
height = image.getHeight(null);
+
+ // convert to ARGB if necessary
+ if (image.getType() != BufferedImage.TYPE_INT_ARGB) {
+ BufferedImage imageARGB = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
+ // the next line causes JVM app icon to previous display in Dock on OS X
+ imageARGB.createGraphics().drawImage(image, 0, 0, null);
+ image = imageARGB;
+ }
}
- catch (IOException ioe) {
- throw new IllegalArgumentException("could not open image file: " + filename, ioe);
+ catch (IOException | URISyntaxException e) {
+ throw new IllegalArgumentException("could not open image: " + filename, e);
}
}
/**
- * Creates a picture by reading the image from a PNG, GIF, or JPEG file.
+ * Creates a picture by reading the image from a JPEG, PNG, GIF, BMP, or TIFF file.
+ * The filetype extension must be {@code .jpg}, {@code .png}, {@code .gif},
+ * {@code .bmp}, or {@code .tif}.
*
* @param file the file
* @throws IllegalArgumentException if cannot read image
@@ -180,16 +357,54 @@ public Picture(File file) {
try {
image = ImageIO.read(file);
+
+ width = image.getWidth(null);
+ height = image.getHeight(null);
+ title = file.getName();
+
+ // convert to ARGB
+ if (image.getType() != BufferedImage.TYPE_INT_RGB) {
+ BufferedImage imageARGB = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
+ imageARGB.createGraphics().drawImage(image, 0, 0, null);
+ image = imageARGB;
+ }
}
catch (IOException ioe) {
throw new IllegalArgumentException("could not open file: " + file, ioe);
}
- if (image == null) {
- throw new IllegalArgumentException("could not read file: " + file);
- }
- width = image.getWidth(null);
- height = image.getHeight(null);
- filename = file.getName();
+ }
+
+ // create the GUI for viewing the image if needed
+ @SuppressWarnings("deprecation")
+ private JFrame createGUI() {
+ JFrame frame = new JFrame();
+ JMenuBar menuBar = new JMenuBar();
+ JMenu menu = new JMenu("File");
+ menuBar.add(menu);
+ JMenuItem menuItem1 = new JMenuItem(" Save... ");
+ menuItem1.addActionListener(this);
+ // Java 11: use getMenuShortcutKeyMaskEx()
+ // Java 8: use getMenuShortcutKeyMask()
+ menuItem1.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S,
+ Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx()));
+ menu.add(menuItem1);
+ frame.setJMenuBar(menuBar);
+
+ frame.setContentPane(getJLabel());
+ // f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
+ frame.setTitle(title);
+ frame.setResizable(false);
+ frame.pack();
+
+ frame.addWindowListener(new WindowAdapter() {
+ public void windowClosing(WindowEvent event){
+ isVisible = false;
+ isDisposed = true;
+ super.windowClosing(event);
+ }
+ });
+ return frame;
}
/**
@@ -205,52 +420,60 @@ public JLabel getJLabel() {
}
/**
- * Sets the origin to be the upper left pixel. This is the default.
+ * Sets the origin (0, 0) to be the upper left pixel. This is the default.
*/
public void setOriginUpperLeft() {
isOriginUpperLeft = true;
}
/**
- * Sets the origin to be the lower left pixel.
+ * Sets the origin (0, 0) to be the lower left pixel.
*/
public void setOriginLowerLeft() {
isOriginUpperLeft = false;
}
+ /**
+ * Displays the picture in a window on the screen.
+ */
+
+ // getMenuShortcutKeyMask() deprecated in Java 10 but its replacement
+ // getMenuShortcutKeyMaskEx() is not available in Java 8
+ @SuppressWarnings("deprecation")
/**
* Displays the picture in a window on the screen.
*/
public void show() {
+ if (jframe == null && !isDisposed) {
+ jframe = createGUI();
+ isVisible = true;
+ jframe.setVisible(true);
+ jframe.repaint();
+ }
- // create the GUI for viewing the image if needed
- if (frame == null) {
- frame = new JFrame();
-
- JMenuBar menuBar = new JMenuBar();
- JMenu menu = new JMenu("File");
- menuBar.add(menu);
- JMenuItem menuItem1 = new JMenuItem(" Save... ");
- menuItem1.addActionListener(this);
- menuItem1.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S,
- Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
- menu.add(menuItem1);
- frame.setJMenuBar(menuBar);
-
-
-
- frame.setContentPane(getJLabel());
- // f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
- frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
- if (filename == null) frame.setTitle(width + "-by-" + height);
- else frame.setTitle(filename);
- frame.setResizable(false);
- frame.pack();
- frame.setVisible(true);
+ if (jframe != null && !isDisposed) {
+ isVisible = true;
+ jframe.setVisible(true);
+ jframe.repaint();
}
+ }
- // draw
- frame.repaint();
+ /**
+ * Hides the window containing the picture.
+ */
+ public void hide() {
+ if (jframe != null) {
+ isVisible = false;
+ jframe.setVisible(false);
+ }
+ }
+
+ /**
+ * Is the window containing the picture visible?
+ * @return {@code true} if the picture is visible, and {@code false} otherwise
+ */
+ public boolean isVisible() {
+ return isVisible;
}
/**
@@ -273,40 +496,40 @@ public int width() {
private void validateRowIndex(int row) {
if (row < 0 || row >= height())
- throw new IllegalArgumentException("row index must be between 0 and " + (height() - 1) + ": " + row);
+ throw new IndexOutOfBoundsException("row index must be between 0 and " + (height() - 1) + ": " + row);
}
private void validateColumnIndex(int col) {
if (col < 0 || col >= width())
- throw new IllegalArgumentException("column index must be between 0 and " + (width() - 1) + ": " + col);
+ throw new IndexOutOfBoundsException("column index must be between 0 and " + (width() - 1) + ": " + col);
}
/**
- * Returns the color of pixel ({@code col}, {@code row}) as a {@link java.awt.Color}.
+ * Returns the color of pixel ({@code col}, {@code row}) as a {@link java.awt.Color} object.
*
* @param col the column index
* @param row the row index
* @return the color of pixel ({@code col}, {@code row})
- * @throws IllegalArgumentException unless both {@code 0 <= col < width} and {@code 0 <= row < height}
+ * @throws IndexOutOfBoundsException unless both {@code 0 <= col < width} and {@code 0 <= row < height}
*/
public Color get(int col, int row) {
validateColumnIndex(col);
validateRowIndex(row);
- int rgb = getRGB(col, row);
- return new Color(rgb);
+ int argb = getARGB(col, row);
+ return new Color(argb, true);
}
/**
- * Returns the color of pixel ({@code col}, {@code row}) as an {@code int}.
+ * Returns the ARGB color of pixel ({@code col}, {@code row}) as a 32-bit integer.
* Using this method can be more efficient than {@link #get(int, int)} because
* it does not create a {@code Color} object.
*
* @param col the column index
* @param row the row index
- * @return the integer representation of the color of pixel ({@code col}, {@code row})
- * @throws IllegalArgumentException unless both {@code 0 <= col < width} and {@code 0 <= row < height}
+ * @return the 32-bit integer representation of the ARGB color of pixel ({@code col}, {@code row})
+ * @throws IndexOutOfBoundsException unless both {@code 0 <= col < width} and {@code 0 <= row < height}
*/
- public int getRGB(int col, int row) {
+ public int getARGB(int col, int row) {
validateColumnIndex(col);
validateRowIndex(row);
if (isOriginUpperLeft) return image.getRGB(col, row);
@@ -314,39 +537,40 @@ public int getRGB(int col, int row) {
}
/**
- * Sets the color of pixel ({@code col}, {@code row}) to given color.
+ * Sets the color of pixel ({@code col}, {@code row}) to the given color.
*
* @param col the column index
* @param row the row index
* @param color the color
- * @throws IllegalArgumentException unless both {@code 0 <= col < width} and {@code 0 <= row < height}
+ * @throws IndexOutOfBoundsException unless both {@code 0 <= col < width} and {@code 0 <= row < height}
* @throws IllegalArgumentException if {@code color} is {@code null}
*/
public void set(int col, int row, Color color) {
validateColumnIndex(col);
validateRowIndex(row);
if (color == null) throw new IllegalArgumentException("color argument is null");
- int rgb = color.getRGB();
- setRGB(col, row, rgb);
+ int argb = color.getRGB();
+ setARGB(col, row, argb);
}
/**
- * Sets the color of pixel ({@code col}, {@code row}) to given color.
+ * Sets the color of pixel ({@code col}, {@code row}) to the given ARGB color.
*
* @param col the column index
* @param row the row index
- * @param rgb the integer representation of the color
- * @throws IllegalArgumentException unless both {@code 0 <= col < width} and {@code 0 <= row < height}
+ * @param argb the 32-bit integer representation of the color
+ * @throws IndexOutOfBoundsException unless both {@code 0 <= col < width} and {@code 0 <= row < height}
*/
- public void setRGB(int col, int row, int rgb) {
+ public void setARGB(int col, int row, int argb) {
validateColumnIndex(col);
validateRowIndex(row);
- if (isOriginUpperLeft) image.setRGB(col, row, rgb);
- else image.setRGB(col, height - row - 1, rgb);
+ if (isOriginUpperLeft) image.setRGB(col, row, argb);
+ else image.setRGB(col, height - row - 1, argb);
}
/**
- * Returns true if this picture is equal to the argument picture.
+ * Returns {@code true} if this picture is equal to the argument picture,
+ * and {@code false} otherwise.
*
* @param other the other picture
* @return {@code true} if this picture is the same dimension as {@code other}
@@ -361,7 +585,7 @@ public boolean equals(Object other) {
if (this.height() != that.height()) return false;
for (int col = 0; col < width(); col++)
for (int row = 0; row < height(); row++)
- if (this.getRGB(col, row) != that.getRGB(col, row)) return false;
+ if (this.getARGB(col, row) != that.getARGB(col, row)) return false;
return true;
}
@@ -378,7 +602,7 @@ public String toString() {
sb.append(width +"-by-" + height + " picture (RGB values given in hex)\n");
for (int row = 0; row < height; row++) {
for (int col = 0; col < width; col++) {
- int rgb = 0;
+ int rgb;
if (isOriginUpperLeft) rgb = image.getRGB(col, row);
else rgb = image.getRGB(col, height - row - 1);
sb.append(String.format("#%06X ", rgb & 0xFFFFFF));
@@ -398,40 +622,86 @@ public int hashCode() {
throw new UnsupportedOperationException("hashCode() is not supported because pictures are mutable");
}
+ /**
+ * Sets the title of this picture.
+ * @param title the title
+ * @throws IllegalArgumentException if {@code title} is {@code null}
+ */
+ public void setTitle(String title) {
+ if (title == null) throw new IllegalArgumentException("title is null");
+ this.title = title;
+ }
+
+ // does this picture use transparency (i.e., alpha < 255 for some pixel)?
+ private boolean hasAlpha() {
+ for (int col = 0; col < width; col++) {
+ for (int row = 0; row < height; row++) {
+ int argb = image.getRGB(col, row);
+ int alpha = (argb >> 24) & 0xFF;
+ if (alpha != 255) return true;
+ }
+ }
+ return false;
+ }
+
/**
- * Saves the picture to a file in either PNG or JPEG format.
- * The filetype extension must be either .png or .jpg.
+ * Saves the picture to a file in a supported file format
+ * (typically JPEG, PNG, GIF, TIFF, and BMP).
+ * The filetype extension must be {@code .jpg}, {@code .png}, {@code .gif},
+ * {@code .bmp}, or {@code .tif}.
+ * If the file format does not support transparency (such as JPEG
+ * or BMP), it will be converted to be opaque (with purely
+ * transparent pixels converted to black).
*
- * @param name the name of the file
- * @throws IllegalArgumentException if {@code name} is {@code null}
+ * @param filename the name of the file
+ * @throws IllegalArgumentException if {@code filename} is {@code null}
+ * @throws IllegalArgumentException if {@code filename} is the empty string
+ * @throws IllegalArgumentException if {@code filename} has invalid filetype extension
+ * @throws IllegalArgumentException if cannot write the file {@code filename}
*/
- public void save(String name) {
- if (name == null) throw new IllegalArgumentException("argument to save() is null");
- save(new File(name));
- filename = name;
+ public void save(String filename) {
+ if (filename == null) throw new IllegalArgumentException("argument to save() is null");
+ if (filename.length() == 0) throw new IllegalArgumentException("argument to save() is the empty string");
+ File file = new File(filename);
+ save(file);
}
/**
- * Saves the picture to a file in a PNG or JPEG image format.
+ * Saves the picture to a file in a supported file format
+ * (typically JPEG, PNG, GIF, TIFF, and BMP).
+ * The filetype extension must be {@code .jpg}, {@code .png}, {@code .gif},
+ * {@code .bmp}, or {@code .tif}.
+ * If the file format does not support transparency (such as JPEG
+ * or BMP), it will be converted to be opaque (with purely
+ * transparent pixels converted to black).
*
* @param file the file
* @throws IllegalArgumentException if {@code file} is {@code null}
*/
public void save(File file) {
if (file == null) throw new IllegalArgumentException("argument to save() is null");
- filename = file.getName();
- if (frame != null) frame.setTitle(filename);
- String suffix = filename.substring(filename.lastIndexOf('.') + 1);
- if ("jpg".equalsIgnoreCase(suffix) || "png".equalsIgnoreCase(suffix)) {
- try {
- ImageIO.write(image, suffix, file);
- }
- catch (IOException e) {
- e.printStackTrace();
- }
+ title = file.getName();
+
+ String suffix = title.substring(title.lastIndexOf('.') + 1);
+ if (!title.contains(".") || suffix.length() == 0) {
+ throw new IllegalArgumentException("The filename '" + title + "' has no filetype extension, such as .jpg or .png");
}
- else {
- System.out.println("Error: filename must end in .jpg or .png");
+
+ try {
+ // for formats that support transparency (e.g., PNG and GIF)
+ if (ImageIO.write(image, suffix, file)) return;
+
+ // for formats that don't support transparency (e.g., JPG and BMP)
+ // create BufferedImage in RGB format and use white background
+ BufferedImage imageRGB = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
+ imageRGB.createGraphics().drawImage(image, 0, 0, Color.WHITE, null);
+ if (ImageIO.write(imageRGB, suffix, file)) return;
+
+ // failed to save the file; probably wrong format
+ throw new IllegalArgumentException("The filetype '" + suffix + "' is not supported");
+ }
+ catch (IOException e) {
+ throw new IllegalArgumentException("could not write file '" + title + "'", e);
}
}
@@ -439,12 +709,19 @@ public void save(File file) {
* Opens a save dialog box when the user selects "Save As" from the menu.
*/
@Override
- public void actionPerformed(ActionEvent e) {
- FileDialog chooser = new FileDialog(frame,
- "Use a .png or .jpg extension", FileDialog.SAVE);
+ public void actionPerformed(ActionEvent event) {
+ FileDialog chooser = new FileDialog(jframe,
+ "The filetype extension must be either .jpg or .png", FileDialog.SAVE);
chooser.setVisible(true);
- if (chooser.getFile() != null) {
- save(chooser.getDirectory() + File.separator + chooser.getFile());
+ String selectedDirectory = chooser.getDirectory();
+ String selectedFilename = chooser.getFile();
+ if (selectedDirectory != null && selectedFilename != null) {
+ try {
+ save(selectedDirectory + selectedFilename);
+ }
+ catch (IllegalArgumentException e) {
+ System.err.println(e.getMessage());
+ }
}
}
@@ -463,9 +740,8 @@ public static void main(String[] args) {
}
-
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/PictureDump.java b/src/main/java/edu/princeton/cs/algs4/PictureDump.java
index cf13a573c..09d5d0ff1 100644
--- a/src/main/java/edu/princeton/cs/algs4/PictureDump.java
+++ b/src/main/java/edu/princeton/cs/algs4/PictureDump.java
@@ -3,11 +3,11 @@
* Execution: java PictureDump width height < file
* Dependencies: BinaryStdIn.java Picture.java
* Data file: http://introcs.cs.princeton.edu/stdlib/abra.txt
- *
+ *
* Reads in a binary file and writes out the bits as w-by-h picture,
* with the 1 bits in black and the 0 bits in white.
*
- * % more abra.txt
+ * % more abra.txt
* ABRACADABRA!
*
* % java PictureDump 16 6 < abra.txt
@@ -24,7 +24,7 @@
* of a binary file as a black-and-white picture.
*
* For additional documentation,
- * see Section 5.5 of
+ * see Section 5.5 of
* Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
*
* See also {@link BinaryDump} and {@link HexDump}.
@@ -66,7 +66,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/Point2D.java b/src/main/java/edu/princeton/cs/algs4/Point2D.java
index 53847978d..c58e905a1 100644
--- a/src/main/java/edu/princeton/cs/algs4/Point2D.java
+++ b/src/main/java/edu/princeton/cs/algs4/Point2D.java
@@ -17,13 +17,13 @@
* The {@code Point} class is an immutable data type to encapsulate a
* two-dimensional point with real-value coordinates.
*
- * Note: in order to deal with the difference behavior of double and
+ * Note: in order to deal with the difference behavior of double and
* Double with respect to -0.0 and +0.0, the Point2D constructor converts
* any coordinates that are -0.0 to +0.0.
*
- * For additional documentation,
- * see Section 1.2 of
- * Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
+ * For additional documentation,
+ * see Section 1.2 of
+ * Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
@@ -86,7 +86,7 @@ public double y() {
/**
* Returns the polar radius of this point.
- * @return the polar radius of this point in polar coordiantes: sqrt(x*x + y*y)
+ * @return the polar radius of this point in polar coordinates: sqrt(x*x + y*y)
*/
public double r() {
return Math.sqrt(x*x + y*y);
@@ -94,7 +94,7 @@ public double r() {
/**
* Returns the angle of this point in polar coordinates.
- * @return the angle (in radians) of this point in polar coordiantes (between –π and π)
+ * @return the angle (in radians) of this point in polar coordinates (between –π and π)
*/
public double theta() {
return Math.atan2(y, x);
@@ -115,7 +115,7 @@ private double angleTo(Point2D that) {
* @param a first point
* @param b second point
* @param c third point
- * @return { -1, 0, +1 } if a→b→c is a { clockwise, collinear; counterclocwise } turn.
+ * @return { -1, 0, +1 } if a→b→c is a { clockwise, collinear; counterclockwise } turn.
*/
public static int ccw(Point2D a, Point2D b, Point2D c) {
double area2 = (b.x-a.x)*(c.y-a.y) - (b.y-a.y)*(c.x-a.x);
@@ -207,18 +207,14 @@ public Comparator
+ * This computes correct results if all arithmetic performed is
+ * without overflow.
+ *
* For additional documentation,
* see Section 9.9 of
* Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
@@ -140,10 +143,10 @@ public Polynomial compose(Polynomial that) {
}
- /**
+ /**
* Compares this polynomial to the specified polynomial.
- *
- * @param other the other polynoimal
+ *
+ * @param other the other polynomial
* @return {@code true} if this polynomial equals {@code other};
* {@code false} otherwise
*/
@@ -192,7 +195,7 @@ public int evaluate(int x) {
* @param that the other point
* @return the value {@code 0} if this polynomial is equal to the argument
* polynomial (precisely when {@code equals()} returns {@code true});
- * a negative integer if this polynomialt is less than the argument
+ * a negative integer if this polynomial is less than the argument
* polynomial; and a positive integer if this polynomial is greater than the
* argument point
*/
@@ -232,7 +235,7 @@ public String toString() {
*
* @param args the command-line arguments (none)
*/
- public static void main(String[] args) {
+ public static void main(String[] args) {
Polynomial zero = new Polynomial(0, 0);
Polynomial p1 = new Polynomial(4, 3);
@@ -266,7 +269,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/PrimMST.java b/src/main/java/edu/princeton/cs/algs4/PrimMST.java
index cf90a485d..372e803a0 100644
--- a/src/main/java/edu/princeton/cs/algs4/PrimMST.java
+++ b/src/main/java/edu/princeton/cs/algs4/PrimMST.java
@@ -9,7 +9,7 @@
*
* Compute a minimum spanning forest using Prim's algorithm.
*
- * % java PrimMST tinyEWG.txt
+ * % java PrimMST tinyEWG.txt
* 1-7 0.19000
* 0-2 0.26000
* 2-3 0.17000
@@ -44,17 +44,24 @@
* The edge weights can be positive, zero, or negative and need not
* be distinct. If the graph is not connected, it computes a minimum
* spanning forest, which is the union of minimum spanning trees
- * in each connected component. The {@code weight()} method returns the
+ * in each connected component. The {@code weight()} method returns the
* weight of a minimum spanning tree and the {@code edges()} method
* returns its edges.
*
* This implementation uses Prim's algorithm with an indexed
* binary heap.
- * The constructor takes time proportional to E log V
- * and extra space (not including the graph) proportional to V,
- * where V is the number of vertices and E is the number of edges.
- * Afterwards, the {@code weight()} method takes constant time
- * and the {@code edges()} method takes time proportional to V.
+ * The constructor takes Θ(E log V) time in
+ * the worst case, where V is the number of
+ * vertices and E is the number of edges.
+ * Each instance method takes Θ(1) time.
+ * It uses Θ(V) extra space (not including the
+ * edge-weighted graph).
+ *
+ * This {@code weight()} method correctly computes the weight of the MST
+ * if all arithmetic performed is without floating-point rounding error
+ * or arithmetic overflow.
+ * This is the case if all edge weights are non-negative integers
+ * and the weight of the MST does not exceed 252.
*
* For additional documentation,
* see Section 4.3 of
@@ -66,7 +73,7 @@
* @author Kevin Wayne
*/
public class PrimMST {
- private static final double FLOATING_POINT_EPSILON = 1E-12;
+ private static final double FLOATING_POINT_EPSILON = 1.0E-12;
private Edge[] edgeTo; // edgeTo[v] = shortest edge from tree vertex to non-tree vertex
private double[] distTo; // distTo[v] = weight of shortest such edge
@@ -162,7 +169,7 @@ private boolean check(EdgeWeightedGraph G) {
UF uf = new UF(G.V());
for (Edge e : edges()) {
int v = e.either(), w = e.other(v);
- if (uf.connected(v, w)) {
+ if (uf.find(v) == uf.find(w)) {
System.err.println("Not a forest");
return false;
}
@@ -172,7 +179,7 @@ private boolean check(EdgeWeightedGraph G) {
// check that it is a spanning forest
for (Edge e : G.edges()) {
int v = e.either(), w = e.other(v);
- if (!uf.connected(v, w)) {
+ if (uf.find(v) != uf.find(w)) {
System.err.println("Not a spanning forest");
return false;
}
@@ -191,7 +198,7 @@ private boolean check(EdgeWeightedGraph G) {
// check that e is min weight edge in crossing cut
for (Edge f : G.edges()) {
int x = f.either(), y = f.other(x);
- if (!uf.connected(x, y)) {
+ if (uf.find(x) != uf.find(y)) {
if (f.weight() < e.weight()) {
System.err.println("Edge " + f + " violates cut optimality conditions");
return false;
@@ -223,7 +230,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/Queue.java b/src/main/java/edu/princeton/cs/algs4/Queue.java
index 4275e4c6e..713c97230 100644
--- a/src/main/java/edu/princeton/cs/algs4/Queue.java
+++ b/src/main/java/edu/princeton/cs/algs4/Queue.java
@@ -2,11 +2,11 @@
* Compilation: javac Queue.java
* Execution: java Queue < input.txt
* Dependencies: StdIn.java StdOut.java
- * Data files: https://algs4.cs.princeton.edu/13stacks/tobe.txt
+ * Data files: https://algs4.cs.princeton.edu/13stacks/tobe.txt
*
* A generic queue, implemented using a linked list.
*
- * % java Queue < tobe.txt
+ * % java Queue < tobe.txt
* to be or not to be (2 left on queue)
*
******************************************************************************/
@@ -37,7 +37,7 @@
* @author Robert Sedgewick
* @author Kevin Wayne
*
- * @param
- * For additional documentation,
- * see Section 2.3 of
- * Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
+ * For additional documentation, see
+ * Section 2.3
+ * of Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
@@ -55,7 +55,7 @@ public static void sort(Comparable[] a) {
}
// quicksort the subarray from a[lo] to a[hi]
- private static void sort(Comparable[] a, int lo, int hi) {
+ private static void sort(Comparable[] a, int lo, int hi) {
if (hi <= lo) return;
int j = partition(a, lo, hi);
sort(a, lo, j-1);
@@ -69,7 +69,7 @@ private static int partition(Comparable[] a, int lo, int hi) {
int i = lo;
int j = hi + 1;
Comparable v = a[lo];
- while (true) {
+ while (true) {
// find item on lo to swap
while (less(a[++i], v)) {
@@ -124,13 +124,13 @@ public static Comparable select(Comparable[] a, int k) {
/***************************************************************************
* Helper sorting functions.
***************************************************************************/
-
+
// is v < w ?
private static boolean less(Comparable v, Comparable w) {
if (v == w) return false; // optimization when reference equals
return v.compareTo(w) < 0;
}
-
+
// exchange a[i] and a[j]
private static void exch(Object[] a, int i, int j) {
Object swap = a[i];
@@ -161,8 +161,8 @@ private static void show(Comparable[] a) {
}
/**
- * Reads in a sequence of strings from standard input; quicksorts them;
- * and prints them to standard output in ascending order.
+ * Reads in a sequence of strings from standard input; quicksorts them;
+ * and prints them to standard output in ascending order.
* Shuffles the array and then prints the strings again to
* standard output, but this time, using the select method.
*
@@ -188,7 +188,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/Quick3string.java b/src/main/java/edu/princeton/cs/algs4/Quick3string.java
index b116650af..41ecfaf4d 100644
--- a/src/main/java/edu/princeton/cs/algs4/Quick3string.java
+++ b/src/main/java/edu/princeton/cs/algs4/Quick3string.java
@@ -1,7 +1,7 @@
/******************************************************************************
* Compilation: javac Quick3string.java
* Execution: java Quick3string < input.txt
- * Dependencies: StdIn.java StdOut.java
+ * Dependencies: StdIn.java StdOut.java
* Data files: https://algs4.cs.princeton.edu/51radix/words3.txt
* https://algs4.cs.princeton.edu/51radix/shells.txt
*
@@ -43,9 +43,9 @@ public class Quick3string {
private static final int CUTOFF = 15; // cutoff to insertion sort
// do not instantiate
- private Quick3string() { }
+ private Quick3string() { }
- /**
+ /**
* Rearranges the array of strings in ascending order.
*
* @param a the array to be sorted
@@ -57,7 +57,7 @@ public static void sort(String[] a) {
}
// return the dth character of s, -1 if d = length of s
- private static int charAt(String s, int d) {
+ private static int charAt(String s, int d) {
assert d >= 0 && d <= s.length();
if (d == s.length()) return -1;
return s.charAt(d);
@@ -65,7 +65,7 @@ private static int charAt(String s, int d) {
// 3-way string quicksort a[lo..hi] starting at dth character
- private static void sort(String[] a, int lo, int hi, int d) {
+ private static void sort(String[] a, int lo, int hi, int d) {
// cutoff to insertion sort for small subarrays
if (hi <= lo + CUTOFF) {
@@ -83,7 +83,7 @@ private static void sort(String[] a, int lo, int hi, int d) {
else i++;
}
- // a[lo..lt-1] < v = a[lt..gt] < a[gt+1..hi].
+ // a[lo..lt-1] < v = a[lt..gt] < a[gt+1..hi].
sort(a, lo, lt-1, d);
if (v >= 0) sort(a, lt, gt, d+1);
sort(a, gt+1, hi, d);
@@ -107,7 +107,7 @@ private static void exch(String[] a, int i, int j) {
// DEPRECATED BECAUSE OF SLOW SUBSTRING EXTRACTION IN JAVA 7
// private static boolean less(String v, String w, int d) {
// assert v.substring(0, d).equals(w.substring(0, d));
- // return v.substring(d).compareTo(w.substring(d)) < 0;
+ // return v.substring(d).compareTo(w.substring(d)) < 0;
// }
// is v less than w, starting at character d
@@ -151,7 +151,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/Quick3way.java b/src/main/java/edu/princeton/cs/algs4/Quick3way.java
index e8583b546..44b7d1450 100644
--- a/src/main/java/edu/princeton/cs/algs4/Quick3way.java
+++ b/src/main/java/edu/princeton/cs/algs4/Quick3way.java
@@ -4,18 +4,18 @@
* Dependencies: StdOut.java StdIn.java
* Data files: https://algs4.cs.princeton.edu/23quicksort/tiny.txt
* https://algs4.cs.princeton.edu/23quicksort/words3.txt
- *
+ *
* Sorts a sequence of strings from standard input using 3-way quicksort.
- *
+ *
* % more tiny.txt
* S O R T E X A M P L E
*
* % java Quick3way < tiny.txt
* A E E L M O P R S T X [ one string per line ]
- *
+ *
* % more words3.txt
* bed bug dad yes zoo ... all bad yet
- *
+ *
* % java Quick3way < words3.txt
* all bad bed bug dad ... yes yet zoo [ one string per line ]
*
@@ -27,9 +27,9 @@
* The {@code Quick3way} class provides static methods for sorting an
* array using quicksort with 3-way partitioning.
*
- * For additional documentation,
- * see Section 2.3 of
- * Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
+ * For additional documentation, see
+ * Section 2.3
+ * of Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
@@ -50,7 +50,7 @@ public static void sort(Comparable[] a) {
}
// quicksort the subarray a[lo .. hi] using 3-way partitioning
- private static void sort(Comparable[] a, int lo, int hi) {
+ private static void sort(Comparable[] a, int lo, int hi) {
if (hi <= lo) return;
int lt = lo, gt = hi;
Comparable v = a[lo];
@@ -62,7 +62,7 @@ private static void sort(Comparable[] a, int lo, int hi) {
else i++;
}
- // a[lo..lt-1] < v = a[lt..gt] < a[gt+1..hi].
+ // a[lo..lt-1] < v = a[lt..gt] < a[gt+1..hi].
sort(a, lo, lt-1);
sort(a, gt+1, hi);
assert isSorted(a, lo, hi);
@@ -73,12 +73,12 @@ private static void sort(Comparable[] a, int lo, int hi) {
/***************************************************************************
* Helper sorting functions.
***************************************************************************/
-
+
// is v < w ?
private static boolean less(Comparable v, Comparable w) {
return v.compareTo(w) < 0;
}
-
+
// exchange a[i] and a[j]
private static void exch(Object[] a, int i, int j) {
Object swap = a[i];
@@ -111,7 +111,7 @@ private static void show(Comparable[] a) {
/**
* Reads in a sequence of strings from standard input; 3-way
- * quicksorts them; and prints them to standard output in ascending order.
+ * quicksorts them; and prints them to standard output in ascending order.
*
* @param args the command-line arguments
*/
@@ -124,7 +124,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/QuickBentleyMcIlroy.java b/src/main/java/edu/princeton/cs/algs4/QuickBentleyMcIlroy.java
index 60a716b5d..fe285eb1b 100644
--- a/src/main/java/edu/princeton/cs/algs4/QuickBentleyMcIlroy.java
+++ b/src/main/java/edu/princeton/cs/algs4/QuickBentleyMcIlroy.java
@@ -4,13 +4,13 @@
* Dependencies: StdOut.java StdIn.java
* Data files: https://algs4.cs.princeton.edu/23quicksort/tiny.txt
* https://algs4.cs.princeton.edu/23quicksort/words3.txt
- *
+ *
* Uses the Bentley-McIlroy 3-way partitioning scheme,
* chooses the partitioning element using Tukey's ninther,
* and cuts off to insertion sort.
*
* Reference: Engineering a Sort Function by Jon L. Bentley
- * and M. Douglas McIlroy. Softwae-Practice and Experience,
+ * and M. Douglas McIlroy. Software-Practice and Experience,
* Vol. 23 (11), 1249-1265 (November 1993).
*
******************************************************************************/
@@ -22,9 +22,9 @@
* an array using an optimized version of quicksort (using Bentley-McIlroy
* 3-way partitioning, Tukey's ninther, and cutoff to insertion sort).
*
- * For additional documentation,
- * see Section 2.3 of
- * Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
+ * For additional documentation, see
+ * Section 2.3
+ * of Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
@@ -48,7 +48,7 @@ public static void sort(Comparable[] a) {
sort(a, 0, a.length - 1);
}
- private static void sort(Comparable[] a, int lo, int hi) {
+ private static void sort(Comparable[] a, int lo, int hi) {
int n = hi - lo + 1;
// cutoff to insertion sort
@@ -69,7 +69,7 @@ else if (n <= MEDIAN_OF_3_CUTOFF) {
int mid = lo + n/2;
int m1 = median3(a, lo, lo + eps, lo + eps + eps);
int m2 = median3(a, mid - eps, mid, mid + eps);
- int m3 = median3(a, hi - eps - eps, hi - eps, hi);
+ int m3 = median3(a, hi - eps - eps, hi - eps, hi);
int ninther = median3(a, m1, m2, m3);
exch(a, ninther, lo);
}
@@ -124,7 +124,7 @@ private static int median3(Comparable[] a, int i, int j, int k) {
/***************************************************************************
* Helper sorting functions.
***************************************************************************/
-
+
// is v < w ?
private static boolean less(Comparable v, Comparable w) {
if (v == w) return false; // optimization when reference equal
@@ -136,7 +136,7 @@ private static boolean eq(Comparable v, Comparable w) {
if (v == w) return true; // optimization when reference equal
return v.compareTo(w) == 0;
}
-
+
// exchange a[i] and a[j]
private static void exch(Object[] a, int i, int j) {
Object swap = a[i];
@@ -163,8 +163,8 @@ private static void show(Comparable[] a) {
/**
* Reads in a sequence of strings from standard input; quicksorts them
- * (using an optimized version of quicksort);
- * and prints them to standard output in ascending order.
+ * (using an optimized version of quicksort);
+ * and prints them to standard output in ascending order.
*
* @param args the command-line arguments
*/
@@ -178,7 +178,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/QuickFindUF.java b/src/main/java/edu/princeton/cs/algs4/QuickFindUF.java
index 6f364a96a..8891b8840 100644
--- a/src/main/java/edu/princeton/cs/algs4/QuickFindUF.java
+++ b/src/main/java/edu/princeton/cs/algs4/QuickFindUF.java
@@ -15,65 +15,47 @@
/**
* The {@code QuickFindUF} class represents a union–find data type
* (also known as the disjoint-sets data type).
- * It supports the union and find operations,
- * along with a connected operation for determining whether
- * two sites are in the same component and a count operation that
- * returns the total number of components.
+ * It supports the classic union and find operations,
+ * along with a count operation that returns the total number
+ * of sets.
*
- * The union–find data type models connectivity among a set of n
- * sites, named 0 through n–1.
- * The is-connected-to relation must be an
- * equivalence relation:
+ * The union–find data type models a collection of sets containing
+ * n elements, with each element in exactly one set.
+ * The elements are named 0 through n–1.
+ * Initially, there are n sets, with each element in its
+ * own set. The canonical element of a set
+ * (also known as the root, identifier,
+ * leader, or set representative)
+ * is one distinguished element in the set. Here is a summary of
+ * the operations:
*
- * An equivalence relation partitions the sites into
- * equivalence classes (or components). In this case,
- * two sites are in the same component if and only if they are connected.
- * Both sites and components are identified with integers between 0 and
- * n–1.
- * Initially, there are n components, with each site in its
- * own component. The component identifier of a component
- * (also known as the root, canonical element, leader,
- * or set representative) is one of the sites in the component:
- * two sites have the same component identifier if and only if they are
- * in the same component.
- *
- * The component identifier of a component can change
- * only when the component itself changes during a call to
- * union—it cannot change during a call
- * to find, connected, or count.
+ * This implementation uses quick find.
+ * The constructor takes Θ(n) time, where n
+ * is the number of sites.
+ * The find, connected, and count
+ * operations take Θ(1) time; the union operation
+ * takes Θ(n) time.
*
- * This implementation uses quick find.
- * Initializing a data structure with n sites takes linear time.
- * Afterwards, the find, connected, and count
- * operations take constant time but the union operation
- * takes linear time.
- * For alternate implementations of the same API, see
+ * For alternative implementations of the same API, see
* {@link UF}, {@link QuickUnionUF}, and {@link WeightedQuickUnionUF}.
- *
- *
- * For additional documentation, see Section 1.5 of
+ * For additional documentation, see
+ * Section 1.5 of
* Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
*
* @author Robert Sedgewick
@@ -85,11 +67,11 @@ public class QuickFindUF {
private int count; // number of components
/**
- * Initializes an empty union–find data structure with {@code n} sites
- * {@code 0} through {@code n-1}. Each site is initially in its own
- * component.
+ * Initializes an empty union-find data structure with
+ * {@code n} elements {@code 0} through {@code n-1}.
+ * Initially, each element is in its own set.
*
- * @param n the number of sites
+ * @param n the number of elements
* @throws IllegalArgumentException if {@code n < 0}
*/
public QuickFindUF(int n) {
@@ -100,19 +82,19 @@ public QuickFindUF(int n) {
}
/**
- * Returns the number of components.
+ * Returns the number of sets.
*
- * @return the number of components (between {@code 1} and {@code n})
+ * @return the number of sets (between {@code 1} and {@code n})
*/
public int count() {
return count;
}
-
+
/**
- * Returns the component identifier for the component containing site {@code p}.
+ * Returns the canonical element of the set containing element {@code p}.
*
- * @param p the integer representing one site
- * @return the component identifier for the component containing site {@code p}
+ * @param p an element
+ * @return the canonical element of the set containing {@code p}
* @throws IllegalArgumentException unless {@code 0 <= p < n}
*/
public int find(int p) {
@@ -129,27 +111,29 @@ private void validate(int p) {
}
/**
- * Returns true if the the two sites are in the same component.
+ * Returns true if the two elements are in the same set.
*
- * @param p the integer representing one site
- * @param q the integer representing the other site
- * @return {@code true} if the two sites {@code p} and {@code q} are in the same component;
+ * @param p one element
+ * @param q the other element
+ * @return {@code true} if {@code p} and {@code q} are in the same set;
* {@code false} otherwise
* @throws IllegalArgumentException unless
* both {@code 0 <= p < n} and {@code 0 <= q < n}
+ * @deprecated Replace with two calls to {@link #find(int)}.
*/
+ @Deprecated
public boolean connected(int p, int q) {
validate(p);
validate(q);
return id[p] == id[q];
}
-
+
/**
- * Merges the component containing site {@code p} with the
- * the component containing site {@code q}.
+ * Merges the set containing element {@code p} with the set
+ * containing element {@code q}.
*
- * @param p the integer representing one site
- * @param q the integer representing the other site
+ * @param p one element
+ * @param q the other element
* @throws IllegalArgumentException unless
* both {@code 0 <= p < n} and {@code 0 <= q < n}
*/
@@ -168,9 +152,10 @@ public void union(int p, int q) {
}
/**
- * Reads in a sequence of pairs of integers (between 0 and n-1) from standard input,
- * where each integer represents some site;
- * if the sites are in different components, merge the two components
+ * Reads an integer {@code n} and a sequence of pairs of integers
+ * (between {@code 0} and {@code n-1}) from standard input, where each integer
+ * in the pair represents some element;
+ * if the elements are in different sets, merge the two sets
* and print the pair to standard output.
*
* @param args the command-line arguments
@@ -181,7 +166,7 @@ public static void main(String[] args) {
while (!StdIn.isEmpty()) {
int p = StdIn.readInt();
int q = StdIn.readInt();
- if (uf.connected(p, q)) continue;
+ if (uf.find(p) == uf.find(q)) continue;
uf.union(p, q);
StdOut.println(p + " " + q);
}
@@ -191,7 +176,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/QuickUnionUF.java b/src/main/java/edu/princeton/cs/algs4/QuickUnionUF.java
index dbf174194..58d8f323f 100644
--- a/src/main/java/edu/princeton/cs/algs4/QuickUnionUF.java
+++ b/src/main/java/edu/princeton/cs/algs4/QuickUnionUF.java
@@ -15,65 +15,47 @@
/**
* The {@code QuickUnionUF} class represents a union–find data type
* (also known as the disjoint-sets data type).
- * It supports the union and find operations,
- * along with a connected operation for determining whether
- * two sites are in the same component and a count operation that
- * returns the total number of components.
+ * It supports the classic union and find operations,
+ * along with a count operation that returns the total number
+ * of sets.
*
- * The union–find data type models connectivity among a set of n
- * sites, named 0 through n–1.
- * The is-connected-to relation must be an
- * equivalence relation:
+ * The union–find data type models a collection of sets containing
+ * n elements, with each element in exactly one set.
+ * The elements are named 0 through n–1.
+ * Initially, there are n sets, with each element in its
+ * own set. The canonical element of a set
+ * (also known as the root, identifier,
+ * leader, or set representative)
+ * is one distinguished element in the set. Here is a summary of
+ * the operations:
*
- * An equivalence relation partitions the sites into
- * equivalence classes (or components). In this case,
- * two sites are in the same component if and only if they are connected.
- * Both sites and components are identified with integers between 0 and
- * n–1.
- * Initially, there are n components, with each site in its
- * own component. The component identifier of a component
- * (also known as the root, canonical element, leader,
- * or set representative) is one of the sites in the component:
- * two sites have the same component identifier if and only if they are
- * in the same component.
- *
- * The component identifier of a component can change
- * only when the component itself changes during a call to
- * union—it cannot change during a call
- * to find, connected, or count.
+ * This implementation uses quick union.
+ * The constructor takes Θ(n) time, where
+ * n is the number of sites.
+ * The union and find operations take
+ * Θ(n) time in the worst case.
+ * The count operation takes Θ(1) time.
*
- * This implementation uses quick union.
- * Initializing a data structure with n sites takes linear time.
- * Afterwards, the union, find, and connected
- * operations take linear time (in the worst case) and the
- * count operation takes constant time.
- * For alternate implementations of the same API, see
+ * For alternative implementations of the same API, see
* {@link UF}, {@link QuickFindUF}, and {@link WeightedQuickUnionUF}.
- *
- *
- * For additional documentation, see Section 1.5 of
+ * For additional documentation,
+ * see Section 1.5 of
* Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
*
* @author Robert Sedgewick
@@ -84,11 +66,11 @@ public class QuickUnionUF {
private int count; // number of components
/**
- * Initializes an empty union–find data structure with {@code n} sites
- * {@code 0} through {@code n-1}. Each site is initially in its own
- * component.
+ * Initializes an empty union-find data structure with
+ * {@code n} elements {@code 0} through {@code n-1}.
+ * Initially, each element is in its own set.
*
- * @param n the number of sites
+ * @param n the number of elements
* @throws IllegalArgumentException if {@code n < 0}
*/
public QuickUnionUF(int n) {
@@ -100,19 +82,19 @@ public QuickUnionUF(int n) {
}
/**
- * Returns the number of components.
+ * Returns the number of sets.
*
- * @return the number of components (between {@code 1} and {@code n})
+ * @return the number of sets (between {@code 1} and {@code n})
*/
public int count() {
return count;
}
-
+
/**
- * Returns the component identifier for the component containing site {@code p}.
+ * Returns the canonical element of the set containing element {@code p}.
*
- * @param p the integer representing one object
- * @return the component identifier for the component containing site {@code p}
+ * @param p an element
+ * @return the canonical element of the set containing {@code p}
* @throws IllegalArgumentException unless {@code 0 <= p < n}
*/
public int find(int p) {
@@ -131,26 +113,27 @@ private void validate(int p) {
}
/**
- * Returns true if the the two sites are in the same component.
+ * Returns true if the two elements are in the same set.
*
- * @param p the integer representing one site
- * @param q the integer representing the other site
- * @return {@code true} if the two sites {@code p} and {@code q} are in the same component;
+ * @param p one element
+ * @param q the other element
+ * @return {@code true} if {@code p} and {@code q} are in the same set;
* {@code false} otherwise
* @throws IllegalArgumentException unless
* both {@code 0 <= p < n} and {@code 0 <= q < n}
+ * @deprecated Replace with two calls to {@link #find(int)}.
*/
+ @Deprecated
public boolean connected(int p, int q) {
return find(p) == find(q);
}
-
/**
- * Merges the component containing site {@code p} with the
- * the component containing site {@code q}.
+ * Merges the set containing element {@code p} with the set
+ * containing element {@code q}.
*
- * @param p the integer representing one site
- * @param q the integer representing the other site
+ * @param p one element
+ * @param q the other element
* @throws IllegalArgumentException unless
* both {@code 0 <= p < n} and {@code 0 <= q < n}
*/
@@ -158,14 +141,15 @@ public void union(int p, int q) {
int rootP = find(p);
int rootQ = find(q);
if (rootP == rootQ) return;
- parent[rootP] = rootQ;
+ parent[rootP] = rootQ;
count--;
}
/**
- * Reads in a sequence of pairs of integers (between 0 and n-1) from standard input,
- * where each integer represents some object;
- * if the sites are in different components, merge the two components
+ * Reads an integer {@code n} and a sequence of pairs of integers
+ * (between {@code 0} and {@code n-1}) from standard input, where each integer
+ * in the pair represents some element;
+ * if the elements are in different sets, merge the two sets
* and print the pair to standard output.
*
* @param args the command-line arguments
@@ -176,7 +160,7 @@ public static void main(String[] args) {
while (!StdIn.isEmpty()) {
int p = StdIn.readInt();
int q = StdIn.readInt();
- if (uf.connected(p, q)) continue;
+ if (uf.find(p) == uf.find(q)) continue;
uf.union(p, q);
StdOut.println(p + " " + q);
}
@@ -187,7 +171,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/QuickX.java b/src/main/java/edu/princeton/cs/algs4/QuickX.java
index ff56bac56..c84db26be 100644
--- a/src/main/java/edu/princeton/cs/algs4/QuickX.java
+++ b/src/main/java/edu/princeton/cs/algs4/QuickX.java
@@ -4,7 +4,7 @@
* Dependencies: StdOut.java StdIn.java
* Data files: https://algs4.cs.princeton.edu/23quicksort/tiny.txt
* https://algs4.cs.princeton.edu/23quicksort/words3.txt
- *
+ *
* Uses the Hoare's 2-way partitioning scheme, chooses the partitioning
* element using median-of-3, and cuts off to insertion sort.
*
@@ -18,9 +18,9 @@
* algorithm, median-of-3 to choose the partitioning element, and cutoff
* to insertion sort).
*
- * For additional documentation,
- * see Section 2.3 of
- * Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
+ * For additional documentation, see
+ * Section 2.3
+ * of Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
@@ -44,7 +44,7 @@ public static void sort(Comparable[] a) {
}
// quicksort the subarray from a[lo] to a[hi]
- private static void sort(Comparable[] a, int lo, int hi) {
+ private static void sort(Comparable[] a, int lo, int hi) {
if (hi <= lo) return;
// cutoff to insertion sort (Insertion.sort() uses half-open intervals)
@@ -81,7 +81,7 @@ private static int partition(Comparable[] a, int lo, int hi) {
}
// the main loop
- while (i < j) {
+ while (i < j) {
exch(a, i, j);
while (less(a[++i], v)) ;
while (less(v, a[--j])) ;
@@ -104,7 +104,7 @@ private static int median3(Comparable[] a, int i, int j, int k) {
/***************************************************************************
* Helper sorting functions.
***************************************************************************/
-
+
// is v < w ?
private static boolean less(Comparable v, Comparable w) {
return v.compareTo(w) < 0;
@@ -136,8 +136,8 @@ private static void show(Comparable[] a) {
/**
* Reads in a sequence of strings from standard input; quicksorts them
- * (using an optimized version of 2-way quicksort);
- * and prints them to standard output in ascending order.
+ * (using an optimized version of 2-way quicksort);
+ * and prints them to standard output in ascending order.
*
* @param args the command-line arguments
*/
@@ -151,7 +151,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/RabinKarp.java b/src/main/java/edu/princeton/cs/algs4/RabinKarp.java
index e9d039286..eaa6e23c1 100644
--- a/src/main/java/edu/princeton/cs/algs4/RabinKarp.java
+++ b/src/main/java/edu/princeton/cs/algs4/RabinKarp.java
@@ -9,17 +9,17 @@
*
* % java RabinKarp abracadabra abacadabrabracabracadabrabrabracad
* pattern: abracadabra
- * text: abacadabrabracabracadabrabrabracad
- * match: abracadabra
+ * text: abacadabrabracabracadabrabrabracad
+ * match: abracadabra
*
* % java RabinKarp rab abacadabrabracabracadabrabrabracad
* pattern: rab
- * text: abacadabrabracabracadabrabrabracad
- * match: rab
+ * text: abacadabrabracabracadabrabrabracad
+ * match: rab
*
* % java RabinKarp bcara abacadabrabracabracadabrabrabracad
* pattern: bcara
- * text: abacadabrabracabracadabrabrabracad
+ * text: abacadabrabracabracadabrabrabracad
*
* % java RabinKarp rabrabracad abacadabrabracabracadabrabrabracad
* text: abacadabrabracabracadabrabrabracad
@@ -62,7 +62,7 @@ public class RabinKarp {
*/
public RabinKarp(char[] pattern, int R) {
this.pat = String.valueOf(pattern);
- this.R = R;
+ this.R = R;
throw new UnsupportedOperationException("Operation not supported yet");
}
@@ -82,21 +82,21 @@ public RabinKarp(String pat) {
for (int i = 1; i <= m-1; i++)
RM = (R * RM) % q;
patHash = hash(pat, m);
- }
+ }
- // Compute hash for key[0..m-1].
- private long hash(String key, int m) {
- long h = 0;
- for (int j = 0; j < m; j++)
+ // Compute hash for key[0..m-1].
+ private long hash(String key, int m) {
+ long h = 0;
+ for (int j = 0; j < m; j++)
h = (R * h + key.charAt(j)) % q;
return h;
}
// Las Vegas version: does pat[] match txt[i..i-m+1] ?
private boolean check(String txt, int i) {
- for (int j = 0; j < m; j++)
- if (pat.charAt(j) != txt.charAt(i + j))
- return false;
+ for (int j = 0; j < m; j++)
+ if (pat.charAt(j) != txt.charAt(i + j))
+ return false;
return true;
}
@@ -104,9 +104,9 @@ private boolean check(String txt, int i) {
// private boolean check(int i) {
// return true;
//}
-
+
/**
- * Returns the index of the first occurrrence of the pattern string
+ * Returns the index of the first occurrence of the pattern string
* in the text string.
*
* @param txt the text string
@@ -114,9 +114,9 @@ private boolean check(String txt, int i) {
* in the text string; n if no such match
*/
public int search(String txt) {
- int n = txt.length();
+ int n = txt.length();
if (n < m) return n;
- long txtHash = hash(txt, m);
+ long txtHash = hash(txt, m);
// check for match at offset 0
if ((patHash == txtHash) && check(txt, 0))
@@ -124,9 +124,9 @@ public int search(String txt) {
// check for hash match; if hash match, check for exact match
for (int i = m; i < n; i++) {
- // Remove leading digit, add trailing digit, check for match.
- txtHash = (txtHash + q - RM*txt.charAt(i-m) % q) % q;
- txtHash = (txtHash*R + txt.charAt(i)) % q;
+ // Remove leading digit, add trailing digit, check for match.
+ txtHash = (txtHash + q - RM*txt.charAt(i-m) % q) % q;
+ txtHash = (txtHash*R + txt.charAt(i)) % q;
// match
int offset = i - m + 1;
@@ -145,7 +145,7 @@ private static long longRandomPrime() {
return prime.longValue();
}
- /**
+ /**
* Takes a pattern string and an input string as command-line arguments;
* searches for the pattern string in the text string; and prints
* the first occurrence of the pattern string in the text string.
@@ -171,7 +171,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/RandomSeq.java b/src/main/java/edu/princeton/cs/algs4/RandomSeq.java
index 632a06d1b..c2a15c5c9 100644
--- a/src/main/java/edu/princeton/cs/algs4/RandomSeq.java
+++ b/src/main/java/edu/princeton/cs/algs4/RandomSeq.java
@@ -26,7 +26,7 @@
* @author Robert Sedgewick
* @author Kevin Wayne
*/
-public class RandomSeq {
+public class RandomSeq {
// this class should not be instantiated
private RandomSeq() { }
@@ -47,7 +47,7 @@ public static void main(String[] args) {
if (args.length == 1) {
// generate and print n numbers between 0.0 and 1.0
for (int i = 0; i < n; i++) {
- double x = StdRandom.uniform();
+ double x = StdRandom.uniformDouble(0.0, 1.0);
StdOut.println(x);
}
}
@@ -58,7 +58,7 @@ else if (args.length == 3) {
// generate and print n numbers between lo and hi
for (int i = 0; i < n; i++) {
- double x = StdRandom.uniform(lo, hi);
+ double x = StdRandom.uniformDouble(lo, hi);
StdOut.printf("%.2f\n", x);
}
}
@@ -70,7 +70,7 @@ else if (args.length == 3) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/RectHV.java b/src/main/java/edu/princeton/cs/algs4/RectHV.java
index 7bd117eab..2417c6e8d 100644
--- a/src/main/java/edu/princeton/cs/algs4/RectHV.java
+++ b/src/main/java/edu/princeton/cs/algs4/RectHV.java
@@ -14,9 +14,9 @@
* two-dimensional axis-aligned rectagle with real-value coordinates.
* The rectangle is closed—it includes the points on the boundary.
*
- * For additional documentation,
- * see Section 1.2 of
- * Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
+ * For additional documentation,
+ * see Section 1.2 of
+ * Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
@@ -31,11 +31,11 @@ public final class RectHV {
* x [ymin, ymax].
*
* @param xmin the x-coordinate of the lower-left endpoint
- * @param xmax the x-coordinate of the upper-right endpoint
* @param ymin the y-coordinate of the lower-left endpoint
+ * @param xmax the x-coordinate of the upper-right endpoint
* @param ymax the y-coordinate of the upper-right endpoint
* @throws IllegalArgumentException if any of {@code xmin},
- * {@code xmax}, {@code ymin}, or {@code ymax}
+ * {@code ymin}, {@code xmax}, or {@code ymax}
* is {@code Double.NaN}.
* @throws IllegalArgumentException if {@code xmax < xmin} or {@code ymax < ymin}.
*/
@@ -113,14 +113,14 @@ public double height() {
}
/**
- * Returns true if the two rectangles intersect. This includes
- * improper intersections (at points on the boundary
- * of each rectangle) and nested intersctions
- * (when one rectangle is contained inside the other)
+ * Returns true if the two rectangles intersect, and false otherwise.
+ * This includes improper intersections (at points on the
+ * boundary of each rectangle) and nested intersections
+ * (when one rectangle is contained inside the other).
*
* @param that the other rectangle
- * @return {@code true} if this rectangle intersect the argument
- rectangle at one or more points
+ * @return {@code true} if this rectangle intersects the argument
+ rectangle at one or more points; false otherwise
*/
public boolean intersects(RectHV that) {
return this.xmax >= that.xmin && this.ymax >= that.ymin
@@ -128,9 +128,10 @@ public boolean intersects(RectHV that) {
}
/**
- * Returns true if this rectangle contain the point.
+ * Returns true if this rectangle contains the point, and false otherwise.
+ * This includes point on the boundary of the rectangle.
* @param p the point
- * @return {@code true} if this rectangle contain the point {@code p},
+ * @return {@code true} if this rectangle contains the point {@code p},
possibly at the boundary; {@code false} otherwise
*/
public boolean contains(Point2D p) {
@@ -224,7 +225,7 @@ public void draw() {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/RedBlackBST.java b/src/main/java/edu/princeton/cs/algs4/RedBlackBST.java
index 079f1c741..531734379 100644
--- a/src/main/java/edu/princeton/cs/algs4/RedBlackBST.java
+++ b/src/main/java/edu/princeton/cs/algs4/RedBlackBST.java
@@ -1,9 +1,9 @@
/******************************************************************************
* Compilation: javac RedBlackBST.java
* Execution: java RedBlackBST < input.txt
- * Dependencies: StdIn.java StdOut.java
- * Data files: https://algs4.cs.princeton.edu/33balanced/tinyST.txt
- *
+ * Dependencies: StdIn.java StdOut.java
+ * Data files: https://algs4.cs.princeton.edu/33balanced/tinyST.txt
+ *
* A symbol table implemented using a left-leaning red-black BST.
* This is the 2-3 version.
*
@@ -12,7 +12,7 @@
*
* % more tinyST.txt
* S E A R C H E X A M P L E
- *
+ *
* % java RedBlackBST < tinyST.txt
* A 8
* C 4
@@ -47,21 +47,30 @@
* value associated with a key to {@code null} is equivalent to deleting the key
* from the symbol table.
*
- * This implementation uses a left-leaning red-black BST. It requires that
+ * It requires that
* the key type implements the {@code Comparable} interface and calls the
* {@code compareTo()} and method to compare two keys. It does not call either
* {@code equals()} or {@code hashCode()}.
- * The put, contains, remove, minimum,
- * maximum, ceiling, and floor operations each take
- * logarithmic time in the worst case, if the tree becomes unbalanced.
- * The size, and is-empty operations take constant time.
- * Construction takes constant time.
*
- * For additional documentation, see Section 3.3 of
+ * This implementation uses a left-leaning red-black BST.
+ * The put, get, contains, remove,
+ * minimum, maximum, ceiling, floor,
+ * rank, and select operations each take
+ * Θ(log n) time in the worst case, where n is the
+ * number of key-value pairs in the symbol table.
+ * The size, and is-empty operations take Θ(1) time.
+ * The keys methods take
+ * O(log n + m) time, where m is
+ * the number of keys returned by the iterator.
+ * Construction takes Θ(1) time.
+ *
+ * For alternative implementations of the symbol table API, see {@link ST},
+ * {@link BinarySearchST}, {@link SequentialSearchST}, {@link BST},
+ * {@link SeparateChainingHashST}, {@link LinearProbingHashST}, and
+ * {@link AVLTreeST}.
+ * For additional documentation, see
+ * Section 3.3 of
* Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
- * For other implementations of the same API, see {@link ST}, {@link BinarySearchST},
- * {@link SequentialSearchST}, {@link BST},
- * {@link SeparateChainingHashST}, {@link LinearProbingHashST}, and {@link AVLTreeST}.
*
* @author Robert Sedgewick
* @author Kevin Wayne
@@ -109,7 +118,7 @@ private boolean isRed(Node x) {
private int size(Node x) {
if (x == null) return 0;
return x.size;
- }
+ }
/**
@@ -172,7 +181,7 @@ public boolean contains(Key key) {
***************************************************************************/
/**
- * Inserts the specified key-value pair into the symbol table, overwriting the old
+ * Inserts the specified key-value pair into the symbol table, overwriting the old
* value with the new value if the symbol table already contains the specified key.
* Deletes the specified key (and its associated value) from this symbol table
* if the specified value is {@code null}.
@@ -194,12 +203,12 @@ public void put(Key key, Value val) {
}
// insert the key-value pair in the subtree rooted at h
- private Node put(Node h, Key key, Value val) {
+ private Node put(Node h, Key key, Value val) {
if (h == null) return new Node(key, val, RED, 1);
int cmp = key.compareTo(h.key);
- if (cmp < 0) h.left = put(h.left, key, val);
- else if (cmp > 0) h.right = put(h.right, key, val);
+ if (cmp < 0) h.left = put(h.left, key, val);
+ else if (cmp > 0) h.right = put(h.right, key, val);
else h.val = val;
// fix-up any right-leaning links
@@ -232,7 +241,7 @@ public void deleteMin() {
}
// delete the key-value pair with the minimum key rooted at h
- private Node deleteMin(Node h) {
+ private Node deleteMin(Node h) {
if (h.left == null)
return null;
@@ -261,7 +270,7 @@ public void deleteMax() {
}
// delete the key-value pair with the maximum key rooted at h
- private Node deleteMax(Node h) {
+ private Node deleteMax(Node h) {
if (isRed(h.left))
h = rotateRight(h);
@@ -277,13 +286,13 @@ private Node deleteMax(Node h) {
}
/**
- * Removes the specified key and its associated value from this symbol table
- * (if the key is in this symbol table).
+ * Removes the specified key and its associated value from this symbol table
+ * (if the key is in this symbol table).
*
* @param key the key
* @throws IllegalArgumentException if {@code key} is {@code null}
*/
- public void delete(Key key) {
+ public void delete(Key key) {
if (key == null) throw new IllegalArgumentException("argument to delete() is null");
if (!contains(key)) return;
@@ -297,7 +306,7 @@ public void delete(Key key) {
}
// delete the key-value pair with the given key rooted at h
- private Node delete(Node h, Key key) {
+ private Node delete(Node h, Key key) {
// assert get(h, key) != null;
if (key.compareTo(h.key) < 0) {
@@ -331,12 +340,13 @@ private Node delete(Node h, Key key) {
// make a left-leaning link lean to the right
private Node rotateRight(Node h) {
- // assert (h != null) && isRed(h.left);
+ assert (h != null) && isRed(h.left);
+ // assert (h != null) && isRed(h.left) && !isRed(h.right); // for insertion only
Node x = h.left;
h.left = x.right;
x.right = h;
- x.color = x.right.color;
- x.right.color = RED;
+ x.color = h.color;
+ h.color = RED;
x.size = h.size;
h.size = size(h.left) + size(h.right) + 1;
return x;
@@ -344,12 +354,13 @@ private Node rotateRight(Node h) {
// make a right-leaning link lean to the left
private Node rotateLeft(Node h) {
- // assert (h != null) && isRed(h.right);
+ assert (h != null) && isRed(h.right);
+ // assert (h != null) && isRed(h.right) && !isRed(h.left); // for insertion only
Node x = h.right;
h.right = x.left;
x.left = h;
- x.color = x.left.color;
- x.left.color = RED;
+ x.color = h.color;
+ h.color = RED;
x.size = h.size;
h.size = size(h.left) + size(h.right) + 1;
return x;
@@ -373,7 +384,7 @@ private Node moveRedLeft(Node h) {
// assert isRed(h) && !isRed(h.left) && !isRed(h.left.left);
flipColors(h);
- if (isRed(h.right.left)) {
+ if (isRed(h.right.left)) {
h.right = rotateRight(h.right);
h = rotateLeft(h);
flipColors(h);
@@ -387,7 +398,7 @@ private Node moveRedRight(Node h) {
// assert (h != null);
// assert isRed(h) && !isRed(h.right) && !isRed(h.right.left);
flipColors(h);
- if (isRed(h.left.left)) {
+ if (isRed(h.left.left)) {
h = rotateRight(h);
flipColors(h);
}
@@ -398,7 +409,7 @@ private Node moveRedRight(Node h) {
private Node balance(Node h) {
// assert (h != null);
- if (isRed(h.right)) h = rotateLeft(h);
+ if (isRed(h.right) && !isRed(h.left)) h = rotateLeft(h);
if (isRed(h.left) && isRed(h.left.left)) h = rotateRight(h);
if (isRed(h.left) && isRed(h.right)) flipColors(h);
@@ -435,14 +446,14 @@ private int height(Node x) {
public Key min() {
if (isEmpty()) throw new NoSuchElementException("calls min() with empty symbol table");
return min(root).key;
- }
+ }
// the smallest key in subtree rooted at x; null if no such key
- private Node min(Node x) {
+ private Node min(Node x) {
// assert x != null;
- if (x.left == null) return x;
- else return min(x.left);
- }
+ if (x.left == null) return x;
+ else return min(x.left);
+ }
/**
* Returns the largest key in the symbol table.
@@ -452,14 +463,14 @@ private Node min(Node x) {
public Key max() {
if (isEmpty()) throw new NoSuchElementException("calls max() with empty symbol table");
return max(root).key;
- }
+ }
// the largest key in the subtree rooted at x; null if no such key
- private Node max(Node x) {
+ private Node max(Node x) {
// assert x != null;
- if (x.right == null) return x;
- else return max(x.right);
- }
+ if (x.right == null) return x;
+ else return max(x.right);
+ }
/**
@@ -473,9 +484,9 @@ public Key floor(Key key) {
if (key == null) throw new IllegalArgumentException("argument to floor() is null");
if (isEmpty()) throw new NoSuchElementException("calls floor() with empty symbol table");
Node x = floor(root, key);
- if (x == null) return null;
+ if (x == null) throw new NoSuchElementException("argument to floor() is too small");
else return x.key;
- }
+ }
// the largest key in the subtree rooted at x less than or equal to the given key
private Node floor(Node x, Key key) {
@@ -484,7 +495,7 @@ private Node floor(Node x, Key key) {
if (cmp == 0) return x;
if (cmp < 0) return floor(x.left, key);
Node t = floor(x.right, key);
- if (t != null) return t;
+ if (t != null) return t;
else return x;
}
@@ -499,47 +510,48 @@ public Key ceiling(Key key) {
if (key == null) throw new IllegalArgumentException("argument to ceiling() is null");
if (isEmpty()) throw new NoSuchElementException("calls ceiling() with empty symbol table");
Node x = ceiling(root, key);
- if (x == null) return null;
- else return x.key;
+ if (x == null) throw new NoSuchElementException("argument to ceiling() is too large");
+ else return x.key;
}
// the smallest key in the subtree rooted at x greater than or equal to the given key
- private Node ceiling(Node x, Key key) {
+ private Node ceiling(Node x, Key key) {
if (x == null) return null;
int cmp = key.compareTo(x.key);
if (cmp == 0) return x;
if (cmp > 0) return ceiling(x.right, key);
Node t = ceiling(x.left, key);
- if (t != null) return t;
+ if (t != null) return t;
else return x;
}
/**
- * Return the key in the symbol table whose rank is {@code k}.
- * This is the (k+1)st smallest key in the symbol table.
+ * Return the key in the symbol table of a given {@code rank}.
+ * This key has the property that there are {@code rank} keys in
+ * the symbol table that are smaller. In other words, this key is the
+ * ({@code rank}+1)st smallest key in the symbol table.
*
- * @param k the order statistic
- * @return the key in the symbol table of rank {@code k}
- * @throws IllegalArgumentException unless {@code k} is between 0 and
+ * @param rank the order statistic
+ * @return the key in the symbol table of given {@code rank}
+ * @throws IllegalArgumentException unless {@code rank} is between 0 and
* n–1
*/
- public Key select(int k) {
- if (k < 0 || k >= size()) {
- throw new IllegalArgumentException("argument to select() is invalid: " + k);
+ public Key select(int rank) {
+ if (rank < 0 || rank >= size()) {
+ throw new IllegalArgumentException("argument to select() is invalid: " + rank);
}
- Node x = select(root, k);
- return x.key;
+ return select(root, rank);
}
- // the key of rank k in the subtree rooted at x
- private Node select(Node x, int k) {
- // assert x != null;
- // assert k >= 0 && k < size(x);
- int t = size(x.left);
- if (t > k) return select(x.left, k);
- else if (t < k) return select(x.right, k-t-1);
- else return x;
- }
+ // Return key in BST rooted at x of given rank.
+ // Precondition: rank is in legal range.
+ private Key select(Node x, int rank) {
+ if (x == null) return null;
+ int leftSize = size(x.left);
+ if (leftSize > rank) return select(x.left, rank);
+ else if (leftSize < rank) return select(x.right, rank - leftSize - 1);
+ else return x.key;
+ }
/**
* Return the number of keys in the symbol table strictly less than {@code key}.
@@ -550,26 +562,26 @@ private Node select(Node x, int k) {
public int rank(Key key) {
if (key == null) throw new IllegalArgumentException("argument to rank() is null");
return rank(key, root);
- }
+ }
// number of keys less than key in the subtree rooted at x
private int rank(Key key, Node x) {
- if (x == null) return 0;
- int cmp = key.compareTo(x.key);
- if (cmp < 0) return rank(key, x.left);
- else if (cmp > 0) return 1 + size(x.left) + rank(key, x.right);
- else return size(x.left);
- }
+ if (x == null) return 0;
+ int cmp = key.compareTo(x.key);
+ if (cmp < 0) return rank(key, x.left);
+ else if (cmp > 0) return 1 + size(x.left) + rank(key, x.right);
+ else return size(x.left);
+ }
/***************************************************************************
* Range count and range search.
***************************************************************************/
/**
- * Returns all keys in the symbol table as an {@code Iterable}.
+ * Returns all keys in the symbol table in ascending order as an {@code Iterable}.
* To iterate over all of the keys in the symbol table named {@code st},
* use the foreach notation: {@code for (Key key : st.keys())}.
- * @return all keys in the symbol table as an {@code Iterable}
+ * @return all keys in the symbol table in ascending order
*/
public Iterable
* This implementation uses a resizing array.
@@ -30,6 +30,9 @@
* @author Kevin Wayne
*/
public class ResizingArrayBag
* For additional documentation, see Section 1.3 of
* Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
@@ -37,6 +37,9 @@
* @author Kevin Wayne
*/
public class ResizingArrayQueue
* For additional documentation,
* see Section 1.3 of
@@ -40,6 +40,10 @@
* @author Kevin Wayne
*/
public class ResizingArrayStackBinaryIn
data type provides methods for reading
+ * in bits from a binary input stream. It can process the bits
* one bit at a time (as a {@code boolean}),
* 8 bits at a time (as a {@code byte} or {@code char}),
* 16 bits at a time (as a {@code short}),
@@ -33,7 +37,7 @@
* The binary input stream can be from standard input, a filename,
* a URL name, a Socket, or an InputStream.
* BinaryOut
data type provides a basic capability for
+ * converting primitive type variables ({@code boolean}, {@code byte},
+ * {@code char}, {@code int}, {@code long}, {@code float}, and {@code double})
* to sequences of bits and writing them to an output stream.
* The output stream can be standard output, a file, an OutputStream or a Socket.
* Uses big-endian (most-significant byte first).
@@ -60,29 +60,46 @@ public BinaryOut(OutputStream os) {
/**
* Initializes a binary output stream from a file.
- * @param filename the name of the file
+ * @param filename the name of the file
+ * @throws IllegalArgumentException if {@code filename} is {@code null}
+ * @throws IllegalArgumentException if {@code filename} is the empty string
+ * @throws IllegalArgumentException if cannot write the file {@code filename}
*/
public BinaryOut(String filename) {
+ if (filename == null) {
+ throw new IllegalArgumentException("filename argument is null");
+ }
+
+ if (filename.length() == 0) {
+ throw new IllegalArgumentException("filename argument is the empty string");
+ }
+
try {
OutputStream os = new FileOutputStream(filename);
out = new BufferedOutputStream(os);
}
catch (IOException e) {
- e.printStackTrace();
+ throw new IllegalArgumentException("could not create file '" + filename + "' for writing", e);
}
}
/**
* Initializes a binary output stream from a socket.
* @param socket the socket
+ * @throws IllegalArgumentException if {@code filename} is {@code null}
+ * @throws IllegalArgumentException if cannot create output stream from socket
*/
public BinaryOut(Socket socket) {
+ if (socket == null) {
+ throw new IllegalArgumentException("socket argument is null");
+ }
+
try {
OutputStream os = socket.getOutputStream();
out = new BufferedOutputStream(os);
}
catch (IOException e) {
- e.printStackTrace();
+ throw new IllegalArgumentException("could not create output stream from socket", e);
}
}
@@ -99,7 +116,7 @@ private void writeBit(boolean x) {
// if buffer is full (8 bits), write out as a single byte
n++;
if (n == 8) clearBuffer();
- }
+ }
/**
* Writes the 8-bit byte to the binary output stream.
@@ -175,7 +192,7 @@ public void close() {
*/
public void write(boolean x) {
writeBit(x);
- }
+ }
/**
* Writes the 8-bit byte to the binary output stream.
@@ -197,7 +214,7 @@ public void write(int x) {
}
/**
- * Writes the r-bit int to the binary output stream.
+ * Writes the r-bit int to the binary output stream.
*
* @param x the {@code int} to write
* @param r the number of relevant bits in the char
@@ -262,15 +279,15 @@ public void write(short x) {
* Writes the 8-bit char to the binary output stream.
*
* @param x the {@code char} to write
- * @throws IllegalArgumentException unless {@code x} is betwen 0 and 255
+ * @throws IllegalArgumentException unless {@code x} is between 0 and 255
*/
public void write(char x) {
- if (x < 0 || x >= 256) throw new IllegalArgumentException("Illegal 8-bit char = " + x);
+ if (x >= 256) throw new IllegalArgumentException("Illegal 8-bit char = " + x);
writeByte(x);
}
/**
- * Writes the r-bit char to the binary output stream.
+ * Writes the r-bit char to the binary output stream.
*
* @param x the {@code char} to write
* @param r the number of relevant bits in the char
@@ -304,9 +321,9 @@ public void write(String s) {
/**
- * Writes the string of r-bit characters to the binary output stream.
+ * Writes the string of r-bit characters to the binary output stream.
* @param s the {@code String} to write
- * @param r the number of relevants bits in each character
+ * @param r the number of relevant bits in each character
* @throws IllegalArgumentException unless r is between 1 and 16
* @throws IllegalArgumentException if any character in the string is not
* between 0 and 2r - 1
@@ -341,7 +358,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/BinarySearch.java b/src/main/java/edu/princeton/cs/algs4/BinarySearch.java
index 86532460d..d3d4a7441 100644
--- a/src/main/java/edu/princeton/cs/algs4/BinarySearch.java
+++ b/src/main/java/edu/princeton/cs/algs4/BinarySearch.java
@@ -1,18 +1,18 @@
/******************************************************************************
* Compilation: javac BinarySearch.java
- * Execution: java BinarySearch whitelist.txt < input.txt
+ * Execution: java BinarySearch allowlist.txt < input.txt
* Dependencies: In.java StdIn.java StdOut.java
- * Data files: https://algs4.cs.princeton.edu/11model/tinyW.txt
- * https://algs4.cs.princeton.edu/11model/tinyT.txt
- * https://algs4.cs.princeton.edu/11model/largeW.txt
- * https://algs4.cs.princeton.edu/11model/largeT.txt
+ * Data files: https://algs4.cs.princeton.edu/11model/tinyAllowlist.txt
+ * https://algs4.cs.princeton.edu/11model/tinyText.txt
+ * https://algs4.cs.princeton.edu/11model/largeAllowlist.txt
+ * https://algs4.cs.princeton.edu/11model/largeText.txt
*
- * % java BinarySearch tinyW.txt < tinyT.txt
+ * % java BinarySearch tinyAllowlist.txt < tinyText.txt
* 50
* 99
* 13
*
- * % java BinarySearch largeW.txt < largeT.txt | more
+ * % java BinarySearch largeAllowlist.txt < largeText.txt | more
* 499569
* 984875
* 295754
@@ -20,7 +20,7 @@
* 140925
* 161828
* [367,966 total values]
- *
+ *
******************************************************************************/
package edu.princeton.cs.algs4;
@@ -82,7 +82,7 @@ public static int rank(int key, int[] a) {
}
/**
- * Reads in a sequence of integers from the whitelist file, specified as
+ * Reads in a sequence of integers from the allowlist file, specified as
* a command-line argument; reads in integers from standard input;
* prints to standard output those integers that do not appear in the file.
*
@@ -92,22 +92,22 @@ public static void main(String[] args) {
// read the integers from a file
In in = new In(args[0]);
- int[] whitelist = in.readAllInts();
+ int[] allowlist = in.readAllInts();
// sort the array
- Arrays.sort(whitelist);
+ Arrays.sort(allowlist);
- // read integer key from standard input; print if not in whitelist
+ // read integer key from standard input; print if not in allowlist
while (!StdIn.isEmpty()) {
int key = StdIn.readInt();
- if (BinarySearch.indexOf(whitelist, key) == -1)
+ if (BinarySearch.indexOf(allowlist, key) == -1)
StdOut.println(key);
}
}
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/BinarySearchST.java b/src/main/java/edu/princeton/cs/algs4/BinarySearchST.java
index a26fe53a1..3429a3165 100644
--- a/src/main/java/edu/princeton/cs/algs4/BinarySearchST.java
+++ b/src/main/java/edu/princeton/cs/algs4/BinarySearchST.java
@@ -2,13 +2,13 @@
* Compilation: javac BinarySearchST.java
* Execution: java BinarySearchST
* Dependencies: StdIn.java StdOut.java
- * Data files: https://algs4.cs.princeton.edu/31elementary/tinyST.txt
- *
+ * Data files: https://algs4.cs.princeton.edu/31elementary/tinyST.txt
+ *
* Symbol table implementation with binary search in an ordered array.
*
* % more tinyST.txt
* S E A R C H E X A M P L E
- *
+ *
* % java BinarySearchST < tinyST.txt
* A 8
* C 4
@@ -43,21 +43,26 @@
* value associated with a key to {@code null} is equivalent to deleting the key
* from the symbol table.
* BinaryStdIn
class provides static methods for reading
+ * in bits from standard input. It can process the bits
+ * one bit at a time (as a {@code boolean}),
* 8 bits at a time (as a {@code byte} or {@code char}),
* 16 bits at a time (as a {@code short}), 32 bits at a time
* (as an {@code int} or {@code float}), or 64 bits at a time (as a
* {@code double} or {@code long}).
* BinaryStdOut
class provides static methods for converting
+ * primitive type variables ({@code boolean}, {@code byte}, {@code char},
* {@code int}, {@code long}, {@code float}, and {@code double})
* to sequences of bits and writing them to standard output.
* Uses big-endian (most-significant byte first).
@@ -26,7 +26,7 @@
* The client must {@code flush()} the output stream when finished writing bits.
* reverse()
method takes Θ(E + V) time
+ * and space; all other instance methods take Θ(1) time. (Though, iterating over
+ * the vertices returned by {@link #adj(int)} takes time proportional
+ * to the outdegree of the vertex.)
+ * Constructing an empty digraph with V vertices takes
+ * Θ(V) time; constructing a digraph with E edges
+ * and V vertices takes Θ(E + V) time.
* Draw
data type provides a basic capability for
* creating drawings with your programs. It uses a simple graphics model that
* allows you to create drawings consisting of points, lines, and curves
* in a window on your computer and to save the drawings to a file.
* This is the object-oriented version of standard draw; it supports
- * multiple indepedent drawing windows.
+ * multiple independent drawing windows.
* DrawListener
interface provides a basic capability for
+ * responding to keyboard in mouse events from {@link Draw} via callbacks.
+ * You can see some examples in
+ * Section 3.6.
+ *
+ *
- *
- *
+ * The {@code GlobalMincut} class represents a data type for computing a
+ * global minimum cut in a graph with non-negative edge weights.
+ * A cut is a partition of the vertices into two nonempty subsets.
+ * An edge that has one
+ * endpoint in each subset of a cut is a crossing edge. The weight
+ * of a cut is the sum of the weights of its crossing edges.
+ * A global minimum cut whose weight is no larger than the weight
+ * of any other cut.
+ *
+ *
+ *
* @author Marcelo Silva
*/
public class GlobalMincut {
- private static final double FLOATING_POINT_EPSILON = 1E-11;
+ private static final double FLOATING_POINT_EPSILON = 1.0E-11;
// the weight of the minimum cut
private double weight = Double.POSITIVE_INFINITY;
@@ -89,11 +79,12 @@ public CutPhase(double weight, int s, int t) {
}
/**
- * Computes a minimum cut of an edge-weighted graph.
- *
+ * Computes a minimum cut in an edge-weighted graph.
+ *
* @param G the edge-weighted graph
* @throws IllegalArgumentException if the number of vertices of {@code G}
- * is less than {@code 2} or if anny edge weight is negative
+ * is less than {@code 2}.
+ * @throws IllegalArgumentException if any edge weight is negative
*/
public GlobalMincut(EdgeWeightedGraph G) {
V = G.V();
@@ -104,7 +95,7 @@ public GlobalMincut(EdgeWeightedGraph G) {
/**
* Validates the edge-weighted graph.
- *
+ *
* @param G the edge-weighted graph
* @throws IllegalArgumentException if the number of vertices of {@code G}
* is less than {@code 2} or if any edge weight is negative
@@ -118,7 +109,7 @@ private void validate(EdgeWeightedGraph G) {
/**
* Returns the weight of the minimum cut.
- *
+ *
* @return the weight of the minimum cut
*/
public double weight() {
@@ -126,16 +117,17 @@ public double weight() {
}
/**
- * Returns {@code true} if the vertex {@code v} is on the first subset of
- * vertices of the minimum cut; or {@code false} if the vertex {@code v} is
- * on the second subset.
- *
+ * Returns {@code true} if the vertex {@code v} is one side of the
+ * mincut and {@code false} otherwise. An edge v-w
+ * crosses the mincut if and only if v and w have
+ * opposite parity.
+ *
* @param v the vertex to check
* @return {@code true} if the vertex {@code v} is on the first subset of
* vertices of the minimum cut; or {@code false} if the vertex
* {@code v} is on the second subset.
* @throws IllegalArgumentException unless vertex {@code v} is between
- * {@code 0} and {@code (G.V() - 1)}
+ * {@code 0 <= v < V}
*/
public boolean cut(int v) {
validateVertex(v);
@@ -143,17 +135,17 @@ public boolean cut(int v) {
}
/**
- * Makes a cut for the current edge-weighted graph by partitioning its set
- * of vertices into two nonempty subsets. The vertices connected to the
+ * Makes a cut for the current edge-weighted graph by partitioning its
+ * vertices into two nonempty subsets. The vertices connected to the
* vertex {@code t} belong to the first subset. Other vertices not connected
* to {@code t} belong to the second subset.
- *
+ *
* @param t the vertex {@code t}
* @param uf the union-find data type
*/
private void makeCut(int t, UF uf) {
for (int v = 0; v < cut.length; v++) {
- cut[v] = uf.connected(v, t);
+ cut[v] = (uf.find(v) == uf.find(t));
}
}
@@ -161,7 +153,7 @@ private void makeCut(int t, UF uf) {
* Computes a minimum cut of the edge-weighted graph. Precisely, it computes
* the lightest of the cuts-of-the-phase which yields the desired minimum
* cut.
- *
+ *
* @param G the edge-weighted graph
* @param a the starting vertex
*/
@@ -171,7 +163,7 @@ private void minCut(EdgeWeightedGraph G, int a) {
cut = new boolean[G.V()];
CutPhase cp = new CutPhase(0.0, a, a);
for (int v = G.V(); v > 1; v--) {
- cp = minCutPhase(G, marked, cp);
+ minCutPhase(G, marked, cp);
if (cp.weight < weight) {
weight = cp.weight;
makeCut(cp.t, uf);
@@ -187,7 +179,7 @@ private void minCut(EdgeWeightedGraph G, int a) {
* in the current graph, where {@code s} and {@code t} are the two vertices
* added last in the phase. This algorithm is known in the literature as
* maximum adjacency search or maximum cardinality search.
- *
+ *
* @param G the edge-weighted graph
* @param marked the array of contracted vertices, where {@code marked[v]}
* is {@code true} if the vertex {@code v} was already
@@ -195,7 +187,7 @@ private void minCut(EdgeWeightedGraph G, int a) {
* @param cp the previous cut-of-the-phase
* @return the cut-of-the-phase
*/
- private CutPhase minCutPhase(EdgeWeightedGraph G, boolean[] marked, CutPhase cp) {
+ private void minCutPhase(EdgeWeightedGraph G, boolean[] marked, CutPhase cp) {
IndexMaxPQGrayscalePicture
data type provides a basic capability
+ * for manipulating the individual pixels of a grayscale image.
+ * The original image can be read from a {@code PNG}, {@code GIF},
+ * or {@code JPEG} file or the user can create a blank image of a given dimension.
+ * This class includes methods for displaying the image in a window on
+ * the screen or saving it to a file.
+ * int
+ * (even though, in principle, only ~ W H bytes are needed).
+ * width
-by-height
matrix of pixels,
+ * where the grayscale value of a pixel is an integer between 0 and 255.
+ *
+ * @return a string representation of this picture
+ */
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append(width +"-by-" + height + " grayscale picture (grayscale values given in hex)\n");
+ for (int row = 0; row < height; row++) {
+ for (int col = 0; col < width; col++) {
+ int gray;
+ if (isOriginUpperLeft) gray = 0xFF & image.getRGB(col, row);
+ else gray = 0xFF & image.getRGB(col, height - row - 1);
+ sb.append(String.format("%3d ", gray));
+ }
+ sb.append("\n");
+ }
+ return sb.toString().trim();
+ }
+
+ /**
+ * This operation is not supported because pictures are mutable.
+ *
+ * @return does not return a value
+ * @throws UnsupportedOperationException if called
+ */
+ public int hashCode() {
+ throw new UnsupportedOperationException("hashCode() is not supported because pictures are mutable");
+ }
+
+ /**
+ * Saves the picture to a file in either PNG or JPEG format.
+ * The filetype extension must be either .png or .jpg.
+ *
+ * @param filename the name of the file
+ * @throws IllegalArgumentException if {@code filename} is {@code null}
+ * @throws IllegalArgumentException if {@code filename} is the empty string
+ * @throws IllegalArgumentException if {@code filename} has invalid filetype extension
+ * @throws IllegalArgumentException if cannot write the file {@code filename}
+ */
+ public void save(String filename) {
+ if (filename == null) throw new IllegalArgumentException("argument to save() is null");
+ save(new File(filename));
+ title = filename;
+ }
+
+ /**
+ * Saves the picture to a file in a PNG or JPEG image format.
+ *
+ * @param file the file
+ * @throws IllegalArgumentException if {@code file} is {@code null}
+ */
+ public void save(File file) {
+ if (file == null) throw new IllegalArgumentException("argument to save() is null");
+ title = file.getName();
+ if (frame != null) frame.setTitle(title);
+
+ String suffix = title.substring(title.lastIndexOf('.') + 1);
+ if (!title.contains(".") || suffix.length() == 0) {
+ System.out.printf("Error: the filename '%s' has no file extension, such as .jpg or .png\n", title);
+ return;
+ }
+
+ try {
+ // for formats that support transparency (e.g., PNG and GIF)
+ if (ImageIO.write(image, suffix, file)) return;
+
+ // for formats that don't support transparency (e.g., JPG and BMP)
+ // create BufferedImage in RGB format and use white background
+ BufferedImage imageRGB = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
+ imageRGB.createGraphics().drawImage(image, 0, 0, Color.WHITE, null);
+ if (ImageIO.write(imageRGB, suffix, file)) return;
+
+ // failed to save the file; probably wrong format
+ throw new IllegalArgumentException("The filetype '" + suffix + "' is not supported");
+ }
+ catch (IOException e) {
+ throw new IllegalArgumentException("could not write file '" + title + "'", e);
+ }
+ }
+
+ /**
+ * Opens a save dialog box when the user selects "Save As" from the menu.
+ */
+ @Override
+ public void actionPerformed(ActionEvent event) {
+ FileDialog chooser = new FileDialog(frame,
+ "Use a .png or .jpg extension", FileDialog.SAVE);
+ chooser.setVisible(true);
+ String selectedDirectory = chooser.getDirectory();
+ String selectedFilename = chooser.getFile();
+ if (selectedDirectory != null && selectedFilename != null) {
+ try {
+ save(selectedDirectory + selectedFilename);
+ }
+ catch (IllegalArgumentException e) {
+ System.err.println(e.getMessage());
+ }
+ }
+ }
+
+ /**
+ * Unit tests this {@code Picture} data type.
+ * Reads a picture specified by the command-line argument,
+ * and shows it in a window on the screen.
+ *
+ * @param args the command-line arguments
+ */
+ public static void main(String[] args) {
+ GrayscalePicture picture = new GrayscalePicture(args[0]);
+ StdOut.printf("%d-by-%d\n", picture.width(), picture.height());
+ GrayscalePicture copy = new GrayscalePicture(picture);
+ picture.show();
+ copy.show();
+ while (!StdIn.isEmpty()) {
+ int row = StdIn.readInt();
+ int col = StdIn.readInt();
+ int gray = StdIn.readInt();
+ picture.setGrayscale(row, col, gray);
+ StdOut.println(picture.get(row, col));
+ StdOut.println(picture.getGrayscale(row, col));
+ }
+ }
+
+}
+
+/******************************************************************************
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
+ *
+ * This file is part of algs4.jar, which accompanies the textbook
+ *
+ * Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
+ * Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
+ * http://algs4.cs.princeton.edu
+ *
+ *
+ * algs4.jar is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * algs4.jar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with algs4.jar. If not, see http://www.gnu.org/licenses.
+ ******************************************************************************/
diff --git a/src/main/java/edu/princeton/cs/algs4/Heap.java b/src/main/java/edu/princeton/cs/algs4/Heap.java
index dc7586e9f..e9108f41b 100644
--- a/src/main/java/edu/princeton/cs/algs4/Heap.java
+++ b/src/main/java/edu/princeton/cs/algs4/Heap.java
@@ -4,7 +4,7 @@
* Dependencies: StdOut.java StdIn.java
* Data files: https://algs4.cs.princeton.edu/24pq/tiny.txt
* https://algs4.cs.princeton.edu/24pq/words3.txt
- *
+ *
* Sorts a sequence of strings from standard input using heapsort.
*
* % more tiny.txt
@@ -24,10 +24,19 @@
package edu.princeton.cs.algs4;
/**
- * The {@code Heap} class provides a static methods for heapsorting
- * an array.
+ * The {@code Heap} class provides a static method to sort an array
+ * using heapsort.
+ * In
data type provides methods for reading strings
+ * and numbers from standard input, file input, URLs, and sockets.
* Out
data type provides methods for writing strings and
+ * numbers to various output streams, including standard output, file, and sockets.
*
@@ -434,7 +434,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/PatriciaST.java b/src/main/java/edu/princeton/cs/algs4/PatriciaST.java
index b1d17cb4a..6ef3e6af4 100644
--- a/src/main/java/edu/princeton/cs/algs4/PatriciaST.java
+++ b/src/main/java/edu/princeton/cs/algs4/PatriciaST.java
@@ -84,7 +84,7 @@
* implementation performs well, the source code was written with an emphasis
* on clarity, and not performance. PATRICIA performs admirably when its
* bit-testing loops are well tuned. Consider using the source code as a guide,
- * should you need to produce an optimized implementation, for anther key type,
+ * should you need to produce an optimized implementation, for another key type,
* or in another programming language.
*
@@ -453,7 +453,7 @@ public static void main(String[] args) {
}
/******************************************************************************
- * Copyright 2002-2018, Robert Sedgewick and Kevin Wayne.
+ * Copyright 2002-2025, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
diff --git a/src/main/java/edu/princeton/cs/algs4/Picture.java b/src/main/java/edu/princeton/cs/algs4/Picture.java
index 398ed2469..e1c645069 100644
--- a/src/main/java/edu/princeton/cs/algs4/Picture.java
+++ b/src/main/java/edu/princeton/cs/algs4/Picture.java
@@ -1,21 +1,8 @@
/******************************************************************************
* Compilation: javac Picture.java
- * Execution: java Picture imagename
+ * Execution: java Picture filename.jpg
* Dependencies: none
*
- * Data type for manipulating individual pixels of an image. The original
- * image can be read from a file in jpg, gif, or png format, or the
- * user can create a blank image of a given dimension. Includes methods for
- * displaying the image in a window on the screen or saving to a file.
- *
- * % java Picture mandrill.jpg
- *
- * Remarks
- * -------
- * - pixel (x, y) is column x and row y, where (0, 0) is upper left
- *
- * - see also GrayPicture.java for a grayscale version
- *
******************************************************************************/
package edu.princeton.cs.algs4;
@@ -23,14 +10,24 @@
import java.awt.Color;
import java.awt.FileDialog;
import java.awt.Toolkit;
+
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+
import java.awt.image.BufferedImage;
+
import java.io.File;
import java.io.IOException;
+
+import java.net.URI;
+import java.net.URISyntaxException;
import java.net.URL;
+
import javax.imageio.ImageIO;
+
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
@@ -42,41 +39,193 @@
/**
- * This class provides methods for manipulating individual pixels of
- * an image using the RGB color format. The alpha component (for transparency)
- * is not currently supported.
- * The original image can be read from a {@code PNG}, {@code GIF},
- * or {@code JPEG} file or the user can create a blank image of a given dimension.
- * This class includes methods for displaying the image in a window on
- * the screen or saving it to a file.
+ * The {@code Picture} data type provides a basic capability for manipulating
+ * the individual pixels of an image.
+ * You can either create a blank image (of a given dimension) or read an
+ * image in a supported file format (typically JPEG, PNG, GIF, TIFF, and BMP).
+ * This class also includes methods for displaying the image in a window
+ * and saving it to a file.
+ *
*
+ *
+ *
+ *
+ * public class TestPicture {
+ * public static void main(String[] args) {
+ * Picture picture = new Picture("https://introcs.cs.princeton.edu/java/stdlib/mandrill.jpg");
+ * picture.show();
+ * }
+ * }
+ *
+ *
+ *
+ *
+ *
+ *
+ *
*
+ *
+ *
+ * Picture picture = new Picture("https://introcs.cs.princeton.edu/java/stdlib/mandrill.jpg");
+ * Picture grayscale = new Picture(picture.width(), picture.height());
+ * for (int col = 0; col < picture.width(); col++) {
+ * for (int row = 0; row < picture.height(); row++) {
+ * Color color = picture.get(col, row);
+ * int r = color.getRed();
+ * int g = color.getGreen();
+ * int b = color.getBlue();
+ * int y = (int) (Math.round(0.299*r + 0.587*g + 0.114*b));
+ * Color gray = new Color(y, y, y);
+ * grayscale.set(col, row, gray);
+ * }
+ * }
+ * picture.show();
+ * grayscale.show();
+ *
+ *
+ *
+ *
+ *
- * Given the RGB components (8-bits each) of a color,
+ * int a = (rgb >> 24) & 0xFF;
+ * int r = (rgb >> 16) & 0xFF;
+ * int g = (rgb >> 8) & 0xFF;
+ * int b = (rgb >> 0) & 0xFF;
+ *
+ * Given the ARGB components (8-bits each) of a color,
* the following statement packs it into a 32-bit {@code int}:
- *
- * int r = (rgb >> 16) & 0xFF;
- * int g = (rgb >> 8) & 0xFF;
- * int b = (rgb >> 0) & 0xFF;
- *
- *
- * int rgb = (r << 16) + (g << 8) + (b << 0);
- *
+ *
+ *
+ * int argb = (a << 24) | (r << 16) | (g << 8) | (b << 0);
+ *
+ *
+ *
+ *
+ *
+ *
+ * int
.
- *
- *
*
- *
+ * The canonical element of a set can change only when the set
+ * itself changes during a call to union—it cannot
+ * change during a call to either find or count.
*
- *
*
- *
+ * The canonical element of a set can change only when the set
+ * itself changes during a call to union—it cannot
+ * change during a call to either find or count.
*