You are on page 1of 963

BinarySearch.

java
Below is the syntax highlighted version
of BinarySearch.java from 1.1 Programming Model.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac BinarySearch.java
* Execution:
java BinarySearch whitelist.txt <
input.txt
* Dependencies: In.java StdIn.java StdOut.java
* Data files:
http://algs4.cs.princeton.edu/11model/tinyW.txt
*
http://algs4.cs.princeton.edu/11model/tinyT.txt
*
http://algs4.cs.princeton.edu/11model/largeW.txt
*
http://algs4.cs.princeton.edu/11model/largeT.txt
*
* % java BinarySearch tinyW.txt < tinyT.txt
* 50
* 99
* 13
*
* % java BinarySearch largeW.txt < largeT.txt | more
* 499569
* 984875
* 295754
* 207807
* 140925
* 161828
* [367,966 total values]
*
***********************************************************
**************/
import java.util.Arrays;
/**

* The <tt>BinarySearch</tt> class provides a static


method for binary
* searching for an integer in a sorted array of integers.
* <p>
* The <em>rank</em> operations takes logarithmic time in
the worst case.
* <p>
* For additional documentation, see <a
href="http://algs4.cs.princeton.edu/11model">Section 1.1</a>
of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class BinarySearch {
/**
* This class should not be instantiated.
*/
private BinarySearch() { }
/**
* Searches for the integer key in the sorted array
a[].
* @param key the search key
* @param a the array of integers, must be sorted in
ascending order
* @return index of key in array a[] if present; -1 if
not present
*/
public static int rank(int key, int[] a) {
int lo = 0;
int hi = a.length - 1;
while (lo <= hi) {
// Key is in a[lo..hi] or not present.
int mid = lo + (hi - lo) / 2;
if
(key < a[mid]) hi = mid - 1;
else if (key > a[mid]) lo = mid + 1;
else return mid;
}
return -1;
}
/**

* Reads in a sequence of integers from the whitelist


file, specified as
* a command-line argument. Reads in integers from
standard input and
* prints to standard output those integers that do
*not* appear in the file.
*/
public static void main(String[] args) {
// read the integers from a file
In in = new In(args[0]);
int[] whitelist = in.readAllInts();
// sort the array
Arrays.sort(whitelist);
// read integer key from standard input; print if
not in whitelist
while (!StdIn.isEmpty()) {
int key = StdIn.readInt();
if (rank(key, whitelist) == -1)
StdOut.println(key);
}
}
}

Copyright 20022010, Robert Sedgewick and Kevin Wayne.


Last updated: Sun Aug 31 21:38:23 EDT 2014.

RandomSeq.java
Below is the syntax highlighted version
of RandomSeq.java from 1.1 Programming Model.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac RandomSeq.java
* Execution:
java RandomSeq N lo hi
* Dependencies: StdOut.java
*
* Prints N numbers between lo and hi.
*
* % java RandomSeq 5 100.0 200.0
* 123.43
* 153.13
* 144.38
* 155.18
* 104.02
*
***********************************************************
**************/
/**
* The <tt>RandomSeq</tt> class is a client that prints
out a pseudorandom
* sequence of real numbers in a given range.
* <p>
* For additional documentation, see <a
href="http://algs4.cs.princeton.edu/11model">Section 1.1</a>
of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class RandomSeq {

// this class should not be instantiated


private RandomSeq() { }
/**
* Reads in two command-line arguments lo and hi and
prints N uniformly
* random real numbers in [lo, hi) to standard output.
*/
public static void main(String[] args) {
// command-line arguments
int N = Integer.parseInt(args[0]);
// for backward compatibility with Intro to
Programming in Java version of RandomSeq
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();
StdOut.println(x);
}
}
else if (args.length == 3) {
double lo = Double.parseDouble(args[1]);
double hi = Double.parseDouble(args[2]);
// generate and print N numbers between lo and
hi
for (int i = 0; i < N; i++) {
double x = StdRandom.uniform(lo, hi);
StdOut.printf("%.2f\n", x);
}
}
else {
throw new IllegalArgumentException("Invalid
number of arguments");
}
}
}

Copyright 20022010, Robert Sedgewick and Kevin Wayne.


Last updated: Fri Jul 24 09:39:33 EDT 2015.

Average.java
Below is the syntax highlighted version
of Average.java from 1.1 Programming Model.
the Javadoc.

Here is

/
***********************************************************
**************
* 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
* 10.0 5.0 6.0
* 3.0 7.0 32.0
* [Ctrl-d]
* Average is 10.5
*
*
*

Note [Ctrl-d] signifies the end of file on Unix.


On windows use [Ctrl-z].

***********************************************************
**************/
/**
* The <tt>Average</tt> class provides a client for
reading in a sequence
* of real numbers and printing out their average.
* <p>
* For additional documentation, see <a
href="http://algs4.cs.princeton.edu/11model">Section 1.1</a>
of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.

*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class Average {
// this class should not be instantiated
private Average() { }
/**
* Reads in a sequence of real numbers from standard
input and prints
* out their average to standard output.
*/
public static void main(String[] args) {
int count = 0;
// number input values
double sum = 0.0;
// sum of input values
// read data and compute statistics
while (!StdIn.isEmpty()) {
double value = StdIn.readDouble();
sum += value;
count++;
}
// compute the average
double average = sum / count;
// print results
StdOut.println("Average is " + average);
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Fri Jul 24 09:39:33 EDT 2015.

Cat.java
Below is the syntax highlighted version
of Cat.java from 1.1 Programming Model.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac Cat.java
* Execution:
java Cat input0.txt input1.txt ...
output.txt
* Dependencies: In.java Out.java
*
* 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
* a tiny
* test.
*
* % java Cat in1.txt in2.txt out.txt
*
* % more out.txt
* This is
* a tiny
* test.
*
***********************************************************
**************/
/**
* The <tt>Cat</tt> class provides a client for
concatenating the results
* of several text files.
* <p>

* For additional documentation, see <a


href="http://algs4.cs.princeton.edu/11model">Section 1.1</a>
of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class Cat {
// this class should not be instantiated
private Cat() { }
/**
* Reads in a sequence of text files specified as the
first command-line
* arguments, concatenates them, and writes the results
to the file
* specified as the last command-line argument.
*/
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]);
String s = in.readAll();
out.println(s);
in.close();
}
out.close();
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Fri Jul 24 09:39:33 EDT 2015.

Knuth.java
Below is the syntax highlighted version
of Knuth.java from 1.1 Programming Model.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac Knuth.java
* Execution:
java Knuth < list.txt
* Dependencies: StdIn.java StdOut.java
* Data files:
http://algs4.cs.princeton.edu/11model/cards.txt
*
http://algs4.cs.princeton.edu/11model/cardsUnicode.txt
*
* Reads in a list of strings and prints them in random
order.
* The Knuth (or Fisher-Yates) shuffling algorithm
guarantees
* to rearrange the elements in uniformly random order,
under
* the assumption that Math.random() generates independent
and
* uniformly distributed numbers between 0 and 1.
*
* % more cards.txt
* 2C 3C 4C 5C 6C 7C 8C 9C 10C JC QC KC AC
* 2D 3D 4D 5D 6D 7D 8D 9D 10D JD QD KD AD
* 2H 3H 4H 5H 6H 7H 8H 9H 10H JH QH KH AH
* 2S 3S 4S 5S 6S 7S 8S 9S 10S JS QS KS AS
*
* % java Knuth < cards.txt
* 6H
* 9C
* 8H
* 7C
* JS
* ...
* KH

*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*

% more cardsUnicode.txt
2 3 4 5 6 7 8 9
2 3 4 5 6 7 8 9
2 3 4 5 6 7 8 9
2 3 4 5 6 7 8 9

10
10
10
10

J
J
J
J

Q
Q
Q
Q

K
K
K
K

A
A
A
A

% java Knuth < cardsUnicode.txt


2
K
6
5
J
...
A

***********************************************************
**************/
/**
* The <tt>Knuth</tt> class provides a client for reading
in a
* sequence of strings and <em>shuffling</em> them using
the Knuth (or Fisher-Yates)
* shuffling algorithm. This algorithm guarantees to
rearrange the
* elements in uniformly random order, under
* the assumption that Math.random() generates independent
and
* uniformly distributed numbers between 0 and 1.
* <p>
* For additional documentation, see <a
href="http://algs4.cs.princeton.edu/11model">Section 1.1</a>
of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class Knuth {
// this class should not be instantiated
private Knuth() { }
/**

* Rearranges an array of objects in uniformly random


order
* (under the assumption that <tt>Math.random()</tt>
generates independent
* and uniformly distributed numbers between 0 and 1).
* @param a the array to be shuffled
* @see StdRandom
*/
public static void shuffle(Object[] a) {
int N = a.length;
for (int i = 0; i < N; i++) {
// choose index uniformly in [i, N-1]
int r = i + (int) (Math.random() * (N - i));
Object swap = a[r];
a[r] = a[i];
a[i] = swap;
}
}
/**
* Reads in a sequence of strings from standard input,
shuffles
* them, and prints out the results.
*/
public static void main(String[] args) {
// read in the data
String[] a = StdIn.readAllStrings();
// shuffle the array
Knuth.shuffle(a);
// print results.
for (int i = 0; i < a.length; i++)
StdOut.println(a[i]);
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Fri Jul 24 09:39:33 EDT 2015.

Counter.java
Below is the syntax highlighted version
of Counter.java from 1.2 Data Abstraction.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac Counter.java
* Execution:
java Counter N T
* Dependencies: StdRandom.java StdOut.java
*
* A mutable data type for an integer counter.
*
* The test clients create N counters and performs T
increment
* operations on random counters.
*
* % java Counter 6 600000
* 0: 99870
* 1: 99948
* 2: 99738
* 3: 100283
* 4: 100185
* 5: 99976
*
***********************************************************
**************/
/**
* The <tt>Counter</tt> class is a mutable data type to
encapsulate a counter.
* <p>

* For additional documentation, see <a


href="/algs4/12oop">Section 1.2</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class Counter implements Comparable<Counter> {
private final String name;
private int count = 0;

// counter name
// current value

/**
* Initializes a new counter starting at 0, with the
given id.
* @param id the name of the counter
*/
public Counter(String id) {
name = id;
}
/**
* Increments the counter by 1.
*/
public void increment() {
count++;
}
/**
* The current count.
*/
public int tally() {
return count;
}
/**
* A string representation of this counter.
*/
public String toString() {
return count + " " + name;
}
/**
* Compares this counter to that counter.
*/
public int compareTo(Counter that) {

if
(this.count < that.count) return -1;
else if (this.count > that.count) return +1;
else
return 0;
}
/**
* Reads two command-line integers N and T; creates N
counters;
* increments T counters at random; and prints results.
*/
public static void main(String[] args) {
int N = Integer.parseInt(args[0]);
int T = Integer.parseInt(args[1]);
// create N counters
Counter[] hits = new Counter[N];
for (int i = 0; i < N; i++) {
hits[i] = new Counter("counter" + i);
}
// increment T counters at random
for (int t = 0; t < T; t++) {
hits[StdRandom.uniform(N)].increment();
}
// print results
for (int i = 0; i < N; i++) {
StdOut.println(hits[i]);
}
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Tue Jul 28 13:02:59 EDT 2015.

StaticSETofInts.java
Below is the syntax highlighted version
of StaticSETofInts.java from 1.2 Data Abstraction.
is the Javadoc.

Here

/
***********************************************************
**************
* Compilation: javac StaticSetOfInts.java
* Execution:
none
* Dependencies: StdOut.java
*
* Data type to store a set of integers.
*
***********************************************************
**************/
import java.util.Arrays;
/**
* The <tt>StaticSETofInts</tt> class represents a set of
integers.
* It supports searching for a given integer is in the
set. It accomplishes
* this by keeping the set of integers in a sorted array
and using
* binary search to find the given integer.
* <p>
* The <em>rank</em> and <em>contains</em> operations take
* logarithmic time in the worst case.
* <p>
* For additional documentation, see <a
href="http://algs4.cs.princeton.edu/12oop">Section 1.2</a>
of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.

*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class StaticSETofInts {
private int[] a;
/**
* Initializes a set of integers specified by the
integer array.
* @param keys the array of integers
* @throws IllegalArgumentException if the array
contains duplicate integers
*/
public StaticSETofInts(int[] keys) {
// defensive copy
a = new int[keys.length];
for (int i = 0; i < keys.length; i++)
a[i] = keys[i];
// sort the integers
Arrays.sort(a);
// check for duplicates
for (int i = 1; i < a.length; i++)
if (a[i] == a[i-1])
throw new IllegalArgumentException("Argument
arrays contains duplicate keys.");
}
/**
* Is the key in this set of integers?
* @param key the search key
* @return true if the set of integers contains the
key; false otherwise
*/
public boolean contains(int key) {
return rank(key) != -1;
}
/**
* Returns either the index of the search key in the
sorted array
* (if the key is in the set) or -1 (if the key is not
in the set).
* @param key the search key

* @return the number of keys in this set less than the


key (if the key is in the set)
* or -1 (if the key is not in the set).
*/
public int rank(int key) {
int lo = 0;
int hi = a.length - 1;
while (lo <= hi) {
// Key is in a[lo..hi] or not present.
int mid = lo + (hi - lo) / 2;
if
(key < a[mid]) hi = mid - 1;
else if (key > a[mid]) lo = mid + 1;
else return mid;
}
return -1;
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Tue Jul 28 13:02:59 EDT 2015.

Whitelist.java
Below is the syntax highlighted version
of Whitelist.java from 1.2 Data Abstraction.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac Whitelist.java
* Execution:
java Whitelist whitelist.txt < data.txt
* Dependencies: StaticSetOfInts.java In.java StdOut.java
*
* Data files:
http://algs4.cs.princeton.edu/11model/tinyW.txt
*
http://algs4.cs.princeton.edu/11model/tinyT.txt
*
http://algs4.cs.princeton.edu/11model/largeW.txt
*
http://algs4.cs.princeton.edu/11model/largeT.txt
*
* Whitelist filter.
*
*
* % java Whitelist tinyW.txt < tinyT.txt
* 50
* 99
* 13
*
* % java Whitelist largeW.txt < largeT.txt | more
* 499569
* 984875
* 295754
* 207807
* 140925
* 161828
* [367,966 total values]
*
***********************************************************
**************/

/**
* The <tt>Whitelist</tt> class provides a client for
reading in
* a set of integers from a file; reading in a sequence of
integers
* from standard input; and printing to standard output
those
* integers not in the whitelist.
* <p>
* For additional documentation, see <a
href="http://algs4.cs.princeton.edu/12oop">Section 1.2</a>
of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class Whitelist {
/**
* Reads in a sequence of integers from the whitelist
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.
*/
public static void main(String[] args) {
In in = new In(args[0]);
int[] white = in.readAllInts();
StaticSETofInts set = new StaticSETofInts(white);
// Read key, print if not in whitelist.
while (!StdIn.isEmpty()) {
int key = StdIn.readInt();
if (!set.contains(key))
StdOut.println(key);
}
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Sun Feb 2 06:06:56 EST 2014.

Vector.java
Below is the syntax highlighted version
of Vector.java from 1.2 Data Abstraction.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac Vector.java
* Execution:
java Vector
* Dependencies: StdOut.java
*
* Implementation of a vector of real numbers.
*
* This class is implemented to be immutable: once the
client program
* initialize a Vector, it cannot change any of its fields
* (N or data[i]) either directly or indirectly.
Immutability is a
* very desirable feature of a data type.
*
* % java Vector
*
x
= [ 1.0 2.0 3.0 4.0 ]
*
y
= [ 5.0 2.0 4.0 1.0 ]
*
z
= [ 6.0 4.0 7.0 5.0 ]
*
10z
= [ 60.0 40.0 70.0 50.0 ]
*
|x|
= 5.477225575051661
*
<x, y> = 25.0
*
*
* Note that Vector is also the name of an unrelated Java
library class.
*
***********************************************************
**************/
/**
* The <tt>Vector</tt> class represents a <em>d</em>dimensional mathematical vector.

* Vectors are immutable: their values cannot be changed


after they are created.
* The class <code>Vectors</code> includes methods for
addition, subtraction,
* dot product, scalar product, unit vector, Euclidean
distance, and
* Euclidean norm.
* <p>
* For additional documentation, see <a
href="/algs4/12oop">Section 1.2</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class Vector {
private int N;
private double[] data;
components

// length of the vector


// array of vector's

/**
* Initializes a d-dimensional zero vector.
* @param d the dimension of the vector
*/
public Vector(int d) {
N = d;
data = new double[N];
}
/**
* Initializes a vector from either an array or a
vararg list.
* The vararg syntax supports a constructor that takes
a variable number of
* arugments such as Vector x = new Vector(1.0, 2.0,
3.0, 4.0).
* @param a the array or vararg list
*/
public Vector(double... a) {
N = a.length;
// defensive copy so that client can't alter our
copy of data[]
data = new double[N];

for (int i = 0; i < N; i++)


data[i] = a[i];
}
/**
* Returns
* @return
*/
public int
return
}

the length of this vector.


the dimension of this vector
length() {
N;

/**
* Returns the inner product of this vector with that
vector.
* @param that the other vector
* @return the dot product between this vector and that
vector
* @throws IllegalArgumentException if the lengths of
the two vectors are not equal.
*/
public double dot(Vector that) {
if (this.N != that.N) throw new
IllegalArgumentException("Dimensions don't agree");
double sum = 0.0;
for (int i = 0; i < N; i++)
sum = sum + (this.data[i] * that.data[i]);
return sum;
}
/**
* Returns the Euclidean norm of this vector.
* @return the Euclidean norm of this vector
*/
public double magnitude() {
return Math.sqrt(this.dot(this));
}
/**
* Returns the Euclidean distance between this vector
and that vector.
* @param that the other vector
* @return the Euclidean distance between this vector
and that vector
* @throws IllegalArgumentException if the lengths of
the two vectors are not equal.
*/

public double distanceTo(Vector that) {


if (this.N != that.N) throw new
IllegalArgumentException("Dimensions don't agree");
return this.minus(that).magnitude();
}
/**
* Returns the sum of this vector and that vector: this
+ that.
* @param that the vector to add to this vector
* @return the sum of this vector and that vector
* @throws IllegalArgumentException if the lengths of
the two vectors are not equal.
*/
public Vector plus(Vector that) {
if (this.N != that.N) throw new
IllegalArgumentException("Dimensions don't agree");
Vector c = new Vector(N);
for (int i = 0; i < N; i++)
c.data[i] = this.data[i] + that.data[i];
return c;
}
/**
* Returns the difference between this vector and that
vector: this - that.
* @param that the vector to subtract from this vector
* @return the difference between this vector and that
vector
* @throws IllegalArgumentException if the lengths of
the two vectors are not equal.
*/
public Vector minus(Vector that) {
if (this.N != that.N) throw new
IllegalArgumentException("Dimensions don't agree");
Vector c = new Vector(N);
for (int i = 0; i < N; i++)
c.data[i] = this.data[i] - that.data[i];
return c;
}
/**
* Returns the ith cartesian coordinate.
* @param i the coordinate index
* @return the ith cartesian coordinate
*/
public double cartesian(int i) {

return data[i];
}
/**
* Returns the product of this factor multiplied by the
scalar factor: this * factor.
* @param factor the multiplier
* @return the scalar product of this vector and factor
*/
public Vector times(double factor) {
Vector c = new Vector(N);
for (int i = 0; i < N; i++)
c.data[i] = factor * data[i];
return c;
}
/**
* Returns a unit vector in the direction of this
vector.
* @return a unit vector in the direction of this
vector
* @throws ArithmeticException if this vector is the
zero vector.
*/
public Vector direction() {
if (this.magnitude() == 0.0) throw new
ArithmeticException("Zero-vector has no direction");
return this.times(1.0 / this.magnitude());
}
/**
* Returns a string representation of this vector.
* @return a string representation of this vector,
which consists of the
*
the vector entries, separates by single spaces
*/
public String toString() {
StringBuilder s = new StringBuilder();
for (int i = 0; i < N; i++)
s.append(data[i] + " ");
return s.toString();
}
/**
* Unit tests the data type methods.
*/

public static void


double[] xdata
double[] ydata
Vector x = new
Vector y = new

main(String[] args) {
= { 1.0, 2.0, 3.0, 4.0 };
= { 5.0, 2.0, 4.0, 1.0 };
Vector(xdata);
Vector(ydata);

StdOut.println("
StdOut.println("

x
y

= " + x);
= " + y);

Vector z = x.plus(y);
StdOut.println("
z

= " + z);

z = z.times(10.0);
StdOut.println(" 10z

= " + z);

StdOut.println(" |x|
=
StdOut.println(" <x, y>
=
StdOut.println("dist(x, y) =
StdOut.println("dir(x)
=

"
"
"
"

+
+
+
+

x.magnitude());
x.dot(y));
x.distanceTo(y));
x.direction());

}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Fri Jul 24 09:39:33 EDT 2015.

Date.java
Below is the syntax highlighted version of Date.java from
Algorithms.
Here is the Javadoc.

/
***********************************************************
**************
* Compilation: javac Date.java
* Execution:
java Date
* Dependencies: StdOut.java
*
* An immutable data type for dates.
*
***********************************************************
**************/
/**
* The <tt>Date</tt> class is an immutable data type to
encapsulate a
* date (day, month, and year).
* <p>
* For additional documentation, see <a
href="/algs4/12oop">Section 1.2</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class Date implements Comparable<Date> {
private static final int[] DAYS = { 0, 31, 29, 31, 30,
31, 30, 31, 31, 30, 31, 30, 31 };
private final int month;
private final int day;
DAYS[month]
private final int year;
/**

// month (between 1 and 12)


// day
(between 1 and
// year

* Initializes a new date from the month, day, and


year.
* @param month the month (between 1 and 12)
* @param day the day (between 1 and 28-31, depending
on the month)
* @param year the year
* @throws IllegalArgumentException if the date is
invalid
*/
public Date(int month, int day, int year) {
if (!isValid(month, day, year)) throw new
IllegalArgumentException("Invalid date");
this.month = month;
this.day
= day;
this.year = year;
}
/**
* Initializes new date specified as a string in form
MM/DD/YYYY.
* @param date the string representation of the date
* @throws IllegalArgumentException if the date is
invalid
*/
public Date(String date) {
String[] fields = date.split("/");
if (fields.length != 3) {
throw new IllegalArgumentException("Invalid
date");
}
month = Integer.parseInt(fields[0]);
day
= Integer.parseInt(fields[1]);
year = Integer.parseInt(fields[2]);
if (!isValid(month, day, year)) throw new
IllegalArgumentException("Invalid date");
}
/**
* Return the month.
* @return the month (an integer between 1 and 12)
*/
public int month() {
return month;
}
/**
* Return the day.

* @return the day (an integer between 1 and 31)


*/
public int day() {
return day;
}
/**
* Return the year.
* @return the year
*/
public int year() {
return year;
}
// is the given date valid?
private static boolean isValid(int m, int d, int y) {
if (m < 1 || m > 12)
return false;
if (d < 1 || d > DAYS[m]) return false;
if (m == 2 && d == 29 && !isLeapYear(y)) return
false;
return true;
}
/**
* Is year y a leap year?
* @return true if y is a leap year; false otherwise
*/
private static boolean isLeapYear(int y) {
if (y % 400 == 0) return true;
if (y % 100 == 0) return false;
return y % 4 == 0;
}
/**
* Returns the next date in the calendar.
* @return a date that represents the next day after
this day
*/
public Date next() {
if (isValid(month, day + 1, year))
return new
Date(month, day + 1, year);
else if (isValid(month + 1, 1, year)) return new
Date(month + 1, 1, year);
else
return new
Date(1, 1, year + 1);
}

/**
* Is this date after b?
* @return true if this date is after date b; false
otherwise
*/
public boolean isAfter(Date b) {
return compareTo(b) > 0;
}
/**
* Is this date before b?
* @return true if this date is before date b; false
otherwise
*/
public boolean isBefore(Date b) {
return compareTo(b) < 0;
}
/**
* Compare this date to that date.
* @return { a negative integer, zero, or a positive
integer }, depending
*
on whether this date is { before, equal to, after
} that date
*/
public int compareTo(Date that) {
if (this.year < that.year) return -1;
if (this.year > that.year) return +1;
if (this.month < that.month) return -1;
if (this.month > that.month) return +1;
if (this.day
< that.day)
return -1;
if (this.day
> that.day)
return +1;
return 0;
}
/**
* Return a string representation of this date.
* @return the string representation in the foramt
MM/DD/YYYY
*/
public String toString() {
return month + "/" + day + "/" + year;
}
/**
* Is this date equal to x?

* @return true if this date equals x; false otherwise


*/
public boolean equals(Object x) {
if (x == this) return true;
if (x == null) return false;
if (x.getClass() != this.getClass()) return false;
Date that = (Date) x;
return (this.month == that.month) && (this.day ==
that.day) && (this.year == that.year);
}
/**
* Return a hash code.
* @return a hash code for this date
*/
public int hashCode() {
int hash = 17;
hash = 31*hash + month;
hash = 31*hash + day;
hash = 31*hash + year;
return hash;
}
/**
* Unit tests the date data type.
*/
public static void main(String[] args) {
Date today = new Date(2, 25, 2004);
StdOut.println(today);
for (int i = 0; i < 10; i++) {
today = today.next();
StdOut.println(today);
}
StdOut.println(today.isAfter(today.next()));
StdOut.println(today.isAfter(today));
StdOut.println(today.next().isAfter(today));
Date birthday = new Date(10, 16, 1971);
StdOut.println(birthday);
for (int i = 0; i < 10; i++) {
birthday = birthday.next();
StdOut.println(birthday);
}
}

}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Fri Jul 24 09:57:21 EDT 2015.
Transaction.java
Below is the syntax highlighted version
of Transaction.java from Algorithms.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac Transaction.java
* Execution:
java Transaction
* Dependencies: StdOut.java
*
* Data type for commercial transactions.
*
***********************************************************
**************/
import java.util.Arrays;
import java.util.Comparator;
/**
* The <tt>Transaction</tt> class is an immutable data
type to encapsulate a
* commercial transaction with a customer name, date, and
amount.
* <p>
* For additional documentation, see <a
href="/algs4/12oop">Section 1.2</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class Transaction implements Comparable<Transaction>
{
private final String who;
// customer

private final Date


private final double

when;
amount;

// date
// amount

/**
* Initializes a new transaction from the given
arguments.
* @param who the person involved in the transaction
* @param when the date of the transaction
* @param amount the amount of the transaction
* @throws IllegalArgumentException if <tt>amount</tt>
*
is <tt>Double.NaN</tt>,
<tt>Double.POSITIVE_INFINITY</tt> or
*
<tt>Double.NEGATIVE_INFINITY</tt>
*/
public Transaction(String who, Date when, double amount)
{
if (Double.isNaN(amount) ||
Double.isInfinite(amount))
throw new IllegalArgumentException("Amount
cannot be NaN or infinite");
this.who
= who;
this.when
= when;
if (amount == 0.0) this.amount = 0.0; // to handle
-0.0
else
this.amount = amount;
}
/**
* Initializes a new transaction by parsing a string of
the form NAME DATE AMOUNT.
* @param transaction the string to parse
* @throws IllegalArgumentException if <tt>amount</tt>
*
is <tt>Double.NaN</tt>,
<tt>Double.POSITIVE_INFINITY</tt> or
*
<tt>Double.NEGATIVE_INFINITY</tt>
*/
public Transaction(String transaction) {
String[] a = transaction.split("\\s+");
who
= a[0];
when
= new Date(a[1]);
double value = Double.parseDouble(a[2]);
if (value == 0.0) amount = 0.0; // convert -0.0
0.0
else
amount = value;

if (Double.isNaN(amount) ||
Double.isInfinite(amount))
throw new IllegalArgumentException("Amount
cannot be NaN or infinite");
}
/**
* Returns the name of the customer involved in the
transaction.
* @return the name of the customer involved in the
transaction
*/
public String who() {
return who;
}
/**
* Returns the date of the transaction.
* @return the date of the transaction
*/
public Date when() {
return when;
}
/**
* Returns the amount of the transaction.
* @return the amount of the transaction
*/
public double amount() {
return amount;
}
/**
* Returns a string representation of the transaction.
* @return a string representation of the transaction
*/
public String toString() {
return String.format("%-10s %10s %8.2f", who, when,
amount);
}
/**
* Compares this transaction to that transaction.
* @return { a negative integer, zero, a positive
integer}, depending
*
on whether the amount of this transaction is
{ less than,

*
equal to, or greater than } the amount of that
transaction
*/
public int compareTo(Transaction that) {
if
(this.amount < that.amount) return -1;
else if (this.amount > that.amount) return +1;
else
return 0;
}
/**
* Is this transaction equal to x?
* @param x the other transaction
* @return true if this transaction is equal to x;
false otherwise
*/
public boolean equals(Object x) {
if (x == this) return true;
if (x == null) return false;
if (x.getClass() != this.getClass()) return false;
Transaction that = (Transaction) x;
return (this.amount == that.amount) &&
(this.who.equals(that.who))
&&
(this.when.equals(that.when));
}
/**
* Returns a hash code for this transaction.
* @return a hash code for this transaction
*/
public int hashCode() {
int hash = 17;
hash = 31*hash + who.hashCode();
hash = 31*hash + when.hashCode();
hash = 31*hash + ((Double) amount).hashCode();
return hash;
}
/**
* Compares two transactions by customer name.
*/
public static class WhoOrder implements
Comparator<Transaction> {
public int compare(Transaction v, Transaction w) {
return v.who.compareTo(w.who);
}

}
/**
* Compares two transactions by date.
*/
public static class WhenOrder implements
Comparator<Transaction> {
public int compare(Transaction v, Transaction w) {
return v.when.compareTo(w.when);
}
}
/**
* Compares two transactions by amount.
*/
public static class HowMuchOrder implements
Comparator<Transaction> {
public int compare(Transaction v, Transaction w) {
if
(v.amount < w.amount) return -1;
else if (v.amount > w.amount) return +1;
else
return 0;
}
}
/**
* Unit tests the transaction data type.
*/
public static void main(String[] args) {
Transaction[] a = new Transaction[4];
a[0] = new Transaction("Turing
6/17/1990
644.08");
a[1] = new Transaction("Tarjan
3/26/2002
4121.85");
a[2] = new Transaction("Knuth
6/14/1999
288.34");
a[3] = new Transaction("Dijkstra 8/22/2007
2678.40");
StdOut.println("Unsorted");
for (int i = 0; i < a.length; i++)
StdOut.println(a[i]);
StdOut.println();
StdOut.println("Sort by date");
Arrays.sort(a, new Transaction.WhenOrder());
for (int i = 0; i < a.length; i++)

StdOut.println(a[i]);
StdOut.println();
StdOut.println("Sort by customer");
Arrays.sort(a, new Transaction.WhoOrder());
for (int i = 0; i < a.length; i++)
StdOut.println(a[i]);
StdOut.println();
StdOut.println("Sort by amount");
Arrays.sort(a, new Transaction.HowMuchOrder());
for (int i = 0; i < a.length; i++)
StdOut.println(a[i]);
StdOut.println();
}
}

Copyright 20022010, Robert Sedgewick and Kevin Wayne.


Last updated: Fri Jul 24 09:39:33 EDT 2015.

Point2D.java
Below is the syntax highlighted version
of Point2D.java from Algorithms.
Here is the Javadoc.

/
***********************************************************
**************
* Compilation: javac Point2D.java
* Execution:
java Point2D x0 y0 N
* Dependencies: StdDraw.java StdRandom.java
*
* Immutable point data type for points in the plane.
*
***********************************************************
**************/
import java.util.Arrays;
import java.util.Comparator;
/**
* The <tt>Point</tt> class is an immutable data type to
encapsulate a
* two-dimensional point with real-value coordinates.
* <p>
* 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 <a
href="/algs4/12oop">Section 1.2</a> of

* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and


Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public final class Point2D implements Comparable<Point2D> {
/**
* Compares two points by x-coordinate.
*/
public static final Comparator<Point2D> X_ORDER = new
XOrder();
/**
* Compares two points by y-coordinate.
*/
public static final Comparator<Point2D> Y_ORDER = new
YOrder();
/**
* Compares two points by polar radius.
*/
public static final Comparator<Point2D> R_ORDER = new
ROrder();
private final double x;
private final double y;

// x coordinate
// y coordinate

/**
* Initializes a new point (x, y).
* @param x the x-coordinate
* @param y the y-coordinate
* @throws IllegalArgumentException if either <tt>x</tt>
or <tt>y</tt>
*
is <tt>Double.NaN</tt>,
<tt>Double.POSITIVE_INFINITY</tt> or
*
<tt>Double.NEGATIVE_INFINITY</tt>
*/
public Point2D(double x, double y) {
if (Double.isInfinite(x) || Double.isInfinite(y))
throw new IllegalArgumentException("Coordinates
must be finite");
if (Double.isNaN(x) || Double.isNaN(y))
throw new IllegalArgumentException("Coordinates
cannot be NaN");

if (x == 0.0) this.x = 0.0;

// convert -0.0 to

+0.0
else

this.x = x;

if (y == 0.0) this.y = 0.0;

// convert -0.0 to

+0.0
else

this.y = y;

}
/**
* Returns the x-coordinate.
* @return the x-coordinate
*/
public double x() {
return x;
}
/**
* Returns the y-coordinate.
* @return the y-coordinate
*/
public double y() {
return y;
}
/**
* Returns the polar radius of this point.
* @return the polar radius of this point in polar
coordiantes: sqrt(x*x + y*y)
*/
public double r() {
return Math.sqrt(x*x + y*y);
}
/**
* Returns the angle of this point in polar
coordinates.
* @return the angle (in radians) of this point in
polar coordiantes (between -pi/2 and pi/2)
*/
public double theta() {
return Math.atan2(y, x);
}
/**
* Returns the angle between this point and that point.

* @return the angle in radians (between -pi and pi)


between this point and that point (0 if equal)
*/
private double angleTo(Point2D that) {
double dx = that.x - this.x;
double dy = that.y - this.y;
return Math.atan2(dy, dx);
}
/**
* Is a->b->c a counterclockwise turn?
* @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.
*/
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.xa.x);
if
(area2 < 0) return -1;
else if (area2 > 0) return +1;
else
return 0;
}
/**
* Returns twice the signed area of the triangle a-b-c.
* @param a first point
* @param b second point
* @param c third point
* @return twice the signed area of the triangle a-b-c
*/
public static double area2(Point2D a, Point2D b, Point2D
c) {
return (b.x-a.x)*(c.y-a.y) - (b.y-a.y)*(c.x-a.x);
}
/**
* Returns the Euclidean distance between this point
and that point.
* @param that the other point
* @return the Euclidean distance between this point
and that point
*/
public double distanceTo(Point2D that) {
double dx = this.x - that.x;
double dy = this.y - that.y;

return Math.sqrt(dx*dx + dy*dy);


}
/**
* Returns the square of the Euclidean distance between
this point and that point.
* @param that the other point
* @return the square of the Euclidean distance between
this point and that point
*/
public double distanceSquaredTo(Point2D that) {
double dx = this.x - that.x;
double dy = this.y - that.y;
return dx*dx + dy*dy;
}
/**
* Compares this point to that point by y-coordinate,
breaking ties by x-coordinate.
* @param that the other point
* @return { a negative integer, zero, a positive
integer } if this point is
*
{ less than, equal to, greater than } that point
*/
public int compareTo(Point2D that) {
if (this.y < that.y) return -1;
if (this.y > that.y) return +1;
if (this.x < that.x) return -1;
if (this.x > that.x) return +1;
return 0;
}
/**
* Compares two points by polar angle (between 0 and
2pi) with respect to this point.
*/
public Comparator<Point2D> polarOrder() {
return new PolarOrder();
}
/**
* Compares two points by atan2() angle (between -pi
and pi) with respect to this point.
*/
public Comparator<Point2D> atan2Order() {
return new Atan2Order();
}

/**
* Compares two points by distance to this point.
*/
public Comparator<Point2D> distanceToOrder() {
return new DistanceToOrder();
}
// compare points according to their x-coordinate
private static class XOrder implements
Comparator<Point2D> {
public int compare(Point2D p, Point2D q) {
if (p.x < q.x) return -1;
if (p.x > q.x) return +1;
return 0;
}
}
// compare points according to their y-coordinate
private static class YOrder implements
Comparator<Point2D> {
public int compare(Point2D p, Point2D q) {
if (p.y < q.y) return -1;
if (p.y > q.y) return +1;
return 0;
}
}
// compare points according to their polar radius
private static class ROrder implements
Comparator<Point2D> {
public int compare(Point2D p, Point2D q) {
double delta = (p.x*p.x + p.y*p.y) - (q.x*q.x +
q.y*q.y);
if (delta < 0) return -1;
if (delta > 0) return +1;
return 0;
}
}
// compare other points relative to atan2 angle
(bewteen -pi/2 and pi/2) they make with this Point
private class Atan2Order implements Comparator<Point2D>
{
public int compare(Point2D q1, Point2D q2) {
double angle1 = angleTo(q1);
double angle2 = angleTo(q2);

if
(angle1 < angle2) return -1;
else if (angle1 > angle2) return +1;
else
return 0;
}
}
// compare other points relative to polar angle
(between 0 and 2pi) they make with this Point
private class PolarOrder implements Comparator<Point2D>
{
public int compare(Point2D q1, Point2D q2) {
double dx1 = q1.x - x;
double dy1 = q1.y - y;
double dx2 = q2.x - x;
double dy2 = q2.y - y;
if
(dy1 >= 0 && dy2 < 0) return -1;
//
q1 above; q2 below
else if (dy2 >= 0 && dy1 < 0) return +1;
//
q1 below; q2 above
else if (dy1 == 0 && dy2 == 0) {
//
3-collinear and horizontal
if
(dx1 >= 0 && dx2 < 0) return -1;
else if (dx2 >= 0 && dx1 < 0) return +1;
else
return 0;
}
else return -ccw(Point2D.this, q1, q2);
//
both above or below
// Note: ccw() recomputes dx1, dy1, dx2, and
dy2
}
}
// compare points according to their distance to this
point
private class DistanceToOrder implements
Comparator<Point2D> {
public int compare(Point2D p, Point2D q) {
double dist1 = distanceSquaredTo(p);
double dist2 = distanceSquaredTo(q);
if
(dist1 < dist2) return -1;
else if (dist1 > dist2) return +1;
else
return 0;
}
}

/**
* Does this point equal y?
* @param other the other point
* @return true if this point equals the other point;
false otherwise
*/
public boolean equals(Object other) {
if (other == this) return true;
if (other == null) return false;
if (other.getClass() != this.getClass()) return
false;
Point2D that = (Point2D) other;
return this.x == that.x && this.y == that.y;
}
/**
* Return a string representation of this point.
* @return a string representation of this point in the
format (x, y)
*/
public String toString() {
return "(" + x + ", " + y + ")";
}
/**
* Returns an integer hash code for this point.
* @return an integer hash code for this point
*/
public int hashCode() {
int hashX = ((Double) x).hashCode();
int hashY = ((Double) y).hashCode();
return 31*hashX + hashY;
}
/**
* Plot this point using standard draw.
*/
public void draw() {
StdDraw.point(x, y);
}
/**
* Plot a line from this point to that point using
standard draw.
* @param that the other point
*/

public void drawTo(Point2D that) {


StdDraw.line(this.x, this.y, that.x, that.y);
}
/**
* Unit tests the point data type.
*/
public static void main(String[] args) {
int x0 = Integer.parseInt(args[0]);
int y0 = Integer.parseInt(args[1]);
int N = Integer.parseInt(args[2]);
StdDraw.setCanvasSize(800, 800);
StdDraw.setXscale(0, 100);
StdDraw.setYscale(0, 100);
StdDraw.setPenRadius(.005);
Point2D[] points = new Point2D[N];
for (int i = 0; i < N; i++) {
int x = StdRandom.uniform(100);
int y = StdRandom.uniform(100);
points[i] = new Point2D(x, y);
points[i].draw();
}
// draw p = (x0, x1) in red
Point2D p = new Point2D(x0, y0);
StdDraw.setPenColor(StdDraw.RED);
StdDraw.setPenRadius(.02);
p.draw();
// draw line segments from p to each point, one at
a time, in polar order
StdDraw.setPenRadius();
StdDraw.setPenColor(StdDraw.BLUE);
Arrays.sort(points, p.polarOrder());
for (int i = 0; i < N; i++) {
p.drawTo(points[i]);
StdDraw.show(100);
}
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Wed Jul 29 10:02:01 EDT 2015.

Interval1D.java
Below is the syntax highlighted version
of Interval1D.java from 1.2 Data Abstraction.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac Interval1D.java
* Execution:
java Interval1D
* Dependencies: StdOut.java
*
* 1-dimensional interval data type.
*
***********************************************************
**************/
import java.util.Arrays;
import java.util.Comparator;
/**
* The <tt>Interval1D</tt> class represents a onedimensional closed interval.
* Intervals are immutable: their values cannot be changed
after they are created.
* The class <code>Interval1D</code> includes methods for
checking whether
* an interval contains a point and determining whether
two intervals intersect.

* <p>
* For additional documentation, see <a
href="/algs4/12oop">Section 1.2</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class Interval1D {
/**
* Compares two intervals by left endpoint.
*/
public static final Comparator<Interval1D>
LEFT_ENDPOINT_ORDER = new LeftComparator();
/**
* Compares two intervals by right endpoint.
*/
public static final Comparator<Interval1D>
RIGHT_ENDPOINT_ORDER = new RightComparator();
/**
* Compares two intervals by length.
*/
public static final Comparator<Interval1D> LENGTH_ORDER
= new LengthComparator();
private final double left;
private final double right;
/**
* Initializes an interval [left, right].
* @param left the left endpoint
* @param right the right endpoint
* @throws IllegalArgumentException if the left
endpoint is greater than the right endpoint
* @throws IllegalArgumentException if either
<tt>left</tt> or <tt>right</tt>
*
is <tt>Double.NaN</tt>,
<tt>Double.POSITIVE_INFINITY</tt> or
*
<tt>Double.NEGATIVE_INFINITY</tt>
*/
public Interval1D(double left, double right) {

if (Double.isInfinite(left) ||
Double.isInfinite(right))
throw new IllegalArgumentException("Endpoints
must be finite");
if (Double.isNaN(left) || Double.isNaN(right))
throw new IllegalArgumentException("Endpoints
cannot be NaN");
// convert -0.0 to +0.0
if (left == 0.0) left = 0.0;
if (right == 0.0) right = 0.0;
if (left <= right) {
this.left = left;
this.right = right;
}
else throw new IllegalArgumentException("Illegal
interval");
}
/**
* Returns the left endpoint.
* @return the left endpoint
*/
public double left() {
return left;
}
/**
* Returns the right endpoint.
* @return the right endpoint
*/
public double right() {
return right;
}
/**
* Does this interval intersect that interval?
* @param that the other interval
* @return true if this interval intersects that
interval; false otherwise
*/
public boolean intersects(Interval1D that) {
if (this.right < that.left) return false;
if (that.right < this.left) return false;
return true;
}

/**
* Does this interval contain the value x?
* @param x the value
* @return true if this interval contains the value x;
false otherwise
*/
public boolean contains(double x) {
return (left <= x) && (x <= right);
}
/**
* Returns the length of this interval.
* @return the length of this interval (right - left)
*/
public double length() {
return right - left;
}
/**
* Returns a string representation of this interval.
* @return a string representation of this interval in
the form [left, right]
*/
public String toString() {
return "[" + left + ", " + right + "]";
}

// ascending order of left endpoint, breaking ties by


right endpoint
private static class LeftComparator implements
Comparator<Interval1D> {
public int compare(Interval1D a, Interval1D b) {
if
(a.left < b.left) return -1;
else if (a.left > b.left) return +1;
else if (a.right < b.right) return -1;
else if (a.right > b.right) return +1;
else
return 0;
}
}
// ascending order of right endpoint, breaking ties by
left endpoint
private static class RightComparator implements
Comparator<Interval1D> {

public int compare(Interval1D a, Interval1D b) {


if
(a.right < b.right) return -1;
else if (a.right > b.right) return +1;
else if (a.left < b.left) return -1;
else if (a.left > b.left) return +1;
else
return 0;
}
}
// ascending order of length
private static class LengthComparator implements
Comparator<Interval1D> {
public int compare(Interval1D a, Interval1D b) {
double alen = a.length();
double blen = b.length();
if
(alen < blen) return -1;
else if (alen > blen) return +1;
else
return 0;
}
}

/**
* Unit tests the <tt>Interval1D</tt> data type.
*/
public static void main(String[] args) {
Interval1D[] intervals = new Interval1D[4];
intervals[0] = new Interval1D(15.0, 33.0);
intervals[1] = new Interval1D(45.0, 60.0);
intervals[2] = new Interval1D(20.0, 70.0);
intervals[3] = new Interval1D(46.0, 55.0);
StdOut.println("Unsorted");
for (int i = 0; i < intervals.length; i++)
StdOut.println(intervals[i]);
StdOut.println();
StdOut.println("Sort by left endpoint");
Arrays.sort(intervals,
Interval1D.LEFT_ENDPOINT_ORDER);
for (int i = 0; i < intervals.length; i++)
StdOut.println(intervals[i]);
StdOut.println();
StdOut.println("Sort by right endpoint");

Arrays.sort(intervals,
Interval1D.RIGHT_ENDPOINT_ORDER);
for (int i = 0; i < intervals.length; i++)
StdOut.println(intervals[i]);
StdOut.println();
StdOut.println("Sort by length");
Arrays.sort(intervals, Interval1D.LENGTH_ORDER);
for (int i = 0; i < intervals.length; i++)
StdOut.println(intervals[i]);
StdOut.println();
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Tue Jul 28 13:02:59 EDT 2015.

Interval2D.java
Below is the syntax highlighted version
of Interval2D.java from 1.2 Data Abstraction.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac Interval2D.java
* Execution:
java Interval2D
* Dependencies: StdOut.java Interval1D.java StdDraw.java
*
* 2-dimensional interval data type.
*
***********************************************************
**************/
/**
* The <tt>Interval2D</tt> class represents a closed twodimensional interval,
* which represents all points (x, y) with both xleft <= x
<= xright and
* yleft <= y <= right.
* Two-dimensional intervals are immutable: their values
cannot be changed
* after they are created.
* The class <code>Interval2D</code> includes methods for
checking whether
* a two-dimensional interval contains a point and
determining whether
* two two-dimensional intervals intersect.

* <p>
* For additional documentation, see <a
href="/algs4/12oop">Section 1.2</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class Interval2D {
private final Interval1D x;
private final Interval1D y;
/**
* Initializes a two-dimensional interval.
* @param x the one-dimensional interval of xcoordinates
* @param y the one-dimensional interval of ycoordinates
*/
public Interval2D(Interval1D x, Interval1D y) {
this.x = x;
this.y = y;
}
/**
* Does this two-dimensional interval intersect that
two-dimensional interval?
* @param that the other two-dimensional interval
* @return true if this two-dimensional interval
intersects
*
that two-dimensional interval; false otherwise
*/
public boolean intersects(Interval2D that) {
if (!this.x.intersects(that.x)) return false;
if (!this.y.intersects(that.y)) return false;
return true;
}
/**
* Does this two-dimensional interval contain the point
p?
* @param p the two-dimensional point
* @return true if this two-dimensional interval
contains the point p; false otherwise
*/
public boolean contains(Point2D p) {

return x.contains(p.x())

&& y.contains(p.y());

}
/**
* Returns the area of this two-dimensional interval.
* @return the area of this two-dimensional interval
*/
public double area() {
return x.length() * y.length();
}
/**
* Returns a string representation of this twodimensional interval.
* @return a string representation of this twodimensional interval
*
in the form [xleft, xright] x [yleft, yright]
*/
public String toString() {
return x + " x " + y;
}
/**
* Draws this two-dimensional interval to standard
draw.
*/
public void draw() {
double xc = (x.left() + x.right()) / 2.0;
double yc = (y.left() + y.right()) / 2.0;
StdDraw.rectangle(xc, yc, x.length() / 2.0,
y.length() / 2.0);
}
/**
* Unit tests the <tt>Interval2D</tt> data type.
*/
public static void main(String[] args) {
double xlo = Double.parseDouble(args[0]);
double xhi = Double.parseDouble(args[1]);
double ylo = Double.parseDouble(args[2]);
double yhi = Double.parseDouble(args[3]);
int T = Integer.parseInt(args[4]);
Interval1D xinterval = new Interval1D(xlo, xhi);
Interval1D yinterval = new Interval1D(ylo, yhi);
Interval2D box = new Interval2D(xinterval,
yinterval);

box.draw();
Counter counter = new Counter("hits");
for (int t = 0; t < T; t++) {
double x = StdRandom.uniform(0.0, 1.0);
double y = StdRandom.uniform(0.0, 1.0);
Point2D p = new Point2D(x, y);
if (box.contains(p)) counter.increment();
else
p.draw();
}
StdOut.println(counter);
StdOut.printf("box area = %.2f\n", box.area());
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Tue Jul 28 13:02:59 EDT 2015.

ResizingArrayStack.java
Below is the syntax highlighted version
of ResizingArrayStack.java from 1.3 Stacks and Queues.
Here is the Javadoc.

/
***********************************************************
**************
* Compilation: javac ResizingArrayStack.java
* Execution:
java ResizingArrayStack < input.txt
* Dependencies: StdIn.java StdOut.java
* Data files:
http://algs4.cs.princeton.edu/13stacks/tobe.txt
*
* Stack implementation with a resizing array.
*
* % more tobe.txt
* to be or not to - be - - that - - - is
*
* % java ResizingArrayStack < tobe.txt
* to be not that or be (2 left on stack)
*
***********************************************************
**************/
import java.util.Iterator;
import java.util.NoSuchElementException;
/**
* The <tt>ResizingArrayStack</tt> class represents a
last-in-first-out (LIFO) stack

* of generic items.
* It supports the usual <em>push</em> and <em>pop</em>
operations, along with methods
* for peeking at the top item, testing if the stack is
empty, and iterating through
* the items in LIFO order.
* <p>
* This implementation uses a resizing array, which double
the underlying array
* when it is full and halves the underlying array when it
is one-quarter full.
* The <em>push</em> and <em>pop</em> operations take
constant amortized time.
* The <em>size</em>, <em>peek</em>, and <em>is-empty</em>
operations takes
* constant time in the worst case.
* <p>
* For additional documentation, see <a
href="/algs4/13stacks">Section 1.3</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class ResizingArrayStack<Item> implements
Iterable<Item> {
private Item[] a;
// array of items
private int N;
// number of elements on
stack
/**
* Initializes an empty stack.
*/
public ResizingArrayStack() {
a = (Item[]) new Object[2];
}
/**
* Is this stack empty?
* @return true if this stack is empty; false otherwise
*/
public boolean isEmpty() {
return N == 0;
}

/**
* Returns
* @return
*/
public int
return
}

the number of items in the stack.


the number of items in the stack
size() {
N;

// resize the underlying array holding the elements


private void resize(int capacity) {
assert capacity >= N;
Item[] temp = (Item[]) new Object[capacity];
for (int i = 0; i < N; i++) {
temp[i] = a[i];
}
a = temp;
}
/**
* Adds the item to this stack.
* @param item the item to add
*/
public void push(Item item) {
if (N == a.length) resize(2*a.length);
size of array if necessary
a[N++] = item;
item
}

// double
// add

/**
* Removes and returns the item most recently added to
this stack.
* @return the item most recently added
* @throws java.util.NoSuchElementException if this
stack is empty
*/
public Item pop() {
if (isEmpty()) throw new
NoSuchElementException("Stack underflow");
Item item = a[N-1];
a[N-1] = null;
// to
avoid loitering
N--;
// shrink size of array if necessary
if (N > 0 && N == a.length/4) resize(a.length/2);
return item;

}
/**
* Returns (but does not remove) the item most recently
added to this stack.
* @return the item most recently added to this stack
* @throws java.util.NoSuchElementException if this
stack is empty
*/
public Item peek() {
if (isEmpty()) throw new
NoSuchElementException("Stack underflow");
return a[N-1];
}
/**
* 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<Item> iterator() {
return new ReverseArrayIterator();
}
// an iterator, doesn't implement remove() since it's
optional
private class ReverseArrayIterator implements
Iterator<Item> {
private int i;
public ReverseArrayIterator() {
i = N-1;
}
public boolean hasNext() {
return i >= 0;
}
public void remove() {
throw new UnsupportedOperationException();
}
public Item next() {
if (!hasNext()) throw new
NoSuchElementException();

return a[i--];
}
}
/**
* Unit tests the <tt>Stack</tt> data type.
*/
public static void main(String[] args) {
ResizingArrayStack<String> s = new
ResizingArrayStack<String>();
while (!StdIn.isEmpty()) {
String item = StdIn.readString();
if (!item.equals("-")) s.push(item);
else if (!s.isEmpty()) StdOut.print(s.pop() + "
");
}
StdOut.println("(" + s.size() + " left on stack)");
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Thu Jul 23 17:05:46 EDT 2015.

LinkedStack.java
Below is the syntax highlighted version
of LinkedStack.java from 1.3 Stacks and Queues.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac LinkedStack.java
* Execution:
java LinkedStack < input.txt
* Dependencies: StdIn.java StdOut.java
*
* A generic stack, implemented using a linked list. Each
stack
* element is of type Item.
*
* % more tobe.txt
* to be or not to - be - - that - - - is
*
* % java LinkedStack < tobe.txt
* to be not that or be (2 left on stack)
*
***********************************************************
**************/
import java.util.Iterator;
import java.util.NoSuchElementException;
/**
* The <tt>LinkedStack</tt> class represents a last-infirst-out (LIFO) stack of
* generic items.

* It supports the usual <em>push</em> and <em>pop</em>


operations, along with methods
* for peeking at the top item, testing if the stack is
empty, and iterating through
* the items in LIFO order.
* <p>
* 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 <em>push</em>, <em>pop</em>, <em>peek</em>,
<em>size</em>, and <em>is-empty</em>
* operations all take constant time in the worst case.
* <p>
* For additional documentation, see <a
href="/algs4/13stacks">Section 1.3</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class LinkedStack<Item> implements Iterable<Item> {
private int N;
// size of the stack
private Node first;
// top of stack
// helper linked list class
private class Node {
private Item item;
private Node next;
}
/**
* Initializes an empty stack.
*/
public LinkedStack() {
first = null;
N = 0;
assert check();
}
/**
* Is this stack empty?
* @return true if this stack is empty; false otherwise
*/
public boolean isEmpty() {
return first == null;

}
/**
* Returns
* @return
*/
public int
return
}

the number of items in the stack.


the number of items in the stack
size() {
N;

/**
* Adds the item to this stack.
* @param item the item to add
*/
public void push(Item item) {
Node oldfirst = first;
first = new Node();
first.item = item;
first.next = oldfirst;
N++;
assert check();
}
/**
* Removes and returns the item most recently added to
this stack.
* @return the item most recently added
* @throws java.util.NoSuchElementException if this
stack is empty
*/
public Item pop() {
if (isEmpty()) throw new
NoSuchElementException("Stack underflow");
Item item = first.item;
// save item to
return
first = first.next;
// delete first node
N--;
assert check();
return item;
// return the saved
item
}
/**
* Returns (but does not remove) the item most recently
added to this stack.
* @return the item most recently added to this stack

* @throws java.util.NoSuchElementException if this


stack is empty
*/
public Item peek() {
if (isEmpty()) throw new
NoSuchElementException("Stack underflow");
return first.item;
}
/**
* Returns a string representation of this stack.
* @return the sequence of items in the stack in LIFO
order, separated by spaces
*/
public String toString() {
StringBuilder s = new StringBuilder();
for (Item item : this)
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<Item> iterator() { return new
ListIterator(); }
// an iterator, doesn't implement remove() since it's
optional
private class ListIterator implements Iterator<Item> {
private Node current = first;
public boolean hasNext() { return current != null;
}
public void remove()
{ throw new
UnsupportedOperationException(); }
public Item next() {
if (!hasNext()) throw new
NoSuchElementException();
Item item = current.item;
current = current.next;
return item;
}
}

// check internal invariants


private boolean check() {
if (N == 0) {
if (first != null) return false;
}
else if (N == 1) {
if (first == null)
return false;
if (first.next != null) return false;
}
else {
if (first.next == null) return false;
}
// check internal consistency of instance variable
N
int numberOfNodes = 0;
for (Node x = first; x != null; x = x.next) {
numberOfNodes++;
}
if (numberOfNodes != N) return false;
return true;
}
/**
* Unit tests the <tt>LinkedStack</tt> data type.
*/
public static void main(String[] args) {
LinkedStack<String> s = new LinkedStack<String>();
while (!StdIn.isEmpty()) {
String item = StdIn.readString();
if (!item.equals("-")) s.push(item);
else if (!s.isEmpty()) StdOut.print(s.pop() + "
");
}
StdOut.println("(" + s.size() + " left on stack)");
}
}

Copyright 20022010, Robert Sedgewick and Kevin Wayne.


Last updated: Thu Jul 23 17:05:46 EDT 2015.

Stack.java
Below is the syntax highlighted version of Stack.java from
Algorithms.
Here is the Javadoc.

/
***********************************************************
**************
* Compilation: javac Stack.java
* Execution:
java Stack < input.txt
* Dependencies: StdIn.java StdOut.java
*
* A generic stack, implemented using a singly-linked
list.
* Each stack element is of type Item.
*
* This version uses a static nested class Node (to save 8
bytes per
* Node), whereas the version in the textbook uses a nonstatic nested
* class (for simplicity).
*
* % more tobe.txt
* to be or not to - be - - that - - - is
*
* % java Stack < tobe.txt
* to be not that or be (2 left on stack)
*
***********************************************************
**************/
import java.util.Iterator;
import java.util.NoSuchElementException;

/**
* The <tt>Stack</tt> class represents a last-in-first-out
(LIFO) stack of generic items.
* It supports the usual <em>push</em> and <em>pop</em>
operations, along with methods
* for peeking at the top item, testing if the stack is
empty, and iterating through
* the items in LIFO order.
* <p>
* This implementation uses a singly-linked list with a
static nested class for
* linked-list nodes. See {@link LinkedStack} for the
version from the
* textbook that uses a non-static nested class.
* The <em>push</em>, <em>pop</em>, <em>peek</em>,
<em>size</em>, and <em>is-empty</em>
* operations all take constant time in the worst case.
* <p>
* For additional documentation, see <a
href="/algs4/13stacks">Section 1.3</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class Stack<Item> implements Iterable<Item> {
private int N;
// size of the stack
private Node<Item> first;
// top of stack
// helper linked list class
private static class Node<Item> {
private Item item;
private Node<Item> next;
}
/**
* Initializes an empty stack.
*/
public Stack() {
first = null;
N = 0;
}
/**
* Is this stack empty?

* @return true if this stack is empty; false otherwise


*/
public boolean isEmpty() {
return first == null;
}
/**
* Returns
* @return
*/
public int
return
}

the number of items in the stack.


the number of items in the stack
size() {
N;

/**
* Adds the item to this stack.
* @param item the item to add
*/
public void push(Item item) {
Node<Item> oldfirst = first;
first = new Node<Item>();
first.item = item;
first.next = oldfirst;
N++;
}
/**
* Removes and returns the item most recently added to
this stack.
* @return the item most recently added
* @throws java.util.NoSuchElementException if this
stack is empty
*/
public Item pop() {
if (isEmpty()) throw new
NoSuchElementException("Stack underflow");
Item item = first.item;
// save item to
return
first = first.next;
// delete first node
N--;
return item;
// return the saved
item
}
/**

* Returns (but does not remove) the item most recently


added to this stack.
* @return the item most recently added to this stack
* @throws java.util.NoSuchElementException if this
stack is empty
*/
public Item peek() {
if (isEmpty()) throw new
NoSuchElementException("Stack underflow");
return first.item;
}
/**
* Returns a string representation of this stack.
* @return the sequence of items in the stack in LIFO
order, separated by spaces
*/
public String toString() {
StringBuilder s = new StringBuilder();
for (Item item : this)
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<Item> iterator() {
return new ListIterator<Item>(first);
}
// an iterator, doesn't implement remove() since it's
optional
private class ListIterator<Item> implements
Iterator<Item> {
private Node<Item> current;
public ListIterator(Node<Item> first) {
current = first;
}
public boolean hasNext() {
return current != null;

}
public void remove() {
throw new UnsupportedOperationException();
}
public Item next() {
if (!hasNext()) throw new
NoSuchElementException();
Item item = current.item;
current = current.next;
return item;
}
}
/**
* Unit tests the <tt>Stack</tt> data type.
*/
public static void main(String[] args) {
Stack<String> s = new Stack<String>();
while (!StdIn.isEmpty()) {
String item = StdIn.readString();
if (!item.equals("-")) s.push(item);
else if (!s.isEmpty()) StdOut.print(s.pop() + "
");
}
StdOut.println("(" + s.size() + " left on stack)");
}
}

Copyright 20022010, Robert Sedgewick and Kevin Wayne.


Last updated: Thu Jul 23 17:05:46 EDT 2015.

ResizingArrayQueue.java
Below is the syntax highlighted version
of ResizingArrayQueue.java from 1.3 Stacks and Queues.
Here is the Javadoc.

/
***********************************************************
**************
* Compilation: javac ResizingArrayQueue.java
* Execution:
java ResizingArrayQueue < input.txt
* Dependencies: StdIn.java StdOut.java
* Data files:
http://algs4.cs.princeton.edu/13stacks/tobe.txt
*
* Queue implementation with a resizing array.
*
* % java ResizingArrayQueue < tobe.txt
* to be or not to be (2 left on queue)
*
***********************************************************
**************/
import java.util.Iterator;
import java.util.NoSuchElementException;
/**
* The <tt>ResizingArrayQueue</tt> class represents a
first-in-first-out (FIFO)
* queue of generic items.
* It supports the usual <em>enqueue</em> and
<em>dequeue</em>

* operations, along with methods for peeking at the first


item,
* testing if the queue is empty, and iterating through
* the items in FIFO order.
* <p>
* This implementation uses a resizing array, which double
the underlying array
* when it is full and halves the underlying array when it
is one-quarter full.
* The <em>enqueue</em> and <em>dequeue</em> operations
take constant amortized time.
* The <em>size</em>, <em>peek</em>, and <em>is-empty</em>
operations takes
* constant time in the worst case.
* <p>
* For additional documentation, see <a
href="http://algs4.cs.princeton.edu/13stacks">Section
1.3</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class ResizingArrayQueue<Item> implements
Iterable<Item> {
private Item[] q;
// queue elements
private int N = 0;
// number of elements on
queue
private int first = 0;
// index of first element
of queue
private int last = 0;
// index of next available
slot
/**
* Initializes an empty queue.
*/
public ResizingArrayQueue() {
// cast needed since no generic array creation in
Java
q = (Item[]) new Object[2];
}
/**
* Is this queue empty?
* @return true if this queue is empty; false otherwise

*/
public boolean isEmpty() {
return N == 0;
}
/**
* Returns
* @return
*/
public int
return
}

the number of items in this queue.


the number of items in this queue
size() {
N;

// resize the underlying array


private void resize(int max) {
assert max >= N;
Item[] temp = (Item[]) new Object[max];
for (int i = 0; i < N; i++) {
temp[i] = q[(first + i) % q.length];
}
q = temp;
first = 0;
last = N;
}
/**
* Adds the item to this queue.
* @param item the item to add
*/
public void enqueue(Item item) {
// double size of array if necessary and
front of array
if (N == q.length) resize(2*q.length);
size of array if necessary
q[last++] = item;
item
if (last == q.length) last = 0;
around
N++;
}

recopy to
// double
// add
// wrap-

/**
* Removes and returns the item on this queue that was
least recently added.
* @return the item on this queue that was least
recently added

* @throws java.util.NoSuchElementException if this


queue is empty
*/
public Item dequeue() {
if (isEmpty()) throw new
NoSuchElementException("Queue underflow");
Item item = q[first];
q[first] = null;
// to
avoid loitering
N--;
first++;
if (first == q.length) first = 0;
//
wrap-around
// shrink size of array if necessary
if (N > 0 && N == q.length/4) resize(q.length/2);
return item;
}
/**
* Returns the item least recently added to this queue.
* @return the item least recently added to this queue
* @throws java.util.NoSuchElementException if this
queue is empty
*/
public Item peek() {
if (isEmpty()) throw new
NoSuchElementException("Queue underflow");
return q[first];
}
/**
* 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<Item> iterator() {
return new ArrayIterator();
}
// an iterator, doesn't implement remove() since it's
optional
private class ArrayIterator implements Iterator<Item> {
private int i = 0;
public boolean hasNext() { return i < N;
}

public void remove()


UnsupportedOperationException();

{ throw new
}

public Item next() {


if (!hasNext()) throw new
NoSuchElementException();
Item item = q[(i + first) % q.length];
i++;
return item;
}
}
/**
* Unit tests the <tt>ResizingArrayQueue</tt> data
type.
*/
public static void main(String[] args) {
ResizingArrayQueue<String> q = new
ResizingArrayQueue<String>();
while (!StdIn.isEmpty()) {
String item = StdIn.readString();
if (!item.equals("-")) q.enqueue(item);
else if (!q.isEmpty()) StdOut.print(q.dequeue()
+ " ");
}
StdOut.println("(" + q.size() + " left on queue)");
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Thu Jul 23 17:05:46 EDT 2015.

LinkedQueue.java
Below is the syntax highlighted version
of LinkedQueue.java from 1.3 Stacks and Queues.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac LinkedQueue.java
* Execution:
java LinkedQueue < input.txt
* Dependencies: StdIn.java StdOut.java
* Data files:
http://algs4.cs.princeton.edu/13stacks/tobe.txt
*
* A generic queue, implemented using a singly-linked
list.
*
* % java Queue < tobe.txt
* to be or not to be (2 left on queue)
*
***********************************************************
**************/
import java.util.Iterator;

import java.util.NoSuchElementException;
/**
* The <tt>LinkedQueue</tt> class represents a first-infirst-out (FIFO)
* queue of generic items.
* It supports the usual <em>enqueue</em> and
<em>dequeue</em>
* operations, along with methods for peeking at the first
item,
* testing if the queue is empty, and iterating through
* the items in FIFO order.
* <p>
* 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 <em>enqueue</em>, <em>dequeue</em>, <em>peek</em>,
<em>size</em>, and <em>is-empty</em>
* operations all take constant time in the worst case.
* <p>
* For additional documentation, see <a
href="http://algs4.cs.princeton.edu/13stacks">Section
1.3</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class LinkedQueue<Item> implements Iterable<Item> {
private int N;
// number of elements on queue
private Node first;
// beginning of queue
private Node last;
// end of queue
// helper linked list class
private class Node {
private Item item;
private Node next;
}
/**
* Initializes an empty queue.
*/
public LinkedQueue() {
first = null;
last = null;

N = 0;
assert check();
}
/**
* Is this queue empty?
* @return true if this queue is empty; false otherwise
*/
public boolean isEmpty() {
return first == null;
}
/**
* Returns
* @return
*/
public int
return
}

the number of items in this queue.


the number of items in this queue
size() {
N;

/**
* Returns the item least recently added to this queue.
* @return the item least recently added to this queue
* @throws java.util.NoSuchElementException if this
queue is empty
*/
public Item peek() {
if (isEmpty()) throw new
NoSuchElementException("Queue underflow");
return first.item;
}
/**
* Adds the item to this queue.
* @param item the item to add
*/
public void enqueue(Item item) {
Node oldlast = last;
last = new Node();
last.item = item;
last.next = null;
if (isEmpty()) first = last;
else
oldlast.next = last;
N++;
assert check();
}

/**
* Removes and returns the item on this queue that was
least recently added.
* @return the item on this queue that was least
recently added
* @throws java.util.NoSuchElementException if this
queue is empty
*/
public Item dequeue() {
if (isEmpty()) throw new
NoSuchElementException("Queue underflow");
Item item = first.item;
first = first.next;
N--;
if (isEmpty()) last = null;
// to avoid loitering
assert check();
return item;
}
/**
* Returns a string representation of this queue.
* @return the sequence of items in FIFO order,
separated by spaces
*/
public String toString() {
StringBuilder s = new StringBuilder();
for (Item item : this)
s.append(item + " ");
return s.toString();
}
// check internal invariants
private boolean check() {
if (N == 0) {
if (first != null) return false;
if (last != null) return false;
}
else if (N == 1) {
if (first == null || last == null) return false;
if (first != last)
return false;
if (first.next != null)
return false;
}
else {
if (first == last)
return false;
if (first.next == null) return false;
if (last.next != null) return false;

// check internal consistency of instance


variable N
int numberOfNodes = 0;
for (Node x = first; x != null; x = x.next) {
numberOfNodes++;
}
if (numberOfNodes != N) return false;
// check internal consistency of instance
variable last
Node lastNode = first;
while (lastNode.next != null) {
lastNode = lastNode.next;
}
if (last != lastNode) return false;
}
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<Item> iterator() {
return new ListIterator();
}
// an iterator, doesn't implement remove() since it's
optional
private class ListIterator implements Iterator<Item> {
private Node current = first;
public boolean hasNext()

{ return current != null;

}
public void remove()
UnsupportedOperationException();

{ throw new
}

public Item next() {


if (!hasNext()) throw new
NoSuchElementException();
Item item = current.item;
current = current.next;
return item;

}
}
/**
* Unit tests the <tt>LinkedQueue</tt> data type.
*/
public static void main(String[] args) {
LinkedQueue<String> q = new LinkedQueue<String>();
while (!StdIn.isEmpty()) {
String item = StdIn.readString();
if (!item.equals("-")) q.enqueue(item);
else if (!q.isEmpty()) StdOut.print(q.dequeue()
+ " ");
}
StdOut.println("(" + q.size() + " left on queue)");
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Fri Jul 24 11:49:07 EDT 2015.

Queue.java
Below is the syntax highlighted version of Queue.java from
Algorithms.
Here is the Javadoc.

/
***********************************************************
**************
* Compilation: javac Queue.java
* Execution:
java Queue < input.txt
* Dependencies: StdIn.java StdOut.java
* Data files:
http://algs4.cs.princeton.edu/13stacks/tobe.txt
*
* A generic queue, implemented using a linked list.
*
* % java Queue < tobe.txt
* to be or not to be (2 left on queue)
*
***********************************************************
**************/
import java.util.Iterator;
import java.util.NoSuchElementException;

/**
* The <tt>Queue</tt> class represents a first-in-firstout (FIFO)
* queue of generic items.
* It supports the usual <em>enqueue</em> and
<em>dequeue</em>
* operations, along with methods for peeking at the first
item,
* testing if the queue is empty, and iterating through
* the items in FIFO order.
* <p>
* This implementation uses a singly-linked list with a
static nested class for
* linked-list nodes. See {@link LinkedQueue} for the
version from the
* textbook that uses a non-static nested class.
* The <em>enqueue</em>, <em>dequeue</em>, <em>peek</em>,
<em>size</em>, and <em>is-empty</em>
* operations all take constant time in the worst case.
* <p>
* For additional documentation, see <a
href="http://algs4.cs.princeton.edu/13stacks">Section
1.3</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class Queue<Item> implements Iterable<Item> {
private int N;
// number of elements on
queue
private Node<Item> first;
// beginning of queue
private Node<Item> last;
// end of queue
// helper linked list class
private static class Node<Item> {
private Item item;
private Node<Item> next;
}
/**
* Initializes an empty queue.
*/
public Queue() {
first = null;
last = null;

N = 0;
}
/**
* Is this queue empty?
* @return true if this queue is empty; false otherwise
*/
public boolean isEmpty() {
return first == null;
}
/**
* Returns
* @return
*/
public int
return
}

the number of items in this queue.


the number of items in this queue
size() {
N;

/**
* Returns the item least recently added to this queue.
* @return the item least recently added to this queue
* @throws java.util.NoSuchElementException if this
queue is empty
*/
public Item peek() {
if (isEmpty()) throw new
NoSuchElementException("Queue underflow");
return first.item;
}
/**
* Adds the item to this queue.
* @param item the item to add
*/
public void enqueue(Item item) {
Node<Item> oldlast = last;
last = new Node<Item>();
last.item = item;
last.next = null;
if (isEmpty()) first = last;
else
oldlast.next = last;
N++;
}
/**

* Removes and returns the item on this queue that was


least recently added.
* @return the item on this queue that was least
recently added
* @throws java.util.NoSuchElementException if this
queue is empty
*/
public Item dequeue() {
if (isEmpty()) throw new
NoSuchElementException("Queue underflow");
Item item = first.item;
first = first.next;
N--;
if (isEmpty()) last = null;
// to avoid loitering
return item;
}
/**
* Returns a string representation of this queue.
* @return the sequence of items in FIFO order,
separated by spaces
*/
public String toString() {
StringBuilder s = new StringBuilder();
for (Item item : this)
s.append(item + " ");
return s.toString();
}
/**
* 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<Item> iterator() {
return new ListIterator<Item>(first);
}
// an iterator, doesn't implement remove() since it's
optional
private class ListIterator<Item> implements
Iterator<Item> {
private Node<Item> current;
public ListIterator(Node<Item> first) {
current = first;

}
public boolean hasNext()

{ return current != null;

}
public void remove()
UnsupportedOperationException();

{ throw new
}

public Item next() {


if (!hasNext()) throw new
NoSuchElementException();
Item item = current.item;
current = current.next;
return item;
}
}
/**
* Unit tests the <tt>Queue</tt> data type.
*/
public static void main(String[] args) {
Queue<String> q = new Queue<String>();
while (!StdIn.isEmpty()) {
String item = StdIn.readString();
if (!item.equals("-")) q.enqueue(item);
else if (!q.isEmpty()) StdOut.print(q.dequeue()
+ " ");
}
StdOut.println("(" + q.size() + " left on queue)");
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Thu Jul 23 17:05:46 EDT 2015.

ResizingArrayBag.java
Below is the syntax highlighted version
of ResizingArrayBag.java from 1.3 Stacks and Queues.
is the Javadoc.

Here

/
***********************************************************
**************
* Compilation: javac ResizingArrayBag.java
* Execution:
java ResizingArrayBag
* Dependencies: StdIn.java StdOut.java
*
* Bag implementation with a resizing array.
*
***********************************************************
**************/
import java.util.Iterator;
import java.util.NoSuchElementException;
/**
* The <tt>ResizingArrayBag</tt> class represents a bag
(or multiset) of

* generic items. It supports insertion and iterating over


the
* items in arbitrary order.
* <p>
* This implementation uses a resizing array.
* See {@link LinkedBag} for a version that uses a singlylinked list.
* The <em>add</em> operation takes constant amortized
time; the
* <em>isEmpty</em>, and <em>size</em> operations
* take constant time. Iteration takes time proportional
to the number of items.
* <p>
* For additional documentation, see <a
href="http://algs4.cs.princeton.edu/13stacks">Section
1.3</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class ResizingArrayBag<Item> implements
Iterable<Item> {
private Item[] a;
// array of items
private int N = 0;
// number of elements on
stack
/**
* Initializes an empty bag.
*/
public ResizingArrayBag() {
a = (Item[]) new Object[2];
}
/**
* Is this bag empty?
* @return true if this bag is empty; false otherwise
*/
public boolean isEmpty() {
return N == 0;
}
/**
* Returns the number of items in this bag.
* @return the number of items in this bag
*/

public int size() {


return N;
}
// resize the underlying array holding the elements
private void resize(int capacity) {
assert capacity >= N;
Item[] temp = (Item[]) new Object[capacity];
for (int i = 0; i < N; i++)
temp[i] = a[i];
a = temp;
}
/**
* Adds the item to this bag.
* @param item the item to add to this bag
*/
public void add(Item item) {
if (N == a.length) resize(2*a.length);
size of array if necessary
a[N++] = item;
item
}

// double
// add

/**
* Returns an iterator that iterates over the items in
the bag in arbitrary order.
* @return an iterator that iterates over the items in
the bag in arbitrary order
*/
public Iterator<Item> iterator() {
return new ArrayIterator();
}
// an iterator, doesn't implement remove() since it's
optional
private class ArrayIterator implements Iterator<Item> {
private int i = 0;
public boolean hasNext() { return i < N;
}
public void remove()
{ throw new
UnsupportedOperationException(); }
public Item next() {
if (!hasNext()) throw new
NoSuchElementException();

return a[i++];
}
}
/**
* Unit tests the <tt>ResizingArrayBag</tt> data type.
*/
public static void main(String[] args) {
ResizingArrayBag<String> bag = new
ResizingArrayBag<String>();
bag.add("Hello");
bag.add("World");
bag.add("how");
bag.add("are");
bag.add("you");
for (String s : bag)
StdOut.println(s);
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Thu Jul 23 17:05:46 EDT 2015.

LinkedBag.java
Below is the syntax highlighted version
of LinkedBag.java from 1.3 Stacks and Queues.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac LinkedBag.java
* Execution:
java LinkedBag < input.txt
* Dependencies: StdIn.java StdOut.java
*
* A generic bag or multiset, implemented using a singlylinked list.
*
* % more tobe.txt
* to be or not to - be - - that - - - is
*
* % java Bag < tobe.txt
* size of bag = 14
* is
* -

*
*
*
*
*
*
*
*
*
*
*
*
*

that
be
to
not
or
be
to

***********************************************************
**************/
import java.util.Iterator;
import java.util.NoSuchElementException;
/**
* The <tt>LinkedBag</tt> class represents a bag (or
multiset) of
* generic items. It supports insertion and iterating over
the
* items in arbitrary order.
* <p>
* This implementation uses a singly-linked list with a
non-static nested class Node.
* See {@link Bag} for a version that uses a static nested
class.
* The <em>add</em>, <em>isEmpty</em>, and <em>size</em>
operations
* take constant time. Iteration takes time proportional
to the number of items.
* <p>
* For additional documentation, see <a
href="http://algs4.cs.princeton.edu/13stacks">Section
1.3</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class LinkedBag<Item> implements Iterable<Item> {
private int N;
// number of elements in bag

private Node first;

// beginning of bag

// helper linked list class


private class Node {
private Item item;
private Node next;
}
/**
* Initializes an empty bag.
*/
public LinkedBag() {
first = null;
N = 0;
}
/**
* Is this bag empty?
* @return true if this bag is empty; false otherwise
*/
public boolean isEmpty() {
return first == null;
}
/**
* Returns
* @return
*/
public int
return
}

the number of items in this bag.


the number of items in this bag
size() {
N;

/**
* Adds the item to this bag.
* @param item the item to add to this bag
*/
public void add(Item item) {
Node oldfirst = first;
first = new Node();
first.item = item;
first.next = oldfirst;
N++;
}
/**

* Returns an iterator that iterates over the items in


the bag.
*/
public Iterator<Item> iterator() {
return new ListIterator();
}
// an iterator, doesn't implement remove() since it's
optional
private class ListIterator implements Iterator<Item> {
private Node current = first;
public boolean hasNext()

{ return current != null;

}
public void remove()
UnsupportedOperationException();

{ throw new
}

public Item next() {


if (!hasNext()) throw new
NoSuchElementException();
Item item = current.item;
current = current.next;
return item;
}
}
/**
* Unit tests the <tt>LinkedBag</tt> data type.
*/
public static void main(String[] args) {
LinkedBag<String> bag = new LinkedBag<String>();
while (!StdIn.isEmpty()) {
String item = StdIn.readString();
bag.add(item);
}
StdOut.println("size of bag = " + bag.size());
for (String s : bag) {
StdOut.println(s);
}
}
}

Copyright 20022010, Robert Sedgewick and Kevin Wayne.


Last updated: Thu Jul 23 17:05:46 EDT 2015.

Bag.java
Below is the syntax highlighted version of Bag.java from
Algorithms.
Here is the Javadoc.

/
***********************************************************
**************
* Compilation: javac Bag.java
* Execution:
java Bag < input.txt
* Dependencies: StdIn.java StdOut.java
*
* A generic bag or multiset, implemented using a singlylinked list.
*
* % more tobe.txt
* to be or not to - be - - that - - - is
*
* % java Bag < tobe.txt
* size of bag = 14
* is
* * -

*
*
*
*
*
*
*
*
*
*
*
*

that
be
to
not
or
be
to

***********************************************************
**************/
import java.util.Iterator;
import java.util.NoSuchElementException;
/**
* The <tt>Bag</tt> class represents a bag (or multiset)
of
* generic items. It supports insertion and iterating over
the
* items in arbitrary order.
* <p>
* This implementation uses a singly-linked list with a
static nested class Node.
* See {@link LinkedBag} for the version from the
* textbook that uses a non-static nested class.
* The <em>add</em>, <em>isEmpty</em>, and <em>size</em>
operations
* take constant time. Iteration takes time proportional
to the number of items.
* <p>
* For additional documentation, see <a
href="http://algs4.cs.princeton.edu/13stacks">Section
1.3</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class Bag<Item> implements Iterable<Item> {
private int N;
// number of elements in
bag

private Node<Item> first;

// beginning of bag

// helper linked list class


private static class Node<Item> {
private Item item;
private Node<Item> next;
}
/**
* Initializes an empty bag.
*/
public Bag() {
first = null;
N = 0;
}
/**
* Is this bag empty?
* @return true if this bag is empty; false otherwise
*/
public boolean isEmpty() {
return first == null;
}
/**
* Returns
* @return
*/
public int
return
}

the number of items in this bag.


the number of items in this bag
size() {
N;

/**
* Adds the item to this bag.
* @param item the item to add to this bag
*/
public void add(Item item) {
Node<Item> oldfirst = first;
first = new Node<Item>();
first.item = item;
first.next = oldfirst;
N++;
}
/**

* Returns an iterator that iterates over the items in


the bag in arbitrary order.
* @return an iterator that iterates over the items in
the bag in arbitrary order
*/
public Iterator<Item> iterator() {
return new ListIterator<Item>(first);
}
// an iterator, doesn't implement remove() since it's
optional
private class ListIterator<Item> implements
Iterator<Item> {
private Node<Item> current;
public ListIterator(Node<Item> first) {
current = first;
}
public boolean hasNext()

{ return current != null;

}
public void remove()
UnsupportedOperationException();

{ throw new
}

public Item next() {


if (!hasNext()) throw new
NoSuchElementException();
Item item = current.item;
current = current.next;
return item;
}
}
/**
* Unit tests the <tt>Bag</tt> data type.
*/
public static void main(String[] args) {
Bag<String> bag = new Bag<String>();
while (!StdIn.isEmpty()) {
String item = StdIn.readString();
bag.add(item);
}
StdOut.println("size of bag = " + bag.size());
for (String s : bag) {
StdOut.println(s);
}

}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Thu Jul 23 17:05:46 EDT 2015.

Stopwatch.java
Below is the syntax highlighted version
of Stopwatch.java from Algorithms.
Here is the Javadoc.

/
***********************************************************
**************
* Compilation: javac Stopwatch.java
* Execution:
none
* Dependencies: none
*
* A utility class to measure the running time (wall
clock) of a
* program.
*
***********************************************************
**************/
/**

*
*
*
*
*
CPU
*
*
*
*/

The <tt>Stopwatch</tt> data type is for measuring


the time that elapses between the start and end of a
programming task (wall-clock time).
See {@link StopwatchCPU} for a version that measures
time.
@author Robert Sedgewick
@author Kevin Wayne

public class Stopwatch {


private final long start;
/**
* Initialize a stopwatch object.
*/
public Stopwatch() {
start = System.currentTimeMillis();
}
/**
* Returns the elapsed time (in seconds) since this
object was created.
*/
public double elapsedTime() {
long now = System.currentTimeMillis();
return (now - start) / 1000.0;
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Fri Jul 24 09:57:21 EDT 2015.

StopwatchCPU.java
Below is the syntax highlighted version
of StopwatchCPU.java from Algorithms.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac StopwatchCPU.java
* Execution:
none
* Dependencies: none
*
* A version of Stopwatch.java that measures CPU time on a
single
* core or processor (instead of wall clock time).
*
***********************************************************
**************/
import java.lang.management.ThreadMXBean;
import java.lang.management.ManagementFactory;

/**
* The <tt>StopwatchCPU</tt> data type is for measuring
* the CPU time used during a programming task.
*
* See {@link Stopwatch} for a version that measures wallclock time
* (the real time that elapses).
*
* @author Josh Hug
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class StopwatchCPU {
private static final double NANOSECONDS_PER_SECOND =
1000000000;
private final ThreadMXBean threadTimer;
private final long start;
/**
* Initialize a stopwatch object.
*/
public StopwatchCPU() {
threadTimer = ManagementFactory.getThreadMXBean();
start = threadTimer.getCurrentThreadCpuTime();
}
/**
* Returns the elapsed CPU time (in seconds) since the
object was created.
*/
public double elapsedTime() {
long now = threadTimer.getCurrentThreadCpuTime();
return (now - start) / NANOSECONDS_PER_SECOND;
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Fri Jul 24 09:57:21 EDT 2015.

LinearRegression.java
Below is the syntax highlighted version
of LinearRegression.java from Algorithms.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac LinearRegression.java
* Execution:
java LinearRegression
* Dependencies: none
*
* Compute least squares solution to y = beta * x + alpha.
* Simple linear regression.
*
* // TODO: rename beta and alpha to slope and intercept.
*
***********************************************************
**************/
/**

* The <tt>LinearRegression</tt> class performs a simple


linear regression
* on an set of <em>N</em> data points
(<em>y<sub>i</sub></em>, <em>x<sub>i</sub></em>).
* That is, it fits a straight line <em>y</em> = &alpha; +
&beta; <em>x</em>,
* (where <em>y</em> is the response variable, <em>x</em>
is the predictor variable,
* &alpha; is the <em>y-intercept</em>, and &beta; is the
<em>slope</em>)
* that minimizes the sum of squared residuals of the
linear regression model.
* It also computes associated statistics, including the
coefficient of
* determination <em>R</em><sup>2</sup> and the standard
deviation of the
* estimates for the slope and <em>y</em>-intercept.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class LinearRegression {
private final int N;
private final double alpha, beta;
private final double R2;
private final double svar, svar0, svar1;
/**
* Performs a linear regression on the data points
<tt>(y[i], x[i])</tt>.
* @param x the values of the predictor variable
* @param y the corresponding values of the response
variable
* @throws java.lang.IllegalArgumentException if the
lengths of the two arrays are not equal
*/
public LinearRegression(double[] x, double[] y) {
if (x.length != y.length) {
throw new IllegalArgumentException("array
lengths are not equal");
}
N = x.length;
// first pass
double sumx = 0.0, sumy = 0.0, sumx2 = 0.0;
for (int i = 0; i < N; i++)
sumx += x[i];

for (int i = 0; i < N; i++)


sumx2 += x[i]*x[i];
for (int i = 0; i < N; i++)
sumy += y[i];
double xbar = sumx / N;
double ybar = sumy / N;
// second pass: compute summary statistics
double xxbar = 0.0, yybar = 0.0, xybar = 0.0;
for (int i = 0; i < N; i++) {
xxbar += (x[i] - xbar) * (x[i] - xbar);
yybar += (y[i] - ybar) * (y[i] - ybar);
xybar += (x[i] - xbar) * (y[i] - ybar);
}
beta = xybar / xxbar;
alpha = ybar - beta * xbar;
// more statistical analysis
double rss = 0.0;
// residual sum of squares
double ssr = 0.0;
// regression sum of squares
for (int i = 0; i < N; i++) {
double fit = beta*x[i] + alpha;
rss += (fit - y[i]) * (fit - y[i]);
ssr += (fit - ybar) * (fit - ybar);
}
int degreesOfFreedom = N-2;
R2
= ssr / yybar;
svar = rss / degreesOfFreedom;
svar1 = svar / xxbar;
svar0 = svar/N + xbar*xbar*svar1;
}
/**
* Returns the <em>y</em>-intercept &alpha; of the best
of the best-fit line <em>y</em> = &alpha; + &beta;
<em>x</em>.
* @return the <em>y</em>-intercept &alpha; of the
best-fit line <em>y = &alpha; + &beta; x</em>
*/
public double intercept() {
return alpha;
}
/**
* Returns the slope &beta; of the best of the best-fit
line <em>y</em> = &alpha; + &beta; <em>x</em>.

* @return the slope &beta; of the best-fit line


<em>y</em> = &alpha; + &beta; <em>x</em>
*/
public double slope() {
return beta;
}
/**
* Returns the coefficient of determination
<em>R</em><sup>2</sup>.
* @return the coefficient of determination
<em>R</em><sup>2</sup>, which is a real number between 0
and 1
*/
public double R2() {
return R2;
}
/**
* Returns the standard error of the estimate for the
intercept.
* @return the standard error of the estimate for the
intercept
*/
public double interceptStdErr() {
return Math.sqrt(svar0);
}
/**
* Returns the standard error of the estimate for the
slope.
* @return the standard error of the estimate for the
slope
*/
public double slopeStdErr() {
return Math.sqrt(svar1);
}
/**
* Returns the expected response <tt>y</tt> given the
value of the predictor
*
variable <tt>x</tt>.
* @param x the value of the predictor variable
* @return the expected response <tt>y</tt> given the
value of the predictor
*
variable <tt>x</tt>
*/

public double predict(double x) {


return beta*x + alpha;
}
/**
* Returns a string representation of the simple linear
regression model.
* @return a string representation of the simple linear
regression model,
*
including the best-fit line and the coefficient of
determination <em>R</em><sup>2</sup>
*/
public String toString() {
String s = "";
s += String.format("%.2f N + %.2f", slope(),
intercept());
return s + " (R^2 = " + String.format("%.3f", R2())
+ ")";
}
}

Copyright 20022010, Robert Sedgewick and Kevin Wayne.


Last updated: Thu Jul 23 17:05:46 EDT 2015.

PolynomialRegression.java
Below is the syntax highlighted version
of PolynomialRegression.java from Algorithms.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac -cp .:jama.jar
PolynomialRegression.java
* Execution:
java -cp .:jama.jar PolynomialRegression
* Dependencies: jama.jar StdOut.java
*
* % java -cp .:jama.jar PolynomialRegression
* 0.01 N^3 + -1.64 N^2 + 168.92 N + -2113.73 (R^2 =
0.997)
*
***********************************************************
**************/
import Jama.Matrix;
import Jama.QRDecomposition;

/**
* The <tt>PolynomialRegression</tt> class performs a
polynomial regression
* on an set of <em>N</em> data points
(<em>y<sub>i</sub></em>, <em>x<sub>i</sub></em>).
* That is, it fits a polynomial
* <em>y</em> = &beta;<sub>0</sub> + &beta;<sub>1</sub>
<em>x</em> +
* &beta;<sub>2</sub> <em>x</em><sup>2</sup> + ... +
* &beta;<sub><em>d</em></sub>
<em>x</em><sup><em>d</em></sup>
* (where <em>y</em> is the response variable, <em>x</em>
is the predictor variable,
* and the &beta;<sub><em>i</em></sub> are the regression
coefficients)
* that minimizes the sum of squared residuals of the
multiple regression model.
* It also computes associated the coefficient of
determination <em>R</em><sup>2</sup>.
* <p>
* This implementation performs a QR-decomposition of the
underlying
* Vandermonde matrix, so it is not the fastest or most
numerically
* stable way to perform the polynomial regression.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class PolynomialRegression {
private final int N;
// number of observations
private final int degree;
// degree of the
polynomial regression
private final Matrix beta;
// the polynomial
regression coefficients
private double SSE;
// sum of squares due to
error
private double SST;
// total sum of squares
/**
* Performs a polynomial reggression on the data points
<tt>(y[i], x[i])</tt>.
* @param x the values of the predictor variable
* @param y the corresponding values of the response
variable
* @param degree the degree of the polynomial to fit

* @throws java.lang.IllegalArgumentException if the


lengths of the two arrays are not equal
*/
public PolynomialRegression(double[] x, double[] y, int
degree) {
this.degree = degree;
N = x.length;
// build Vandermonde matrix
double[][] vandermonde = new double[N][degree+1];
for (int i = 0; i < N; i++) {
for (int j = 0; j <= degree; j++) {
vandermonde[i][j] = Math.pow(x[i], j);
}
}
Matrix X = new Matrix(vandermonde);
// create matrix from vector
Matrix Y = new Matrix(y, N);
// find least squares solution
QRDecomposition qr = new QRDecomposition(X);
beta = qr.solve(Y);
// mean of y[] values
double sum = 0.0;
for (int i = 0; i < N; i++)
sum += y[i];
double mean = sum / N;
// total variation to be accounted for
for (int i = 0; i < N; i++) {
double dev = y[i] - mean;
SST += dev*dev;
}
// variation not accounted for
Matrix residuals = X.times(beta).minus(Y);
SSE = residuals.norm2() * residuals.norm2();
}
/**
* Returns the <tt>j</tt>th regression coefficient.
* @return the <tt>j</tt>th regression coefficient
*/
public double beta(int j) {

return beta.get(j, 0);


}
/**
* Returns
* @return
*/
public int
return
}

the degree of the polynomial to fit.


the degree of the polynomial to fit
degree() {
degree;

/**
* Returns the coefficient of determination
<em>R</em><sup>2</sup>.
* @return the coefficient of determination
<em>R</em><sup>2</sup>, which is a real number between 0
and 1
*/
public double R2() {
if (SST == 0.0) return 1.0;
// constant function
return 1.0 - SSE/SST;
}
/**
* Returns the expected response <tt>y</tt> given the
value of the predictor
*
variable <tt>x</tt>.
* @param x the value of the predictor variable
* @return the expected response <tt>y</tt> given the
value of the predictor
*
variable <tt>x</tt>
*/
public double predict(double x) {
// horner's method
double y = 0.0;
for (int j = degree; j >= 0; j--)
y = beta(j) + (x * y);
return y;
}
/**
* Returns a string representation of the polynomial
regression model.
* @return a string representation of the polynomial
regression model,
*
including the best-fit polynomial and the
coefficient of determination <em>R</em><sup>2</sup>

*/
public String toString() {
StringBuilder s = new StringBuilder();
int j = degree;
// ignoring leading zero coefficients
while (j >= 0 && Math.abs(beta(j)) < 1E-5)
j--;
// create remaining terms
while (j >= 0) {
if
(j == 0) s.append(String.format("%.2f ",
beta(j)));
else if (j == 1) s.append(String.format("%.2f N
+ ", beta(j)));
else
s.append(String.format("%.2f N^
%d + ", beta(j), j));
j--;
}
s = s.append(" (R^2 = " + String.format("%.3f",
R2()) + ")");
return s.toString();
}
public static void main(String[] args) {
double[] x = { 10, 20, 40, 80, 160, 200 };
double[] y = { 100, 350, 1500, 6700, 20160, 40000 };
PolynomialRegression regression = new
PolynomialRegression(x, y, 3);
StdOut.println(regression);
}
}

Copyright 20022010, Robert Sedgewick and Kevin Wayne.


Last updated: Tue Jul 28 13:40:41 EDT 2015.

ThreeSum.java
Below is the syntax highlighted version
of ThreeSum.java from 1.4 Analysis of Algorithms.

/
***********************************************************
**************
* Compilation: javac ThreeSum.java
* Execution:
java ThreeSum input.txt
* Dependencies: In.java StdOut.java Stopwatch.java
* Data files:
http://algs4.cs.princeton.edu/14analysis/1Kints.txt
*
http://algs4.cs.princeton.edu/14analysis/2Kints.txt
*
http://algs4.cs.princeton.edu/14analysis/4Kints.txt
*
http://algs4.cs.princeton.edu/14analysis/8Kints.txt
*
http://algs4.cs.princeton.edu/14analysis/16Kints.txt
*
http://algs4.cs.princeton.edu/14analysis/32Kints.txt

*
http://algs4.cs.princeton.edu/14analysis/1Mints.txt
*
* A program with cubic running time. Read in N integers
* and counts the number of triples that sum to exactly 0
* (ignoring integer overflow).
*
* % java ThreeSum 1Kints.txt
* 70
*
* % java ThreeSum 2Kints.txt
* 528
*
* % java ThreeSum 4Kints.txt
* 4039
*
***********************************************************
**************/
/**
* The <tt>ThreeSum</tt> class provides static methods for
counting
* and printing the number of triples in an array of
integers that sum to 0
* (ignoring integer overflow).
* <p>
* This implementation uses a triply nested loop and takes
proportional to N^3,
* where N is the number of integers.
* <p>
* For additional documentation, see <a
href="http://algs4.cs.princeton.edu/14analysis">Section
1.4</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class ThreeSum {
/**
* Prints to standard output the (i, j, k) with i < j <
k such that a[i] + a[j] + a[k] == 0.
* @param a the array of integers
*/

public static void printAll(int[] a) {


int N = a.length;
for (int i = 0; i < N; i++) {
for (int j = i+1; j < N; j++) {
for (int k = j+1; k < N; k++) {
if (a[i] + a[j] + a[k] == 0) {
StdOut.println(a[i] + " " + a[j] + "
" + a[k]);
}
}
}
}
}
/**
* Returns the number of triples (i, j, k) with i < j <
k such that a[i] + a[j] + a[k] == 0.
* @param a the array of integers
* @return the number of triples (i, j, k) with i < j <
k such that a[i] + a[j] + a[k] == 0
*/
public static int count(int[] a) {
int N = a.length;
int cnt = 0;
for (int i = 0; i < N; i++) {
for (int j = i+1; j < N; j++) {
for (int k = j+1; k < N; k++) {
if (a[i] + a[j] + a[k] == 0) {
cnt++;
}
}
}
}
return cnt;
}
/**
* Reads in a sequence of integers from a file,
specified as a command-line argument;
* counts the number of triples sum to exactly zero;
prints out the time to perform
* the computation.
*/
public static void main(String[] args) {
In in = new In(args[0]);
int[] a = in.readAllInts();

Stopwatch timer = new Stopwatch();


int cnt = count(a);
StdOut.println("elapsed time = " +
timer.elapsedTime());
StdOut.println(cnt);
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Tue Sep 24 09:27:51 EDT 2013.

ThreeSumFast.java
Below is the syntax highlighted version
of ThreeSumFast.java from 1.4 Analysis of Algorithms.

/
***********************************************************
**************
* Compilation: javac ThreeSumFast.java
* Execution:
java ThreeSumFast input.txt
* Dependencies: StdOut.java In.java Stopwatch.java
* Data files:
http://algs4.cs.princeton.edu/14analysis/1Kints.txt
*
http://algs4.cs.princeton.edu/14analysis/2Kints.txt
*
http://algs4.cs.princeton.edu/14analysis/4Kints.txt
*
http://algs4.cs.princeton.edu/14analysis/8Kints.txt
*
http://algs4.cs.princeton.edu/14analysis/16Kints.txt
*
http://algs4.cs.princeton.edu/14analysis/32Kints.txt
*
http://algs4.cs.princeton.edu/14analysis/1Mints.txt
*

* A program with N^2 log N running time. Read in N


integers
* and counts the number of triples that sum to exactly 0.
*
* Limitations
* ----------*
- we ignore integer overflow
*
- doesn't handle case when input has duplicates
*
*
* % java ThreeSumFast 1Kints.txt
* 70
*
* % java ThreeSumFast 2Kints.txt
* 528
*
* % java ThreeSumFast 4Kints.txt
* 4039
*
* % java ThreeSumFast 8Kints.txt
* 32074
*
* % java ThreeSumFast 16Kints.txt
* 255181
*
* % java ThreeSumFast 32Kints.txt
* 2052358
*
***********************************************************
**************/
import java.util.Arrays;
/**
* The <tt>ThreeSumFast</tt> class provides static methods
for counting
* and printing the number of triples in an array of
distinct integers that
* sum to 0 (ignoring integer overflow).
* <p>
* This implementation uses sorting and binary search and
takes time
* proportional to N^2 log N, where N is the number of
integers.
* <p>

* For additional documentation, see <a


href="http://algs4.cs.princeton.edu/14analysis">Section
1.4</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class ThreeSumFast {
// returns true if the sorted array a[] contains any
duplicated integers
private static boolean containsDuplicates(int[] a) {
for (int i = 1; i < a.length; i++)
if (a[i] == a[i-1]) return true;
return false;
}
/**
* Prints to standard output the (i, j, k) with i < j <
k such that a[i] + a[j] + a[k] == 0.
* @param a the array of integers
* @throws IllegalArgumentException if the array
contains duplicate integers
*/
public static void printAll(int[] a) {
int N = a.length;
Arrays.sort(a);
if (containsDuplicates(a)) throw new
IllegalArgumentException("array contains duplicate
integers");
for (int i = 0; i < N; i++) {
for (int j = i+1; j < N; j++) {
int k = Arrays.binarySearch(a, -(a[i] +
a[j]));
if (k > j) StdOut.println(a[i] + " " + a[j]
+ " " + a[k]);
}
}
}
/**
* Returns the number of triples (i, j, k) with i < j <
k such that a[i] + a[j] + a[k] == 0.
* @param a the array of integers

* @return the number of triples (i, j, k) with i < j <


k such that a[i] + a[j] + a[k] == 0
*/
public static int count(int[] a) {
int N = a.length;
Arrays.sort(a);
if (containsDuplicates(a)) throw new
IllegalArgumentException("array contains duplicate
integers");
int cnt = 0;
for (int i = 0; i < N; i++) {
for (int j = i+1; j < N; j++) {
int k = Arrays.binarySearch(a, -(a[i] +
a[j]));
if (k > j) cnt++;
}
}
return cnt;
}
/**
* Reads in a sequence of distinct integers from a
file, specified as a command-line argument;
* counts the number of triples sum to exactly zero;
prints out the time to perform
* the computation.
*/
public static void main(String[] args) {
In in = new In(args[0]);
int[] a = in.readAllInts();
int cnt = count(a);
StdOut.println(cnt);
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Tue Sep 24 09:30:55 EDT 2013.

DoublingTest.java
Below is the syntax highlighted version
of DoublingTest.java from 1.4 Analysis of Algorithms.
Here is the Javadoc.

/
***********************************************************
**************
* Compilation: javac DoublingTest.java
* Execution:
java DoublingTest
* Dependencies: ThreeSum.java Stopwatch.java
StdRandom.java StdOut.java
*
* % java DoublingTest
*
250
0.0
*
500
0.0
*
1000
0.1
*
2000
0.6
*
4000
4.5
*
8000 35.7
* ...
*

***********************************************************
**************/
/**
* The <tt>DoublingTest</tt> class provides a client for
measuring
* the running time of a method using a doubling test.
* <p>
* For additional documentation, see <a
href="http://algs4.cs.princeton.edu/14analysis">Section
1.4</a>
* of <i>Algorithms, 4th Edition</i> by Robert Sedgewick
and Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class DoublingTest {
private static final int MAXIMUM_INTEGER = 1000000;
// This class should not be instantiated.
private DoublingTest() { }
/**
* Returns the amount of time to call
<tt>ThreeSum.count()</tt> with <em>N</em>
* random 6-digit integers.
* @param N the number of integers
* @return amount of time (in seconds) to call
<tt>ThreeSum.count()</tt>
*
with <em>N</em> random 6-digit integers
*/
public static double timeTrial(int N) {
int[] a = new int[N];
for (int i = 0; i < N; i++) {
a[i] = StdRandom.uniform(-MAXIMUM_INTEGER,
MAXIMUM_INTEGER);
}
Stopwatch timer = new Stopwatch();
ThreeSum.count(a);
return timer.elapsedTime();
}
/**
* Prints table of running times to call
<tt>ThreeSum.count()</tt>

* for arrays of size 250, 500, 1000, 2000, and so


forth.
*/
public static void main(String[] args) {
for (int N = 250; true; N += N) {
double time = timeTrial(N);
StdOut.printf("%7d %5.1f\n", N, time);
}
}
}

Copyright 20022010, Robert Sedgewick and Kevin Wayne.


Last updated: Sun Jul 26 11:19:10 EDT 2015.

DoublingRatio.java
Below is the syntax highlighted version
of DoublingRatio.java from 1.4 Analysis of Algorithms.
Here is the Javadoc.

/
***********************************************************
**************
* Compilation: javac DoublingRatio.java
* Execution:
java DoublingRatio
* Dependencies: ThreeSum.java Stopwatch.java
StdRandom.java StdOut.java
*
*
* % java DoublingRatio
*
250
0.0
2.7
*
500
0.0
4.8
*
1000
0.1
6.9
*
2000
0.6
7.7
*
4000
4.5
8.0
*
8000 35.7
8.0
* ...
*

***********************************************************
**************/
/**
* The <tt>DoublingRatio</tt> class provides a client for
measuring
* the running time of a method using a doubling ratio
test.
* <p>
* For additional documentation, see <a
href="http://algs4.cs.princeton.edu/14analysis">Section
1.4</a>
* of <i>Algorithms, 4th Edition</i> by Robert Sedgewick
and Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class DoublingRatio {
private static final int MAXIMUM_INTEGER = 1000000;
// This class should not be instantiated.
private DoublingRatio() { }
/**
* Returns the amount of time to call
<tt>ThreeSum.count()</tt> with <em>N</em>
* random 6-digit integers.
* @param N the number of integers
* @return amount of time (in seconds) to call
<tt>ThreeSum.count()</tt>
*
with <em>N</em> random 6-digit integers
*/
public static double timeTrial(int N) {
int[] a = new int[N];
for (int i = 0; i < N; i++) {
a[i] = StdRandom.uniform(-MAXIMUM_INTEGER,
MAXIMUM_INTEGER);
}
Stopwatch timer = new Stopwatch();
ThreeSum.count(a);
return timer.elapsedTime();
}
/**

* Prints table of running times to call


<tt>ThreeSum.count()</tt>
* for arrays of size 250, 500, 1000, 2000, and so
forth, along
* with ratios of running times between successive
array sizes.
*/
public static void main(String[] args) {
double prev = timeTrial(125);
for (int N = 250; true; N += N) {
double time = timeTrial(N);
StdOut.printf("%6d %7.1f %5.1f\n", N, time,
time/prev);
prev = time;
}
}
}

Copyright 20022010, Robert Sedgewick and Kevin Wayne.


Last updated: Sun Jul 26 11:19:10 EDT 2015.

QuickFindUF.java
Below is the syntax highlighted version
of QuickFindUF.java from 1.5 Case Study: Union-Find.
is the Javadoc.

Here

/
***********************************************************
*****************
* Compilation: javac QuickFindUF.java
* Execution: java QuickFindUF < input.txt
* Dependencies: StdIn.java StdOut.java
*
* Quick-find algorithm.
*
***********************************************************
*****************/
/**
* The <tt>QuickFindUF</tt> class represents a union-find
data structure.
* It supports the <em>union</em> and <em>find</em>
operations, along with
* methods for determinig whether two objects are in the
same component

* and the total number of components.


* <p>
* This implementation uses quick find.
* Initializing a data structure with <em>N</em> objects
takes linear time.
* Afterwards, <em>find</em>, <em>connected</em>, and
<em>count</em>
* takes constant time but <em>union</em> takes linear
time.
* <p>
* For additional documentation, see <a
href="http://algs4.cs.princeton.edu/15uf">Section 1.5</a>
of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class QuickFindUF {
private int[] id;
// id[i] = component identifier of
i
private int count;
// number of components
/**
* Initializes an empty union-find data structure with
N isolated components 0 through N-1.
* @param N the number of objects
* @throws java.lang.IllegalArgumentException if N < 0
*/
public QuickFindUF(int N) {
count = N;
id = new int[N];
for (int i = 0; i < N; i++)
id[i] = i;
}
/**
* Returns
* @return
*/
public int
return
}
/**

the number of components.


the number of components (between 1 and N)
count() {
count;

* Returns the component identifier for the component


containing site <tt>p</tt>.
* @param p the integer representing one site
* @return the component identifier for the component
containing site <tt>p</tt>
* @throws java.lang.IndexOutOfBoundsException unless 0
<= p < N
*/
public int find(int p) {
validate(p);
return id[p];
}
// validate that p is a valid index
private void validate(int p) {
int N = id.length;
if (p < 0 || p >= N) {
throw new IndexOutOfBoundsException("index " + p
+ " is not between 0 and " + N);
}
}
/**
* Are the two sites <tt>p</tt> and <tt>q</tt> in the
same component?
* @param p the integer representing one site
* @param q the integer representing the other site
* @return <tt>true</tt> if the two sites <tt>p</tt>
and <tt>q</tt> are in
*
the same component, and <tt>false</tt> otherwise
* @throws java.lang.IndexOutOfBoundsException unless
both 0 <= p < N and 0 <= q < N
*/
public boolean connected(int p, int q) {
validate(p);
validate(q);
return id[p] == id[q];
}
/**
* Merges the component containing site<tt>p</tt> with
the component
* containing site <tt>q</tt>.
* @param p the integer representing one site
* @param q the integer representing the other site
* @throws java.lang.IndexOutOfBoundsException unless
both 0 <= p < N and 0 <= q < N

*/
public void union(int p, int q) {
int pID = id[p];
// needed for correctness
int qID = id[q];
// to reduce the number of array
accesses
// p and q are already in the same component
if (pID == qID) return;
for (int i = 0; i < id.length; i++)
if (id[i] == pID) id[i] = qID;
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 objects are in different components, merge
the two components
* and print the pair to standard output.
*/
public static void main(String[] args) {
int N = StdIn.readInt();
QuickFindUF uf = new QuickFindUF(N);
while (!StdIn.isEmpty()) {
int p = StdIn.readInt();
int q = StdIn.readInt();
if (uf.connected(p, q)) continue;
uf.union(p, q);
StdOut.println(p + " " + q);
}
StdOut.println(uf.count() + " components");
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Fri Jul 24 09:39:33 EDT 2015.

QuickUnionUF.java
Below is the syntax highlighted version
of QuickUnionUF.java from 1.5 Case Study: Union-Find.
Here is the Javadoc.

/
***********************************************************
*****************
* Compilation: javac QuickUnionUF.java
* Execution: java QuickUnionUF < input.txt
* Dependencies: StdIn.java StdOut.java
*
* Quick-union algorithm.
*
***********************************************************
*****************/
/**
* The <tt>QuickUnionUF</tt> class represents a union-find
data structure.
* It supports the <em>union</em> and <em>find</em>
operations, along with
* methods for determinig whether two objects are in the
same component
* and the total number of components.

* <p>
* This implementation uses quick union.
* Initializing a data structure with <em>N</em> objects
takes linear time.
* Afterwards, <em>union</em>, <em>find</em>, and
<em>connected</em> take
* time linear time (in the worst case) and <em>count</em>
takes constant
* time.
* <p>
* For additional documentation, see <a
href="http://algs4.cs.princeton.edu/15uf">Section 1.5</a>
of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class QuickUnionUF {
private int[] parent; // parent[i] = parent of i
private int count;
// number of components
/**
* Initializes an empty union-find data structure with
N isolated components 0 through N-1.
* @param N the number of objects
* @throws java.lang.IllegalArgumentException if N < 0
*/
public QuickUnionUF(int N) {
parent = new int[N];
count = N;
for (int i = 0; i < N; i++) {
parent[i] = i;
}
}
/**
* Returns
* @return
*/
public int
return
}
/**

the number of components.


the number of components (between 1 and N)
count() {
count;

* Returns the component identifier for the component


containing site <tt>p</tt>.
* @param p the integer representing one site
* @return the component identifier for the component
containing site <tt>p</tt>
* @throws java.lang.IndexOutOfBoundsException unless 0
<= p < N
*/
public int find(int p) {
validate(p);
while (p != parent[p])
p = parent[p];
return p;
}
// validate that p is a valid index
private void validate(int p) {
int N = parent.length;
if (p < 0 || p >= N) {
throw new IndexOutOfBoundsException("index " + p
+ " is not between 0 and " + N);
}
}
/**
* Are the two sites <tt>p</tt> and <tt>q</tt> in the
same component?
* @param p the integer representing one site
* @param q the integer representing the other site
* @return <tt>true</tt> if the sites <tt>p</tt> and
<tt>q</tt> are in the same
*
component, and <tt>false</tt> otherwise
* @throws java.lang.IndexOutOfBoundsException unless
both 0 <= p < N and 0 <= q < N
*/
public boolean connected(int p, int q) {
return find(p) == find(q);
}
/**
* Merges the component containing site<tt>p</tt> with
the component
* containing site <tt>q</tt>.
* @param p the integer representing one site
* @param q the integer representing the other site

* @throws java.lang.IndexOutOfBoundsException unless


both 0 <= p < N and 0 <= q < N
*/
public void union(int p, int q) {
int rootP = find(p);
int rootQ = find(q);
if (rootP == rootQ) return;
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 objects are in different components, merge
the two components
* and print the pair to standard output.
*/
public static void main(String[] args) {
int N = StdIn.readInt();
QuickUnionUF uf = new QuickUnionUF(N);
while (!StdIn.isEmpty()) {
int p = StdIn.readInt();
int q = StdIn.readInt();
if (uf.connected(p, q)) continue;
uf.union(p, q);
StdOut.println(p + " " + q);
}
StdOut.println(uf.count() + " components");
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Fri Jul 24 09:39:33 EDT 2015.

WeightedQuickUnionUF.java
Below is the syntax highlighted version
of WeightedQuickUnionUF.java from 1.5 Case Study: UnionFind.
Here is the Javadoc.

/
***********************************************************
*****************
* Compilation: javac WeightedQuickUnionUF.java
* Execution: java WeightedQuickUnionUF < input.txt
* Dependencies: StdIn.java StdOut.java
*
* Weighted quick-union (without path compression).
*
***********************************************************
*****************/
/**
* The <tt>WeightedQuickUnionUF</tt> class represents a
union-find data structure.
* It supports the <em>union</em> and <em>find</em>
operations, along with
* methods for determinig whether two objects are in the
same component
* and the total number of components.
* <p>

* This implementation uses weighted quick union by size


(without path compression).
* Initializing a data structure with <em>N</em> objects
takes linear time.
* Afterwards, <em>union</em>, <em>find</em>, and
<em>connected</em> take
* logarithmic time (in the worst case) and <em>count</em>
takes constant
* time.
* <p>
* For additional documentation, see <a
href="http://algs4.cs.princeton.edu/15uf">Section 1.5</a>
of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class WeightedQuickUnionUF {
private int[] parent;
// parent[i] = parent of i
private int[] size;
// size[i] = number of objects
in subtree rooted at i
private int count;
// number of components
/**
* Initializes an empty union-find data structure with
N isolated components 0 through N-1.
* @param N the number of objects
* @throws java.lang.IllegalArgumentException if N < 0
*/
public WeightedQuickUnionUF(int N) {
count = N;
parent = new int[N];
size = new int[N];
for (int i = 0; i < N; i++) {
parent[i] = i;
size[i] = 1;
}
}
/**
* Returns
* @return
*/
public int
return

the number of components.


the number of components (between 1 and N)
count() {
count;

}
/**
* Returns the component identifier for the component
containing site <tt>p</tt>.
* @param p the integer representing one site
* @return the component identifier for the component
containing site <tt>p</tt>
* @throws java.lang.IndexOutOfBoundsException unless 0
<= p < N
*/
public int find(int p) {
validate(p);
while (p != parent[p])
p = parent[p];
return p;
}
// validate that p is a valid index
private void validate(int p) {
int N = parent.length;
if (p < 0 || p >= N) {
throw new IndexOutOfBoundsException("index " + p
+ " is not between 0 and " + N);
}
}
/**
* Are the two sites <tt>p</tt> and <tt>q</tt> in the
same component?
* @param p the integer representing one site
* @param q the integer representing the other site
* @return <tt>true</tt> if the two sites <tt>p</tt>
and <tt>q</tt>
*
are in the same component, and <tt>false</tt>
otherwise
* @throws java.lang.IndexOutOfBoundsException unless
both 0 <= p < N and 0 <= q < N
*/
public boolean connected(int p, int q) {
return find(p) == find(q);
}
/**
* Merges the component containing site<tt>p</tt> with
the component

* containing site <tt>q</tt>.


* @param p the integer representing one site
* @param q the integer representing the other site
* @throws java.lang.IndexOutOfBoundsException unless
both 0 <= p < N and 0 <= q < N
*/
public void union(int p, int q) {
int rootP = find(p);
int rootQ = find(q);
if (rootP == rootQ) return;
// make smaller root point to larger one
if (size[rootP] < size[rootQ]) {
parent[rootP] = rootQ;
size[rootQ] += size[rootP];
}
else {
parent[rootQ] = rootP;
size[rootP] += size[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 objects are in different components, merge
the two components
* and print the pair to standard output.
*/
public static void main(String[] args) {
int N = StdIn.readInt();
WeightedQuickUnionUF uf = new
WeightedQuickUnionUF(N);
while (!StdIn.isEmpty()) {
int p = StdIn.readInt();
int q = StdIn.readInt();
if (uf.connected(p, q)) continue;
uf.union(p, q);
StdOut.println(p + " " + q);
}
StdOut.println(uf.count() + " components");
}
}

Copyright 20022010, Robert Sedgewick and Kevin Wayne.


Last updated: Fri Jul 24 09:39:33 EDT 2015.

UF.java
Below is the syntax highlighted version of UF.java from
Algorithms.
Here is the Javadoc.

/
***********************************************************
*****************
* Compilation: javac UF.java
* Execution:
java UF < input.txt
* Dependencies: StdIn.java StdOut.java
* Data files:
http://algs4.cs.princeton.edu/15uf/tinyUF.txt
*
http://algs4.cs.princeton.edu/15uf/mediumUF.txt
*
http://algs4.cs.princeton.edu/15uf/largeUF.txt
*
* Weighted quick-union by rank with path compression by
halving.
*
* % java UF < tinyUF.txt
* 4 3
* 3 8
* 6 5
* 9 4
* 2 1
* 5 0
* 7 2
* 6 1
* 2 components
*

***********************************************************
*****************/
/**
* The <tt>UF</tt> class represents a <em>union-find data
type</em>
* (also known as the <em>disjoint-sets data type</em>).
* It supports the <em>union</em> and <em>find</em>
operations,
* along with a <em>connected</em> operation for
determinig whether
* two sites in the same component and a <em>count</em>
operation that
* returns the total number of components.
* <p>
* The union-find data type models connectivity among a
set of <em>N</em>
* sites, named 0 through <em>N</em> &ndash; 1.
* The <em>is-connected-to</em> relation must be an
* <em>equivalence relation</em>:
* <ul>
* <p><li> <em>Reflexive</em>: <em>p</em> is connected to
<em>p</em>.
* <p><li> <em>Symmetric</em>: If <em>p</em> is connected
to <em>q</em>,
*
<em>q</em> is connected to <em>p</em>.
* <p><li> <em>Transitive</em>: If <em>p</em> is connected
to <em>q</em>
*
and <em>q</em> is connected to <em>r</em>, then
*
<em>p</em> is connected to <em>r</em>.
* </ul>
* An equivalence relation partitions the sites into
* <em>equivalence classes</em> (or <em>components</em>).
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
* <em>N</em> &ndash; 1.
* Initially, there are <em>N</em> components, with each
site in its
* own component. The <em>component identifier</em> of a
component
* (also known as the <em>root</em>, <em>canonical
element</em>, <em>leader</em>,

* or <em>set representative</em>) 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.
* <ul>
* <p><li><em>union</em>(<em>p</em>, <em>q</em>) adds a
*
connection between the two sites <em>p</em> and
<em>q</em>.
*
If <em>p</em> and <em>q</em> are in different
components,
*
then it replaces
*
these two components with a new component that
is the union of
*
the two.
* <p><li><em>find</em>(<em>p</em>) returns the component
*
identifier of the component containing
<em>p</em>.
* <p><li><em>connected</em>(<em>p</em>, <em>q</em>)
*
returns true if both <em>p</em> and <em>q</em>
*
are in the same component, and false otherwise.
* <p><li><em>count</em>() returns the number of
components.
* </ul>
* The component identifier of a component can change
* only when the component itself changes during a call to
* <em>union</em>&mdash;it cannot change during a call
* to <em>find</em>, <em>connected</em>, or
<em>count</em>.
* <p>
* This implementation uses weighted quick union by rank
with path compression
* by halving.
* Initializing a data structure with <em>N</em> sites
takes linear time.
* Afterwards, the <em>union</em>, <em>find</em>, and
<em>connected</em>
* operations take logarithmic time (in the worst case)
and the
* <em>count</em> operation takes constant time.
* Moreover, the amortized time per <em>union</em>,
<em>find</em>,
* and <em>connected</em> operation has inverse Ackermann
complexity.
* For alternate implementations of the same API, see
* {@link QuickUnionUF}, {@link QuickFindUF}, and {@link
WeightedQuickUnionUF}.

*
* <p>
* For additional documentation, see <a
href="http://algs4.cs.princeton.edu/15uf">Section 1.5</a>
of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class UF {
private
private
rooted at i
private

int[] parent; // parent[i] = parent of i


byte[] rank;
// rank[i] = rank of subtree
(never more than 31)
int count;
// number of components

/**
* Initializes an empty union-find data structure with
<tt>N</tt>
* isolated components <tt>0</tt> through <tt>N-1</tt>.
* @param N the number of sites
* @throws java.lang.IllegalArgumentException if <tt>N
&lt; 0</tt>
*/
public UF(int N) {
if (N < 0) throw new IllegalArgumentException();
count = N;
parent = new int[N];
rank = new byte[N];
for (int i = 0; i < N; i++) {
parent[i] = i;
rank[i] = 0;
}
}
/**
* Returns the component identifier for the component
containing site <tt>p</tt>.
* @param p the integer representing one object
* @return the component identifier for the component
containing site <tt>p</tt>
* @throws java.lang.IndexOutOfBoundsException unless
<tt>0 &le; p &lt; N</tt>
*/

public int find(int p) {


if (p < 0 || p >= parent.length) throw new
IndexOutOfBoundsException();
while (p != parent[p]) {
parent[p] = parent[parent[p]];
// path
compression by halving
p = parent[p];
}
return p;
}
/**
* Returns the number of components.
* @return the number of components (between <tt>1</tt>
and <tt>N</tt>)
*/
public int count() {
return count;
}
/**
* Are the two sites <tt>p</tt> and <tt>q</tt> in the
same component?
* @param p the integer representing one site
* @param q the integer representing the other site
* @return true if the two sites <tt>p</tt> and
<tt>q</tt> are in the same component; false otherwise
* @throws java.lang.IndexOutOfBoundsException unless
*
both <tt>0 &le; p &lt; N</tt> and <tt>0 &le; q
&lt; N</tt>
*/
public boolean connected(int p, int q) {
return find(p) == find(q);
}
/**
* Merges the component containing site <tt>p</tt> with
the
* the component containing site <tt>q</tt>.
* @param p the integer representing one site
* @param q the integer representing the other site
* @throws java.lang.IndexOutOfBoundsException unless
*
both <tt>0 &le; p &lt; N</tt> and <tt>0 &le; q
&lt; N</tt>
*/
public void union(int p, int q) {

int rootP = find(p);


int rootQ = find(q);
if (rootP == rootQ) return;
// make root of smaller rank point to root of
larger rank
if
(rank[rootP] < rank[rootQ]) parent[rootP] =
rootQ;
else if (rank[rootP] > rank[rootQ]) parent[rootQ] =
rootP;
else {
parent[rootQ] = rootP;
rank[rootP]++;
}
count--;
}
/**
* Reads in a an integer <tt>N</tt> and a sequence of
pairs of integers
* (between <tt>0</tt> and <tt>N-1</tt>) from standard
input, where each integer
* in the pair represents some site;
* if the sites are in different components, merge the
two components
* and print the pair to standard output.
*/
public static void main(String[] args) {
int N = StdIn.readInt();
UF uf = new UF(N);
while (!StdIn.isEmpty()) {
int p = StdIn.readInt();
int q = StdIn.readInt();
if (uf.connected(p, q)) continue;
uf.union(p, q);
StdOut.println(p + " " + q);
}
StdOut.println(uf.count() + " components");
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Thu Jul 23 17:05:46 EDT 2015.

Insertion.java
Below is the syntax highlighted version
of Insertion.java from 2.1 Elementary Sorts.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac Insertion.java
* Execution:
java Insertion < input.txt
* Dependencies: StdOut.java StdIn.java
* Data files:
http://algs4.cs.princeton.edu/21sort/tiny.txt
*
http://algs4.cs.princeton.edu/21sort/words3.txt
*
* Sorts a sequence of strings from standard input using
insertion sort.
*
* % more tiny.txt
* S O R T E X A M P L E
*
* % java Insertion < 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 Insertion < words3.txt
* all bad bed bug dad ... yes yet zoo
line ]
*

[ one string per

***********************************************************
**************/
import java.util.Comparator;
/**
* The <tt>Insertion</tt> class provides static methods
for sorting an
* array using insertion sort.
* <p>
* For additional documentation, see <a
href="http://algs4.cs.princeton.edu/21elementary">Section
2.1</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class Insertion {
// This class should not be instantiated.
private Insertion() { }
/**
* Rearranges the array in ascending order, using the
natural order.
* @param a the array to be sorted
*/
public static void sort(Comparable[] a) {
int N = a.length;
for (int i = 0; i < N; i++) {
for (int j = i; j > 0 && less(a[j], a[j-1]);
j--) {
exch(a, j, j-1);
}
assert isSorted(a, 0, i);
}
assert isSorted(a);
}

/**
* Rearranges the subarray a[lo..hi] in ascending
order, using the natural order.
* @param a the array to be sorted
* @param lo left endpoint
* @param hi right endpoint
*/
public static void sort(Comparable[] a, int lo, int hi)
{
for (int i = lo; i <= hi; i++) {
for (int j = i; j > lo && less(a[j], a[j-1]);
j--) {
exch(a, j, j-1);
}
}
assert isSorted(a, lo, hi);
}
/**
* Rearranges the array in ascending order, using a
comparator.
* @param a the array
* @param comparator the comparator specifying the
order
*/
public static void sort(Object[] a, Comparator
comparator) {
int N = a.length;
for (int i = 0; i < N; i++) {
for (int j = i; j > 0 && less(a[j], a[j-1],
comparator); j--) {
exch(a, j, j-1);
}
assert isSorted(a, 0, i, comparator);
}
assert isSorted(a, comparator);
}
/**
* Rearranges the subarray a[lo..hi] in ascending
order, using a comparator.
* @param a the array
* @param lo left endpoint
* @param hi right endpoint
* @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 j = i; j > lo && less(a[j], a[j-1],
comparator); j--) {
exch(a, j, j-1);
}
}
assert isSorted(a, lo, hi, comparator);
}
// return a permutation that gives the elements in a[]
in ascending order
// do not change the original array a[]
/**
* Returns a permutation that gives the elements in the
array in ascending order.
* @param a the array
* @return a permutation <tt>p[]</tt> such that
<tt>a[p[0]]</tt>, <tt>a[p[1]]</tt>,
*
..., <tt>a[p[N-1]]</tt> are in ascending order
*/
public static int[] indexSort(Comparable[] a) {
int N = a.length;
int[] index = new int[N];
for (int i = 0; i < N; i++)
index[i] = i;
for (int i = 0; i < N; i++)
for (int j = i; j > 0 && less(a[index[j]],
a[index[j-1]]); j--)
exch(index, j, j-1);
return index;
}
/**********************************************************
*************
* Helper sorting functions.
***********************************************************
************/
// is v < w ?

private static boolean less(Comparable v, Comparable w)


{
return (v.compareTo(w) < 0);
}
// is v < 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];
a[i] = a[j];
a[j] = swap;
}
// exchange a[i] and a[j] (for indirect sort)
private static void exch(int[] a, int i, int j) {
int swap = a[i];
a[i] = a[j];
a[j] = swap;
}
/**********************************************************
*************
* Check if array is sorted - useful for debugging.
***********************************************************
************/
private static boolean isSorted(Comparable[] a) {
return isSorted(a, 0, a.length - 1);
}
// is the array sorted
private static boolean
int hi) {
for (int i = lo+1;
if (less(a[i],
return true;
}

from a[lo] to a[hi]


isSorted(Comparable[] a, int lo,
i <= hi; i++)
a[i-1])) return false;

private static boolean isSorted(Object[] a, Comparator


comparator) {
return isSorted(a, 0, a.length - 1, comparator);
}

// is the array sorted from a[lo] to a[hi]


private static boolean isSorted(Object[] a, int lo, int
hi, Comparator comparator) {
for (int i = lo + 1; i <= hi; i++)
if (less(a[i], a[i-1], comparator)) return
false;
return true;
}
// print array to standard output
private static void show(Comparable[] a) {
for (int i = 0; i < a.length; i++) {
StdOut.println(a[i]);
}
}
/**
* Reads in a sequence of strings from standard input;
insertion sorts them;
* and prints them to standard output in ascending
order.
*/
public static void main(String[] args) {
String[] a = StdIn.readAllStrings();
Insertion.sort(a);
show(a);
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Tue Jul 28 13:10:02 EDT 2015.

InsertionX.java
Below is the syntax highlighted version
of InsertionX.java from 2.1 Elementary Sorts.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac InsertionX.java
* Execution:
java InsertionX < input.txt
* Dependencies: StdOut.java StdIn.java
* Data files:
http://algs4.cs.princeton.edu/21sort/tiny.txt
*
http://algs4.cs.princeton.edu/21sort/words3.txt
*
* Sorts a sequence of strings from standard input using
an optimized
* version of insertion sort.
*
* % more tiny.txt
* S O R T E X A M P L E

*
* % java InsertionX <
* A E E L M O P R S T
line ]
*
* % more words3.txt
* bed bug dad yes zoo
*
* % java InsertionX <
* all bad bed bug dad
line ]
*

tiny.txt
X

[ one string per

... all bad yet


words3.txt
... yes yet zoo

[ one string per

***********************************************************
**************/
/**
* The <tt>InsertionX</tt> class provides static methods
for sorting an
* array using an optimized version of insertion sort
(with half exchanges
* and a sentinel).
* <p>
* For additional documentation, see <a
href="http://algs4.cs.princeton.edu/21elementary">Section
2.1</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class InsertionX {
// This class should not be instantiated.
private InsertionX() { }
/**
* Rearranges the array in ascending order, using the
natural order.
* @param a the array to be sorted
*/
public static void sort(Comparable[] a) {
int N = a.length;
// put smallest element in position to serve as
sentinel

for (int i = N-1; i > 0; i--)


if (less(a[i], a[i-1])) exch(a, i, i-1);
// insertion sort with half-exchanges
for (int i = 2; i < N; i++) {
Comparable v = a[i];
int j = i;
while (less(v, a[j-1])) {
a[j] = a[j-1];
j--;
}
a[j] = v;
}
assert isSorted(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];
a[i] = a[j];
a[j] = swap;
}

/**********************************************************
*************
* Check if array is sorted - useful for debugging.
***********************************************************
************/
private static boolean isSorted(Comparable[] a) {

for (int i = 1; i < a.length; i++)


if (less(a[i], a[i-1])) return false;
return true;
}
// print array to standard output
private static void show(Comparable[] a) {
for (int i = 0; i < a.length; i++) {
StdOut.println(a[i]);
}
}
/**
* Reads in a sequence of strings from standard input;
insertion sorts them;
* and prints them to standard output in ascending
order.
*/
public static void main(String[] args) {
String[] a = StdIn.readAllStrings();
InsertionX.sort(a);
show(a);
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Tue Jul 28 13:10:02 EDT 2015.

Selection.java
Below is the syntax highlighted version
of Selection.java from 2.1 Elementary Sorts.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac Selection.java
* Execution:
java Selection < input.txt
* Dependencies: StdOut.java StdIn.java
* Data files:
http://algs4.cs.princeton.edu/21sort/tiny.txt
*
http://algs4.cs.princeton.edu/21sort/words3.txt
*
* Sorts a sequence of strings from standard input using
selection sort.
*
* % more tiny.txt

* S O R T E X A M P L E
*
* % java Selection < tiny.txt
* A E E L M O P R S T X
line ]
*
* % more words3.txt
* bed bug dad yes zoo ... all bad yet
*
* % java Selection < words3.txt
* all bad bed bug dad ... yes yet zoo
line ]
*

[ one string per

[ one string per

***********************************************************
**************/
import java.util.Comparator;
/**
* The <tt>Selection</tt> class provides static methods
for sorting an
* array using selection sort.
* <p>
* For additional documentation, see <a
href="http://algs4.cs.princeton.edu/21elementary">Section
2.1</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class Selection {
// This class should not be instantiated.
private Selection() { }
/**
* Rearranges the array in ascending order, using the
natural order.
* @param a the array to be sorted
*/
public static void sort(Comparable[] a) {
int N = a.length;
for (int i = 0; i < N; i++) {
int min = i;

for (int j = i+1; j < N; j++) {


if (less(a[j], a[min])) min = j;
}
exch(a, i, min);
assert isSorted(a, 0, i);
}
assert isSorted(a);
}
/**
* Rearranges the array in ascending order, using a
comparator.
* @param a the array
* @param c the comparator specifying the order
*/
public static void sort(Object[] a, Comparator c) {
int N = a.length;
for (int i = 0; i < N; i++) {
int min = i;
for (int j = i+1; j < N; j++) {
if (less(c, a[j], a[min])) min = j;
}
exch(a, i, min);
assert isSorted(a, c, 0, i);
}
assert isSorted(a, c);
}

/**********************************************************
*************
* Helper sorting functions.
***********************************************************
************/
// is v < w ?
private static boolean less(Comparable v, Comparable w)
{
return (v.compareTo(w) < 0);
}
// is v < w ?
private static boolean less(Comparator c, Object v,
Object w) {
return (c.compare(v, w) < 0);
}

// exchange a[i] and a[j]


private static void exch(Object[] a, int i, int j) {
Object swap = a[i];
a[i] = a[j];
a[j] = swap;
}

/**********************************************************
*************
* Check if array is sorted - useful for debugging.
***********************************************************
************/
// is the array a[] sorted?
private static boolean isSorted(Comparable[] a) {
return isSorted(a, 0, a.length - 1);
}
// is the array sorted from a[lo] to a[hi]
private static boolean isSorted(Comparable[] a, int lo,
int hi) {
for (int i = lo + 1; i <= hi; i++)
if (less(a[i], a[i-1])) return false;
return true;
}
// is the array a[] sorted?
private static boolean isSorted(Object[] a, Comparator
c) {
return isSorted(a, c, 0, a.length - 1);
}
// is the array sorted from a[lo] to a[hi]
private static boolean isSorted(Object[] a, Comparator
c, int lo, int hi) {
for (int i = lo + 1; i <= hi; i++)
if (less(c, a[i], a[i-1])) return false;
return true;
}

// print array to standard output

private static void show(Comparable[] a) {


for (int i = 0; i < a.length; i++) {
StdOut.println(a[i]);
}
}
/**
* Reads in a sequence of strings from standard input;
selection sorts them;
* and prints them to standard output in ascending
order.
*/
public static void main(String[] args) {
String[] a = StdIn.readAllStrings();
Selection.sort(a);
show(a);
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Tue Jul 28 13:02:59 EDT 2015.

Shell.java
Below is the syntax highlighted version
of Shell.java from 2.1 Elementary Sorts.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac Shell.java
* Execution:
java Shell < input.txt
* Dependencies: StdOut.java StdIn.java
* Data files:
http://algs4.cs.princeton.edu/21sort/tiny.txt
*
http://algs4.cs.princeton.edu/21sort/words3.txt
*
* Sorts a sequence of strings from standard input using
shellsort.
*
* Uses increment sequence proposed by Sedgewick and
Incerpi.
* The nth element of the sequence is the smallest integer
>= 2.5^n
* that is relatively prime to all previous terms in the
sequence.

* For example, incs[4] is 41 because 2.5^4 = 39.0625 and


41 is
* the next integer that is relatively prime to 3, 7, and
16.
*
* % more tiny.txt
* S O R T E X A M P L E
*
* % java Shell < 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 Shell < words3.txt
* all bad bed bug dad ... yes yet zoo
[ one string per
line ]
*
*
***********************************************************
**************/
/**
* The <tt>Shell</tt> class provides static methods for
sorting an
* array using Shellsort with Knuth's increment sequence
(1, 4, 13, 40, ...).
* <p>
* For additional documentation, see <a
href="http://algs4.cs.princeton.edu/21elementary">Section
2.1</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class Shell {
// This class should not be instantiated.
private Shell() { }
/**
* Rearranges the array in ascending order, using the
natural order.

* @param a the array to be sorted


*/
public static void sort(Comparable[] a) {
int N = a.length;
// 3x+1 increment sequence: 1, 4, 13, 40, 121,
364, 1093, ...
int h = 1;
while (h < N/3) h = 3*h + 1;
while (h >= 1) {
// h-sort the array
for (int i = h; i < N; i++) {
for (int j = i; j >= h && less(a[j], a[jh]); j -= h) {
exch(a, j, j-h);
}
}
assert isHsorted(a, h);
h /= 3;
}
assert isSorted(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];
a[i] = a[j];
a[j] = swap;
}

/**********************************************************
*************
* Check if array is sorted - useful for debugging.
***********************************************************
************/
private static boolean isSorted(Comparable[] a) {
for (int i = 1; i < a.length; i++)
if (less(a[i], a[i-1])) return false;
return true;
}
// is the array h-sorted?
private static boolean isHsorted(Comparable[] a, int h)
{
for (int i = h; i < a.length; i++)
if (less(a[i], a[i-h])) return false;
return true;
}
// print array to standard output
private static void show(Comparable[] a) {
for (int i = 0; i < a.length; i++) {
StdOut.println(a[i]);
}
}
/**
* Reads in a sequence of strings from standard input;
Shellsorts them;
* and prints them to standard output in ascending
order.
*/
public static void main(String[] args) {
String[] a = StdIn.readAllStrings();
Shell.sort(a);
show(a);
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Tue Jul 28 13:10:02 EDT 2015.

Merge.java
Below is the syntax highlighted version
of Merge.java from 2.2 Mergesort.
Here is the Javadoc.

/
***********************************************************
**************
* Compilation: javac Merge.java
* Execution:
java Merge < input.txt
* Dependencies: StdOut.java StdIn.java
* Data files:
http://algs4.cs.princeton.edu/22mergesort/tiny.txt
*
http://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
line ]
*
* % more words3.txt
* bed bug dad yes zoo ... all bad yet
*
* % java Merge < words3.txt
* all bad bed bug dad ... yes yet zoo
line ]
*

[ one string per

[ one string per

***********************************************************
**************/
/**
* The <tt>Merge</tt> class provides static methods for
sorting an
* array using mergesort.
* <p>
* For additional documentation, see <a
href="http://algs4.cs.princeton.edu/22mergesort">Section
2.2</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
* For an optimized version, see {@link MergeX}.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class Merge {
// This class should not be instantiated.
private Merge() { }
// stably merge a[lo .. mid] with a[mid+1 ..hi] using
aux[lo .. hi]
private static void merge(Comparable[] a, Comparable[]
aux, int lo, int mid, int hi) {
// precondition: a[lo .. mid] and a[mid+1 .. hi]
are sorted subarrays
assert isSorted(a, lo, mid);
assert isSorted(a, mid+1, hi);
// copy to aux[]
for (int k = lo; k <= hi; 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)
// this copying is unnecessary
else if (j > hi)
else if (less(aux[j], aux[i]))
else
}

a[k] = aux[j++];
a[k] = aux[i++];
a[k] = aux[j++];
a[k] = aux[i++];

// postcondition: a[lo .. hi] is sorted


assert isSorted(a, lo, hi);
}
// mergesort a[lo..hi] using auxiliary array
aux[lo..hi]
private static void sort(Comparable[] a, Comparable[]
aux, int lo, int hi) {
if (hi <= lo) return;
int mid = lo + (hi - lo) / 2;
sort(a, aux, lo, mid);
sort(a, aux, mid + 1, hi);
merge(a, aux, lo, mid, hi);
}
/**
* Rearranges the array in ascending order, using the
natural order.
* @param a the array to be sorted
*/
public static void sort(Comparable[] a) {
Comparable[] aux = new Comparable[a.length];
sort(a, aux, 0, a.length-1);
assert isSorted(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];
a[i] = a[j];
a[j] = swap;
}

/**********************************************************
*************
* Check if array is sorted - useful for debugging.
***********************************************************
************/
private static boolean isSorted(Comparable[] a) {
return isSorted(a, 0, a.length - 1);
}
private static boolean isSorted(Comparable[] a, int lo,
int hi) {
for (int i = lo + 1; i <= hi; i++)
if (less(a[i], a[i-1])) return false;
return true;
}

/**********************************************************
*************
* Index mergesort.
***********************************************************
************/
// stably merge a[lo .. mid] with a[mid+1 .. hi] using
aux[lo .. hi]
private static void merge(Comparable[] a, int[] index,
int[] aux, int lo, int mid, int hi) {
// copy to aux[]
for (int k = lo; k <= hi; k++) {
aux[k] = index[k];
}

// merge back to a[]


int i = lo, j = mid+1;
for (int k = lo; k <= hi; k++) {
if
(i > mid)
aux[j++];
else if (j > hi)
aux[i++];
else if (less(a[aux[j]], a[aux[i]]))
aux[j++];
else
aux[i++];
}
}

index[k] =
index[k] =
index[k] =
index[k] =

/**
* Returns a permutation that gives the elements in the
array in ascending order.
* @param a the array
* @return a permutation <tt>p[]</tt> such that
<tt>a[p[0]]</tt>, <tt>a[p[1]]</tt>,
*
..., <tt>a[p[N-1]]</tt> are in ascending order
*/
public static int[] indexSort(Comparable[] a) {
int N = a.length;
int[] index = new int[N];
for (int i = 0; i < N; i++)
index[i] = i;
int[] aux = new int[N];
sort(a, index, aux, 0, N-1);
return index;
}
// mergesort a[lo..hi] using auxiliary array
aux[lo..hi]
private static void sort(Comparable[] a, int[] index,
int[] aux, int lo, int hi) {
if (hi <= lo) return;
int mid = lo + (hi - lo) / 2;
sort(a, index, aux, lo, mid);
sort(a, index, aux, mid + 1, hi);
merge(a, index, aux, lo, mid, hi);
}
// print array to standard output
private static void show(Comparable[] a) {

for (int i = 0; i < a.length; i++) {


StdOut.println(a[i]);
}
}
/**
* Reads in a sequence of strings from standard input;
mergesorts them;
* and prints them to standard output in ascending
order.
*/
public static void main(String[] args) {
String[] a = StdIn.readAllStrings();
Merge.sort(a);
show(a);
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Tue Jul 28 13:28:50 EDT 2015.

MergeBU.java
Below is the syntax highlighted version
of MergeBU.java from 2.2 Mergesort.
Here is the Javadoc.

/
***********************************************************
**************
* Compilation: javac MergeBU.java
* Execution:
java MergeBU < input.txt
* Dependencies: StdOut.java StdIn.java
* Data files:
http://algs4.cs.princeton.edu/22mergesort/tiny.txt
*
http://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
line ]
*

[ one string per

***********************************************************
**************/
/**
* The <tt>MergeBU</tt> class provides static methods for
sorting an
* array using bottom-up mergesort.
* <p>
* For additional documentation, see <a
href="http://algs4.cs.princeton.edu/21elementary">Section
2.1</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class MergeBU {
// This class should not be instantiated.
private MergeBU() { }
// stably merge a[lo..mid] with a[mid+1..hi] using
aux[lo..hi]
private static void merge(Comparable[] a, Comparable[]
aux, int lo, int mid, int hi) {
// copy to aux[]
for (int k = lo; k <= hi; 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)
// this copying is unneccessary
else if (j > hi)
else if (less(aux[j], aux[i]))
else

a[k] = aux[j++];
a[k] = aux[i++];
a[k] = aux[j++];
a[k] = aux[i++];

}
}
/**
* Rearranges the array in ascending order, using the
natural order.
* @param a the array to be sorted
*/
public static void sort(Comparable[] a) {
int N = a.length;
Comparable[] aux = new Comparable[N];
for (int n = 1; n < N; n = n+n) {
for (int i = 0; i < N-n; i += n+n) {
int lo = i;
int m = i+n-1;
int hi = Math.min(i+n+n-1, N-1);
merge(a, aux, lo, m, hi);
}
}
assert isSorted(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];
a[i] = a[j];
a[j] = swap;
}

/**********************************************************
*************

Check if array is sorted - useful for debugging.

***********************************************************
************/
private static boolean isSorted(Comparable[] a) {
for (int i = 1; i < a.length; i++)
if (less(a[i], a[i-1])) return false;
return true;
}
// print array to standard output
private static void show(Comparable[] a) {
for (int i = 0; i < a.length; i++) {
StdOut.println(a[i]);
}
}
/**
* Reads in a sequence of strings from standard input;
bottom-up
* mergesorts them; and prints them to standard output
in ascending order.
*/
public static void main(String[] args) {
String[] a = StdIn.readAllStrings();
MergeBU.sort(a);
show(a);
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Tue Jul 28 13:28:50 EDT 2015.

MergeX.java
Below is the syntax highlighted version
of MergeX.java from 2.2 Mergesort.
Here is the Javadoc.

/
***********************************************************
**************
* Compilation: javac MergeX.java
* Execution:
java MergeX < input.txt
* Dependencies: StdOut.java StdIn.java
* Data files:
http://algs4.cs.princeton.edu/22mergesort/tiny.txt
*
http://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


line ]
*

[ one string per

***********************************************************
**************/
import java.util.Comparator;
/**
* The <tt>MergeX</tt> class provides static methods for
sorting an
* array using an optimized version of mergesort.
* <p>
* For additional documentation, see <a
href="http://algs4.cs.princeton.edu/22mergesort">Section
2.2</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class MergeX {
private static final int CUTOFF = 7; // cutoff to
insertion sort
// This class should not be instantiated.
private MergeX() { }
private static void merge(Comparable[] src, Comparable[]
dst, int lo, int mid, int hi) {
// precondition: src[lo .. mid] and src[mid+1 ..
hi] are sorted subarrays
assert isSorted(src, lo, mid);
assert isSorted(src, mid+1, hi);
int i = lo, j = mid+1;
for (int k = lo; k <= hi; k++) {
if
(i > mid)

dst[k] = src[j+

+];
else if (j > hi)

dst[k] = src[i+

+];
+];

else if (less(src[j], src[i])) dst[k] = src[j+


// to ensure stability

else

dst[k] = src[i+

+];
}
// postcondition: dst[lo .. hi] is sorted subarray
assert isSorted(dst, lo, hi);
}
private static void sort(Comparable[] src, Comparable[]
dst, int lo, int hi) {
// if (hi <= lo) return;
if (hi <= lo + CUTOFF) {
insertionSort(dst, lo, hi);
return;
}
int mid = lo + (hi - lo) / 2;
sort(dst, src, lo, mid);
sort(dst, src, mid+1, hi);
// if (!less(src[mid+1], src[mid])) {
//
for (int i = lo; i <= hi; i++) dst[i] =
src[i];
//
// }

return;

// using System.arraycopy() is a bit faster than


the above loop
if (!less(src[mid+1], src[mid])) {
System.arraycopy(src, lo, dst, lo, hi - lo + 1);
return;
}
merge(src, dst, lo, mid, hi);
}
/**
* Rearranges the array in ascending order, using the
natural order.
* @param a the array to be sorted
*/
public static void sort(Comparable[] a) {
Comparable[] aux = a.clone();
sort(aux, a, 0, a.length-1);
assert isSorted(a);
}
// sort from a[lo] to a[hi] using insertion sort

private static void insertionSort(Comparable[] a, int


lo, int hi) {
for (int i = lo; i <= hi; i++)
for (int j = i; j > lo && less(a[j], a[j-1]);
j--)
exch(a, j, j-1);
}

/**********************************************************
*********
* Utility methods.
***********************************************************
********/
// exchange a[i] and a[j]
private static void exch(Object[] a, int i, int j) {
Object swap = a[i];
a[i] = a[j];
a[j] = swap;
}
// is a[i] < a[j]?
private static boolean less(Comparable a, Comparable b)
{
return (a.compareTo(b) < 0);
}
// is a[i] < a[j]?
private static boolean less(Object a, Object b,
Comparator comparator) {
return (comparator.compare(a, b) < 0);
}

/**********************************************************
*********
* Version that takes Comparator as argument.
***********************************************************
********/
/**
* Rearranges the array in ascending order, using the
provided order.

* @param a the array to be sorted


*/
public static void sort(Object[] a, Comparator
comparator) {
Object[] aux = a.clone();
sort(aux, a, 0, a.length-1, comparator);
assert isSorted(a, comparator);
}
private static void merge(Object[] src, Object[] dst,
int lo, int mid, int hi, Comparator comparator) {
// precondition: src[lo .. mid] and src[mid+1 ..
hi] are sorted subarrays
assert isSorted(src, lo, mid, comparator);
assert isSorted(src, mid+1, hi, comparator);

dst[k]
dst[k]
dst[k]
dst[k]

int i = lo, j = mid+1;


for (int k = lo; k <= hi; k++) {
if
(i > mid)
= src[j++];
else if (j > hi)
= src[i++];
else if (less(src[j], src[i], comparator))
= src[j++];
else
= src[i++];
}
// postcondition: dst[lo .. hi] is sorted subarray
assert isSorted(dst, lo, hi, comparator);

}
private static void sort(Object[] src, Object[] dst, int
lo, int hi, Comparator comparator) {
// if (hi <= lo) return;
if (hi <= lo + CUTOFF) {
insertionSort(dst, lo, hi, comparator);
return;
}
int mid = lo + (hi - lo) / 2;
sort(dst, src, lo, mid, comparator);
sort(dst, src, mid+1, hi, comparator);
// using System.arraycopy() is a bit faster than
the above loop

if (!less(src[mid+1], src[mid], comparator)) {


System.arraycopy(src, lo, dst, lo, hi - lo + 1);
return;
}
merge(src, dst, lo, mid, hi, comparator);
}
// sort from a[lo] to a[hi] using insertion sort
private static void insertionSort(Object[] a, int lo,
int hi, Comparator comparator) {
for (int i = lo; i <= hi; i++)
for (int j = i; j > lo && less(a[j], a[j-1],
comparator); j--)
exch(a, j, j-1);
}

/**********************************************************
*************
* Check if array is sorted - useful for debugging.
***********************************************************
************/
private static boolean isSorted(Comparable[] a) {
return isSorted(a, 0, a.length - 1);
}
private static boolean isSorted(Comparable[] a, int lo,
int hi) {
for (int i = lo + 1; i <= hi; i++)
if (less(a[i], a[i-1])) return false;
return true;
}
private static boolean isSorted(Object[] a, Comparator
comparator) {
return isSorted(a, 0, a.length - 1, comparator);
}
private static boolean isSorted(Object[] a, int lo, int
hi, Comparator comparator) {
for (int i = lo + 1; i <= hi; i++)
if (less(a[i], a[i-1], comparator)) return
false;
return true;

}
// print array to standard output
private static void show(Object[] a) {
for (int i = 0; i < a.length; i++) {
StdOut.println(a[i]);
}
}
/**
* 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.
*/
public static void main(String[] args) {
String[] a = StdIn.readAllStrings();
MergeX.sort(a);
show(a);
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Tue Jul 28 13:28:50 EDT 2015.

Quick.java
Below is the syntax highlighted version
of Quick.java from 2.3 Quicksort.
Here is the Javadoc.

/
***********************************************************
**************
* Compilation: javac Quick.java
* Execution:
java Quick < input.txt
* Dependencies: StdOut.java StdIn.java
* Data files:
http://algs4.cs.princeton.edu/23quicksort/tiny.txt
*
http://algs4.cs.princeton.edu/23quicksort/words3.txt
*
* Sorts a sequence of strings from standard input using
quicksort.
*
* % more tiny.txt
* S O R T E X A M P L E
*
* % java Quick < 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 Quick < words3.txt


* all bad bed bug dad ... yes yet zoo
[ one string per
line ]
*
*
* Remark: For a type-safe version that uses static
generics, see
*
*
http://algs4.cs.princeton.edu/23quicksort/QuickPedantic.java
*
***********************************************************
**************/
/**
* The <tt>Quick</tt> class provides static methods for
sorting an
* array and selecting the ith smallest element in an
array using quicksort.
* <p>
* For additional documentation, see <a
href="http://algs4.cs.princeton.edu/21elementary">Section
2.1</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class Quick {
// This class should not be instantiated.
private Quick() { }
/**
* Rearranges the array in ascending order, using the
natural order.
* @param a the array to be sorted
*/
public static void sort(Comparable[] a) {
StdRandom.shuffle(a);
sort(a, 0, a.length - 1);
assert isSorted(a);
}
// quicksort the subarray from a[lo] to a[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);
sort(a, j+1, hi);
assert isSorted(a, lo, hi);
}
// partition the subarray a[lo..hi] so that a[lo..j-1]
<= a[j] <= a[j+1..hi]
// and return the index j.
private static int partition(Comparable[] a, int lo, int
hi) {
int i = lo;
int j = hi + 1;
Comparable v = a[lo];
while (true) {
// find item on lo to swap
while (less(a[++i], v))
if (i == hi) break;
// find item on hi to swap
while (less(v, a[--j]))
if (j == lo) break;
a[lo] acts as sentinel

// redundant since

// check if pointers cross


if (i >= j) break;
exch(a, i, j);
}
// put partitioning item v at a[j]
exch(a, lo, j);
// now, a[lo .. j-1] <= a[j] <= a[j+1 .. hi]
return j;
}
/**
* Rearranges the array so that a[k] contains the kth
smallest key;
* a[0] through a[k-1] are less than (or equal to)
a[k]; and

* a[k+1] through a[N-1] are greater than (or equal to)


a[k].
* @param a the array
* @param k find the kth smallest
*/
public static Comparable select(Comparable[] a, int k) {
if (k < 0 || k >= a.length) {
throw new IndexOutOfBoundsException("Selected
element out of bounds");
}
StdRandom.shuffle(a);
int lo = 0, hi = a.length - 1;
while (hi > lo) {
int i = partition(a, lo, hi);
if
(i > k) hi = i - 1;
else if (i < k) lo = i + 1;
else return a[i];
}
return a[lo];
}

/**********************************************************
*************
* 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];
a[i] = a[j];
a[j] = swap;
}

/**********************************************************
*************

Check if array is sorted - useful for debugging.

***********************************************************
************/
private static boolean isSorted(Comparable[] a) {
return isSorted(a, 0, a.length - 1);
}
private static boolean isSorted(Comparable[] a, int lo,
int hi) {
for (int i = lo + 1; i <= hi; i++)
if (less(a[i], a[i-1])) return false;
return true;
}
// print array to standard output
private static void show(Comparable[] a) {
for (int i = 0; i < a.length; i++) {
StdOut.println(a[i]);
}
}
/**
* 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.
*/
public static void main(String[] args) {
String[] a = StdIn.readAllStrings();
Quick.sort(a);
show(a);
// shuffle
StdRandom.shuffle(a);
// display results again using select
StdOut.println();
for (int i = 0; i < a.length; i++) {
String ith = (String) Quick.select(a, i);
StdOut.println(ith);
}

}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Tue Jul 28 13:28:50 EDT 2015.

Quick3way.java
Below is the syntax highlighted version
of Quick3way.java from 2.3 Quicksort.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac Quick3way.java
* Execution:
java Quick3way < input.txt
* Dependencies: StdOut.java StdIn.java
* Data files:
http://algs4.cs.princeton.edu/23quicksort/tiny.txt
*
http://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
line ]
*

[ one string per

***********************************************************
**************/
/**
* The <tt>Quick3way</tt> class provides static methods
for sorting an
* array using quicksort with 3-way partitioning.
* <p>
* For additional documentation, see <a
href="http://algs4.cs.princeton.edu/21elementary">Section
2.1</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class Quick3way {
// This class should not be instantiated.
private Quick3way() { }
/**
* Rearranges the array in ascending order, using the
natural order.
* @param a the array to be sorted
*/
public static void sort(Comparable[] a) {
StdRandom.shuffle(a);
sort(a, 0, a.length - 1);
assert isSorted(a);
}
// quicksort the subarray a[lo .. hi] using 3-way
partitioning
private static void sort(Comparable[] a, int lo, int hi)
{
if (hi <= lo) return;
int lt = lo, gt = hi;

Comparable v = a[lo];
int i = lo;
while (i <= gt) {
int cmp = a[i].compareTo(v);
if
(cmp < 0) exch(a, lt++, i++);
else if (cmp > 0) exch(a, i, gt--);
else
i++;
}
// 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);
}

/**********************************************************
*************
* Helper sorting functions.
***********************************************************
************/
// is v < w ?
private static boolean less(Comparable v, Comparable w)
{
return (v.compareTo(w) < 0);
}
// does v == w ?
private static boolean eq(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];
a[i] = a[j];
a[j] = swap;
}

/**********************************************************
*************
* Check if array is sorted - useful for debugging.

***********************************************************
************/
private static boolean isSorted(Comparable[] a) {
return isSorted(a, 0, a.length - 1);
}
private static boolean isSorted(Comparable[] a, int lo,
int hi) {
for (int i = lo + 1; i <= hi; i++)
if (less(a[i], a[i-1])) return false;
return true;
}

// print array to standard output


private static void show(Comparable[] a) {
for (int i = 0; i < a.length; i++) {
StdOut.println(a[i]);
}
}
/**
* Reads in a sequence of strings from standard input;
3-way
* quicksorts them; and prints them to standard output
in ascending order.
*/
public static void main(String[] args) {
String[] a = StdIn.readAllStrings();
Quick3way.sort(a);
show(a);
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Tue Jul 28 13:28:50 EDT 2015.

QuickX.java
Below is the syntax highlighted version
of QuickX.java from 2.3 Quicksort.
Here is the Javadoc.

/
***********************************************************
**************
* Compilation: javac QuickX.java
* Execution:
java QuickX N
* Dependencies: StdOut.java StdIn.java
*
* 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,
* Vol. 23 (11), 1249-1265 (November 1993).
*
***********************************************************
**************/
/**
* The <tt>QuickX</tt> class provides static methods for
sorting an

* array using an optimized version of quicksort (using


Bentley-McIlroy
* 3-way partitioning, Tukey's ninther, and cutoff to
insertion sort).
* <p>
* For additional documentation, see <a
href="http://algs4.cs.princeton.edu/21elementary">Section
2.1</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class QuickX {
private static final int CUTOFF = 8; // cutoff to
insertion sort, must be >= 1
// This class should not be instantiated.
private QuickX() { }
/**
* Rearranges the array in ascending order, using the
natural order.
* @param a the array to be sorted
*/
public static void sort(Comparable[] a) {
sort(a, 0, a.length - 1);
}
private static void sort(Comparable[] a, int lo, int hi)
{
int N = hi - lo + 1;
// cutoff to insertion sort
if (N <= CUTOFF) {
insertionSort(a, lo, hi);
return;
}
// use median-of-3 as partitioning element
else if (N <= 40) {
int m = median3(a, lo, lo + N/2, hi);
exch(a, m, lo);
}
// use Tukey ninther as partitioning element

else

{
int eps = N/8;
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 ninther = median3(a, m1, m2, m3);
exch(a, ninther, lo);
}
// Bentley-McIlroy 3-way partitioning
int i = lo, j = hi+1;
int p = lo, q = hi+1;
Comparable v = a[lo];
while (true) {
while (less(a[++i], v))
if (i == hi) break;
while (less(v, a[--j]))
if (j == lo) break;
// pointers cross
if (i == j && eq(a[i], v))
exch(a, ++p, i);
if (i >= j) break;
exch(a, i, j);
if (eq(a[i], v)) exch(a, ++p, i);
if (eq(a[j], v)) exch(a, --q, j);
}
i = j + 1;
for (int k = lo; k <= p; k++)
exch(a, k, j--);
for (int k = hi; k >= q; k--)
exch(a, k, i++);
sort(a, lo, j);
sort(a, i, hi);
}
// sort from a[lo] to a[hi] using insertion sort
private static void insertionSort(Comparable[] a, int
lo, int hi) {

for (int i = lo; i <= hi; i++)


for (int j = i; j > lo && less(a[j], a[j-1]);
j--)
exch(a, j, j-1);
}
// return the index of the median element among a[i],
a[j], and a[k]
private static int median3(Comparable[] a, int i, int j,
int k) {
return (less(a[i], a[j]) ?
(less(a[j], a[k]) ? j : less(a[i], a[k]) ? k
: i) :
(less(a[k], a[j]) ? j : less(a[k], a[i]) ? k
: i));
}
/**********************************************************
*************
* Helper sorting functions.
***********************************************************
************/
// is v < w ?
private static boolean less(Comparable v, Comparable w)
{
return (v.compareTo(w) < 0);
}
// does v == w ?
private static boolean eq(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];
a[i] = a[j];
a[j] = swap;
}

/**********************************************************
*************

Check if array is sorted - useful for debugging.

***********************************************************
************/
private static boolean isSorted(Comparable[] a) {
for (int i = 1; i < a.length; i++)
if (less(a[i], a[i-1])) return false;
return true;
}
// print array to standard output
private static void show(Comparable[] a) {
for (int i = 0; i < a.length; i++) {
StdOut.println(a[i]);
}
}
/**
* 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.
*/
public static void main(String[] args) {
String[] a = StdIn.readAllStrings();
QuickX.sort(a);
show(a);
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Tue Jul 28 13:28:50 EDT 2015.

TopM.java
Below is the syntax highlighted version
of TopM.java from 2.4 Priority Queues.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac TopM.java
* Execution:
java TopM M < input.txt
* Dependencies: MinPQ.java Transaction.java StdIn.java
StdOut.java
* Data files:
http://algs4.cs.princeton.edu/24pq/tinyBatch.txt
*
* Given an integer M from the command line and an input
stream where
* each line contains a String and a long value, this
MinPQ client
* prints the M lines whose numbers are the highest.
*
* % java TopM 5 < tinyBatch.txt
* Thompson
2/27/2000 4747.08
* vonNeumann 2/12/1994 4732.35
* vonNeumann 1/11/1999 4409.74
* Hoare
8/18/1992 4381.21
* vonNeumann 3/26/2002 4121.85
*

***********************************************************
**************/
/**
* The <tt>TopM</tt> class provides a client that reads a
sequence of
* transactions from standard input and prints the
<em>M</em> largest ones
* to standard output. This implementation uses a {@link
MinPQ} of size
* at most <em>M</em> + 1 to identify the <em>M</em>
largest transactions
* and a {@link Stack} to output them in the proper order.
* <p>
* For additional documentation, see <a
href="http://algs4.cs.princeton.edu/24pq">Section 2.4</a>
* of <i>Algorithms, 4th Edition</i> by Robert Sedgewick
and Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class TopM {
// This class should not be instantiated.
private TopM() { }
/**
* Reads a sequence of transactions from standard
input; takes a
* command-line integer M; prints to standard output
the M largest
* transactions in descending order.
*/
public static void main(String[] args) {
int M = Integer.parseInt(args[0]);
MinPQ<Transaction> pq = new MinPQ<Transaction>(M+1);
while (StdIn.hasNextLine()) {
// Create an entry from the next line and put
on the PQ.
String line = StdIn.readLine();
Transaction transaction = new Transaction(line);
pq.insert(transaction);
// remove minimum if M+1 entries on the PQ

if (pq.size() > M)
pq.delMin();
// top M entries are on the PQ

// print entries on PQ in reverse order


Stack<Transaction> stack = new Stack<Transaction>();
for (Transaction transaction : pq)
stack.push(transaction);
for (Transaction transaction : stack)
StdOut.println(transaction);
}
}

Copyright 20022010, Robert Sedgewick and Kevin Wayne.


Last updated: Wed Sep 25 07:06:16 EDT 2013.

MaxPQ.java
Below is the syntax highlighted version of MaxPQ.java from
Algorithms.
Here is the Javadoc.

/
***********************************************************
**************
* Compilation: javac MaxPQ.java
* Execution:
java MaxPQ < input.txt
* Dependencies: StdIn.java StdOut.java
*
* 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
* Q X P (6 left on pq)
*
* We use a one-based array to simplify parent and child
calculations.
*
* Can be optimized by replacing full exchanges with half
exchanges
* (ala insertion sort).
*
***********************************************************
**************/
import java.util.Comparator;

import java.util.Iterator;
import java.util.NoSuchElementException;
/**
* The <tt>MaxPQ</tt> class represents a priority queue of
generic keys.
* It supports the usual <em>insert</em> and <em>deletethe-maximum</em>
* operations, along with methods for peeking at the
maximum key,
* testing if the priority queue is empty, and iterating
through
* the keys.
* <p>
* This implementation uses a binary heap.
* The <em>insert</em> and <em>delete-the-maximum</em>
operations take
* logarithmic amortized time.
* The <em>max</em>, <em>size</em>, and <em>is-empty</em>
operations take constant time.
* Construction takes time proportional to the specified
capacity or the number of
* items used to initialize the data structure.
* <p>
* For additional documentation, see <a
href="http://algs4.cs.princeton.edu/24pq">Section 2.4</a>
of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class MaxPQ<Key> implements Iterable<Key> {
private Key[] pq;
// store items at
indices 1 to N
private int N;
// number of items
on priority queue
private Comparator<Key> comparator; // optional
Comparator
/**
* Initializes an empty priority queue with the given
initial capacity.
* @param initCapacity the initial capacity of the
priority queue

*/
public MaxPQ(int initCapacity) {
pq = (Key[]) new Object[initCapacity + 1];
N = 0;
}
/**
* Initializes an empty priority queue.
*/
public MaxPQ() {
this(1);
}
/**
* Initializes an empty priority queue with the given
initial capacity,
* using the given comparator.
* @param initCapacity the initial capacity of the
priority queue
* @param comparator the order in which to compare the
keys
*/
public MaxPQ(int initCapacity, Comparator<Key>
comparator) {
this.comparator = comparator;
pq = (Key[]) new Object[initCapacity + 1];
N = 0;
}
/**
* Initializes an empty priority queue using the given
comparator.
* @param comparator the order in which to compare the
keys
*/
public MaxPQ(Comparator<Key> comparator) {
this(1, comparator);
}
/**
* Initializes a priority queue from the array of keys.
* Takes time proportional to the number of keys, using
sink-based heap construction.
* @param keys the array of keys
*/
public MaxPQ(Key[] keys) {
N = keys.length;

pq = (Key[]) new Object[keys.length + 1];


for (int i = 0; i < N; i++)
pq[i+1] = keys[i];
for (int k = N/2; k >= 1; k--)
sink(k);
assert isMaxHeap();
}

/**
* Is the priority queue empty?
* @return true if the priority queue is empty; false
otherwise
*/
public boolean isEmpty() {
return N == 0;
}
/**
* Returns
* @return
*/
public int
return
}

the number of keys on the priority queue.


the number of keys on the priority queue
size() {
N;

/**
* Returns a largest key on the priority queue.
* @return a largest key on the priority queue
* @throws java.util.NoSuchElementException if the
priority queue is empty
*/
public Key max() {
if (isEmpty()) throw new
NoSuchElementException("Priority queue underflow");
return pq[1];
}
// helper function to double the size of the heap array
private void resize(int capacity) {
assert capacity > N;
Key[] temp = (Key[]) new Object[capacity];
for (int i = 1; i <= N; i++) {
temp[i] = pq[i];
}
pq = temp;

}
/**
* Adds a new key to the priority queue.
* @param x the new key to add to the priority queue
*/
public void insert(Key x) {
// double size of array if necessary
if (N >= pq.length - 1) resize(2 * pq.length);
// add x, and percolate it up to maintain heap
invariant
pq[++N] = x;
swim(N);
assert isMaxHeap();
}
/**
* Removes and returns a largest key on the priority
queue.
* @return a largest key on the priority queue
* @throws java.util.NoSuchElementException if priority
queue is empty.
*/
public Key delMax() {
if (isEmpty()) throw new
NoSuchElementException("Priority queue underflow");
Key max = pq[1];
exch(1, N--);
sink(1);
pq[N+1] = null;
// to avoid loiterig and help
with garbage collection
if ((N > 0) && (N == (pq.length - 1) / 4))
resize(pq.length / 2);
assert isMaxHeap();
return max;
}

/**********************************************************
*************
* Helper functions to restore the heap invariant.

***********************************************************
***********/
private void swim(int k) {
while (k > 1 && less(k/2, k)) {
exch(k, k/2);
k = k/2;
}
}
private void sink(int k) {
while (2*k <= N) {
int j = 2*k;
if (j < N && less(j, j+1)) j++;
if (!less(k, j)) break;
exch(k, j);
k = j;
}
}
/**********************************************************
*************
* Helper functions for compares and swaps.
***********************************************************
***********/
private boolean less(int i, int j) {
if (comparator == null) {
return ((Comparable<Key>)
pq[i]).compareTo(pq[j]) < 0;
}
else {
return comparator.compare(pq[i], pq[j]) < 0;
}
}
private void exch(int i, int j) {
Key swap = pq[i];
pq[i] = pq[j];
pq[j] = swap;
}
// is pq[1..N] a max heap?
private boolean isMaxHeap() {
return isMaxHeap(1);
}

// is subtree of pq[1..N] rooted at k a max heap?


private boolean isMaxHeap(int k) {
if (k > N) return true;
int left = 2*k, 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);
}

/**********************************************************
*************
* Iterator
***********************************************************
***********/
/**
* Returns an iterator that iterates over the keys on
the priority queue
* in descending order.
* The iterator doesn't implement <tt>remove()</tt>
since it's optional.
* @return an iterator that iterates over the keys in
descending order
*/
public Iterator<Key> iterator() { return new
HeapIterator(); }
private class HeapIterator implements Iterator<Key> {
// create a new pq
private MaxPQ<Key> copy;
// add all items to copy of heap
// takes linear time since already in heap order so
no keys move
public HeapIterator() {
if (comparator == null) copy = new
MaxPQ<Key>(size());
else
copy = new
MaxPQ<Key>(size(), comparator);
for (int i = 1; i <= N; i++)
copy.insert(pq[i]);
}

public boolean hasNext()

{ return !copy.isEmpty();

}
public void remove()
UnsupportedOperationException();

{ throw new
}

public Key next() {


if (!hasNext()) throw new
NoSuchElementException();
return copy.delMax();
}
}
/**
* Unit tests the <tt>MaxPQ</tt> data type.
*/
public static void main(String[] args) {
MaxPQ<String> pq = new MaxPQ<String>();
while (!StdIn.isEmpty()) {
String item = StdIn.readString();
if (!item.equals("-")) pq.insert(item);
else if (!pq.isEmpty()) StdOut.print(pq.delMax()
+ " ");
}
StdOut.println("(" + pq.size() + " left on pq)");
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Thu Jul 23 17:05:46 EDT 2015.

MinPQ.java
Below is the syntax highlighted version of MinPQ.java from
Algorithms.
Here is the Javadoc.

/
***********************************************************
**************
* Compilation: javac MinPQ.java
* Execution:
java MinPQ < input.txt
* Dependencies: StdIn.java StdOut.java
*
* Generic min priority queue implementation with a binary
heap.
* Can be used with a comparator instead of the natural
order.
*
* % java MinPQ < tinyPQ.txt
* E A E (6 left on pq)
*
* We use a one-based array to simplify parent and child
calculations.
*
* Can be optimized by replacing full exchanges with half
exchanges
* (ala insertion sort).
*
***********************************************************
**************/
import java.util.Comparator;

import java.util.Iterator;
import java.util.NoSuchElementException;
/**
* The <tt>MinPQ</tt> class represents a priority queue of
generic keys.
* It supports the usual <em>insert</em> and <em>deletethe-minimum</em>
* operations, along with methods for peeking at the
minimum key,
* testing if the priority queue is empty, and iterating
through
* the keys.
* <p>
* This implementation uses a binary heap.
* The <em>insert</em> and <em>delete-the-minimum</em>
operations take
* logarithmic amortized time.
* The <em>min</em>, <em>size</em>, and <em>is-empty</em>
operations take constant time.
* Construction takes time proportional to the specified
capacity or the number of
* items used to initialize the data structure.
* <p>
* For additional documentation, see <a
href="http://algs4.cs.princeton.edu/24pq">Section 2.4</a>
of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class MinPQ<Key> implements Iterable<Key> {
private Key[] pq;
// store items at
indices 1 to N
private int N;
// number of items
on priority queue
private Comparator<Key> comparator; // optional
comparator
/**
* Initializes an empty priority queue with the given
initial capacity.
* @param initCapacity the initial capacity of the
priority queue
*/

public MinPQ(int initCapacity) {


pq = (Key[]) new Object[initCapacity + 1];
N = 0;
}
/**
* Initializes an empty priority queue.
*/
public MinPQ() {
this(1);
}
/**
* Initializes an empty priority queue with the given
initial capacity,
* using the given comparator.
* @param initCapacity the initial capacity of the
priority queue
* @param comparator the order to use when comparing
keys
*/
public MinPQ(int initCapacity, Comparator<Key>
comparator) {
this.comparator = comparator;
pq = (Key[]) new Object[initCapacity + 1];
N = 0;
}
/**
* Initializes an empty priority queue using the given
comparator.
* @param comparator the order to use when comparing
keys
*/
public MinPQ(Comparator<Key> comparator) {
this(1, comparator);
}
/**
* Initializes a priority queue from the array of keys.
* Takes time proportional to the number of keys, using
sink-based heap construction.
* @param keys the array of keys
*/
public MinPQ(Key[] keys) {
N = keys.length;
pq = (Key[]) new Object[keys.length + 1];

for (int i = 0; i < N; i++)


pq[i+1] = keys[i];
for (int k = N/2; k >= 1; k--)
sink(k);
assert isMinHeap();
}
/**
* Is the priority queue empty?
* @return true if the priority queue is empty; false
otherwise
*/
public boolean isEmpty() {
return N == 0;
}
/**
* Returns
* @return
*/
public int
return
}

the number of keys on the priority queue.


the number of keys on the priority queue
size() {
N;

/**
* Returns a smallest key on the priority queue.
* @return a smallest key on the priority queue
* @throws java.util.NoSuchElementException if priority
queue is empty
*/
public Key min() {
if (isEmpty()) throw new
NoSuchElementException("Priority queue underflow");
return pq[1];
}
// helper function to double the size of the heap array
private void resize(int capacity) {
assert capacity > N;
Key[] temp = (Key[]) new Object[capacity];
for (int i = 1; i <= N; i++) {
temp[i] = pq[i];
}
pq = temp;
}
/**

* Adds a new key to the priority queue.


* @param x the key to add to the priority queue
*/
public void insert(Key x) {
// double size of array if necessary
if (N == pq.length - 1) resize(2 * pq.length);
// add x, and percolate it up to maintain heap
invariant
pq[++N] = x;
swim(N);
assert isMinHeap();
}
/**
* Removes and returns a smallest key on the priority
queue.
* @return a smallest key on the priority queue
* @throws java.util.NoSuchElementException if the
priority queue is empty
*/
public Key delMin() {
if (isEmpty()) throw new
NoSuchElementException("Priority queue underflow");
exch(1, N);
Key min = pq[N--];
sink(1);
pq[N+1] = null;
// avoid loitering and help
with garbage collection
if ((N > 0) && (N == (pq.length - 1) / 4))
resize(pq.length / 2);
assert isMinHeap();
return min;
}

/**********************************************************
*************
* Helper functions to restore the heap invariant.
***********************************************************
***********/
private void swim(int k) {
while (k > 1 && greater(k/2, k)) {
exch(k, k/2);

k = k/2;
}
}
private void sink(int k) {
while (2*k <= N) {
int j = 2*k;
if (j < N && greater(j, j+1)) j++;
if (!greater(k, j)) break;
exch(k, j);
k = j;
}
}
/**********************************************************
*************
* Helper functions for compares and swaps.
***********************************************************
***********/
private boolean greater(int i, int j) {
if (comparator == null) {
return ((Comparable<Key>)
pq[i]).compareTo(pq[j]) > 0;
}
else {
return comparator.compare(pq[i], pq[j]) > 0;
}
}
private void exch(int i, int j) {
Key swap = pq[i];
pq[i] = pq[j];
pq[j] = swap;
}
// is pq[1..N] a min heap?
private boolean isMinHeap() {
return isMinHeap(1);
}
// is subtree of pq[1..N] rooted at k a min heap?
private boolean isMinHeap(int k) {
if (k > N) return true;
int left = 2*k, 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);
}

/**********************************************************
*************
* Iterators
***********************************************************
***********/
/**
* Returns an iterator that iterates over the keys on
the priority queue
* in ascending order.
* The iterator doesn't implement <tt>remove()</tt>
since it's optional.
* @return an iterator that iterates over the keys in
ascending order
*/
public Iterator<Key> iterator() { return new
HeapIterator(); }
private class HeapIterator implements Iterator<Key> {
// create a new pq
private MinPQ<Key> copy;
// add all items to copy of heap
// takes linear time since already in heap order so
no keys move
public HeapIterator() {
if (comparator == null) copy = new
MinPQ<Key>(size());
else
copy = new
MinPQ<Key>(size(), comparator);
for (int i = 1; i <= N; i++)
copy.insert(pq[i]);
}
public boolean hasNext()

{ return !copy.isEmpty();

}
public void remove()
UnsupportedOperationException();
public Key next() {

{ throw new
}

if (!hasNext()) throw new


NoSuchElementException();
return copy.delMin();
}
}
/**
* Unit tests the <tt>MinPQ</tt> data type.
*/
public static void main(String[] args) {
MinPQ<String> pq = new MinPQ<String>();
while (!StdIn.isEmpty()) {
String item = StdIn.readString();
if (!item.equals("-")) pq.insert(item);
else if (!pq.isEmpty()) StdOut.print(pq.delMin()
+ " ");
}
StdOut.println("(" + pq.size() + " left on pq)");
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Fri Jul 24 09:57:21 EDT 2015.

IndexMinPQ.java
Below is the syntax highlighted version
of IndexMinPQ.java from Algorithms.
Here is the Javadoc.

/
***********************************************************
**************
* Compilation: javac IndexMinPQ.java
* Execution:
java IndexMinPQ
* Dependencies: StdOut.java
*
* Minimum-oriented indexed PQ implementation using a
binary heap.
*
***********************************************************
**********/
import java.util.Iterator;
import java.util.NoSuchElementException;
/**
* The <tt>IndexMinPQ</tt> class represents an indexed
priority queue of generic keys.
* It supports the usual <em>insert</em> and <em>deletethe-minimum</em>
* operations, along with <em>delete</em> and <em>changethe-key</em>
* methods. In order to let the client refer to keys on
the priority queue,

* an integer between 0 and maxN-1 is associated with each


key&mdash;the client
* uses this integer to specify which key to delete or
change.
* It also supports methods for peeking at the minimum
key,
* testing if the priority queue is empty, and iterating
through
* the keys.
* <p>
* This implementation uses a binary heap along with an
array to associate
* keys with integers in the given range.
* The <em>insert</em>, <em>delete-the-minimum</em>,
<em>delete</em>,
* <em>change-key</em>, <em>decrease-key</em>, and
<em>increase-key</em>
* operations take logarithmic time.
* The <em>is-empty</em>, <em>size</em>, <em>minindex</em>, <em>min-key</em>, and <em>key-of</em>
* operations take constant time.
* Construction takes time proportional to the specified
capacity.
* <p>
* For additional documentation, see <a
href="http://algs4.cs.princeton.edu/24pq">Section 2.4</a>
of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class IndexMinPQ<Key extends Comparable<Key>>
implements Iterable<Integer> {
private int maxN;
// maximum number of elements
on PQ
private int N;
// number of elements on PQ
private int[] pq;
// binary heap using 1-based
indexing
private int[] qp;
// inverse of pq - qp[pq[i]] =
pq[qp[i]] = i
private Key[] keys;
// keys[i] = priority of i
/**
* Initializes an empty indexed priority queue with
indices between 0 and maxN-1.

* @param maxN the keys on the priority queue are index


from 0 to maxN-1
* @throws java.lang.IllegalArgumentException if maxN <
0
*/
public IndexMinPQ(int maxN) {
if (maxN < 0) throw new IllegalArgumentException();
this.maxN = maxN;
keys = (Key[]) new Comparable[maxN + 1];
// make
this of length maxN??
pq
= new int[maxN + 1];
qp
= new int[maxN + 1];
// make
this of length maxN??
for (int i = 0; i <= maxN; i++)
qp[i] = -1;
}
/**
* Is the priority queue empty?
* @return true if the priority queue is empty; false
otherwise
*/
public boolean isEmpty() {
return N == 0;
}
/**
* Is i an index on the priority queue?
* @param i an index
* @throws java.lang.IndexOutOfBoundsException unless
(0 &le; i < maxN)
*/
public boolean contains(int i) {
if (i < 0 || i >= maxN) throw new
IndexOutOfBoundsException();
return qp[i] != -1;
}
/**
* Returns
* @return
*/
public int
return
}
/**

the number of keys on the priority queue.


the number of keys on the priority queue
size() {
N;

* Associates key with index i.


* @param i an index
* @param key the key to associate with index i
* @throws java.lang.IndexOutOfBoundsException unless 0
&le; i < maxN
* @throws java.util.IllegalArgumentException if there
already is an item associated with index i
*/
public void insert(int i, Key key) {
if (i < 0 || i >= maxN) throw new
IndexOutOfBoundsException();
if (contains(i)) throw new
IllegalArgumentException("index is already in the priority
queue");
N++;
qp[i] = N;
pq[N] = i;
keys[i] = key;
swim(N);
}
/**
* Returns an index associated with a minimum key.
* @return an index associated with a minimum key
* @throws java.util.NoSuchElementException if priority
queue is empty
*/
public int minIndex() {
if (N == 0) throw new
NoSuchElementException("Priority queue underflow");
return pq[1];
}
/**
* Returns a minimum key.
* @return a minimum key
* @throws java.util.NoSuchElementException if priority
queue is empty
*/
public Key minKey() {
if (N == 0) throw new
NoSuchElementException("Priority queue underflow");
return keys[pq[1]];
}
/**

* Removes a minimum key and returns its associated


index.
* @return an index associated with a minimum key
* @throws java.util.NoSuchElementException if priority
queue is empty
*/
public int delMin() {
if (N == 0) throw new
NoSuchElementException("Priority queue underflow");
int min = pq[1];
exch(1, N--);
sink(1);
qp[min] = -1;
// delete
keys[pq[N+1]] = null;
// to help with garbage
collection
pq[N+1] = -1;
// not needed
return min;
}
/**
* Returns the key associated with index i.
* @param i the index of the key to return
* @return the key associated with index i
* @throws java.lang.IndexOutOfBoundsException unless 0
&le; i < maxN
* @throws java.util.NoSuchElementException no key is
associated with index i
*/
public Key keyOf(int i) {
if (i < 0 || i >= maxN) throw new
IndexOutOfBoundsException();
if (!contains(i)) throw new
NoSuchElementException("index is not in the priority
queue");
else return keys[i];
}
/**
* Change the key associated with index i to the
specified value.
* @param i the index of the key to change
* @param key change the key assocated with index i to
this key
* @throws java.lang.IndexOutOfBoundsException unless 0
&le; i < maxN
* @deprecated Replaced by changeKey()
*/

@Deprecated public void change(int i, Key key) {


changeKey(i, key);
}
/**
* Change the key associated with index i to the
specified value.
* @param i the index of the key to change
* @param key change the key assocated with index i to
this key
* @throws java.lang.IndexOutOfBoundsException unless 0
&le; i < maxN
* @throws java.util.NoSuchElementException no key is
associated with index i
*/
public void changeKey(int i, Key key) {
if (i < 0 || i >= maxN) throw new
IndexOutOfBoundsException();
if (!contains(i)) throw new
NoSuchElementException("index is not in the priority
queue");
keys[i] = key;
swim(qp[i]);
sink(qp[i]);
}
/**
* Decrease the key associated with index i to the
specified value.
* @param i the index of the key to decrease
* @param key decrease the key assocated with index i
to this key
* @throws java.lang.IndexOutOfBoundsException unless 0
&le; i < maxN
* @throws java.lang.IllegalArgumentException if key
&ge; key associated with index i
* @throws java.util.NoSuchElementException no key is
associated with index i
*/
public void decreaseKey(int i, Key key) {
if (i < 0 || i >= maxN) throw new
IndexOutOfBoundsException();
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");
keys[i] = key;
swim(qp[i]);
}
/**
* Increase the key associated with index i to the
specified value.
* @param i the index of the key to increase
* @param key increase the key assocated with index i
to this key
* @throws java.lang.IndexOutOfBoundsException unless 0
&le; i < maxN
* @throws java.lang.IllegalArgumentException if key
&le; key associated with index i
* @throws java.util.NoSuchElementException no key is
associated with index i
*/
public void increaseKey(int i, Key key) {
if (i < 0 || i >= maxN) throw new
IndexOutOfBoundsException();
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");
keys[i] = key;
sink(qp[i]);
}
/**
* Remove the key associated with index i.
* @param i the index of the key to remove
* @throws java.lang.IndexOutOfBoundsException unless 0
&le; i < maxN
* @throws java.util.NoSuchElementException no key is
associated with index i
*/
public void delete(int i) {
if (i < 0 || i >= maxN) throw new
IndexOutOfBoundsException();

if (!contains(i)) throw new


NoSuchElementException("index is not in the priority
queue");
int index = qp[i];
exch(index, N--);
swim(index);
sink(index);
keys[i] = null;
qp[i] = -1;
}

/**********************************************************
****
* General helper functions.
***********************************************************
***/
private boolean greater(int i, int j) {
return keys[pq[i]].compareTo(keys[pq[j]]) > 0;
}
private void exch(int i, int j) {
int swap = pq[i];
pq[i] = pq[j];
pq[j] = swap;
qp[pq[i]] = i;
qp[pq[j]] = j;
}

/**********************************************************
****
* Heap helper functions.
***********************************************************
***/
private void swim(int k) {
while (k > 1 && greater(k/2, k)) {
exch(k, k/2);
k = k/2;
}
}
private void sink(int k) {
while (2*k <= N) {

int j = 2*k;
if (j < N && greater(j, j+1)) j++;
if (!greater(k, j)) break;
exch(k, j);
k = j;
}
}

/**********************************************************
*************
* Iterators.
***********************************************************
***********/
/**
* Returns an iterator that iterates over the keys on
the
* priority queue in ascending order.
* The iterator doesn't implement <tt>remove()</tt>
since it's optional.
* @return an iterator that iterates over the keys in
ascending order
*/
public Iterator<Integer> iterator() { return new
HeapIterator(); }
private class HeapIterator implements Iterator<Integer>
{
// create a new pq
private IndexMinPQ<Key> copy;
// add all elements to copy of heap
// takes linear time since already in heap order so
no keys move
public HeapIterator() {
copy = new IndexMinPQ<Key>(pq.length - 1);
for (int i = 1; i <= N; i++)
copy.insert(pq[i], keys[pq[i]]);
}
public boolean hasNext()

{ return !copy.isEmpty();

}
public void remove()
UnsupportedOperationException();

{ throw new
}

public Integer next() {


if (!hasNext()) throw new
NoSuchElementException();
return copy.delMin();
}
}
/**
* Unit tests the <tt>IndexMinPQ</tt> data type.
*/
public static void main(String[] args) {
// insert a bunch of strings
String[] strings = { "it", "was", "the", "best",
"of", "times", "it", "was", "the", "worst" };
IndexMinPQ<String> pq = new
IndexMinPQ<String>(strings.length);
for (int i = 0; i < strings.length; i++) {
pq.insert(i, strings[i]);
}
// delete and print each key
while (!pq.isEmpty()) {
int i = pq.delMin();
StdOut.println(i + " " + strings[i]);
}
StdOut.println();
// reinsert the same strings
for (int i = 0; i < strings.length; i++) {
pq.insert(i, strings[i]);
}
// print each key using the iterator
for (int i : pq) {
StdOut.println(i + " " + strings[i]);
}
while (!pq.isEmpty()) {
pq.delMin();
}
}
}

Copyright 20022010, Robert Sedgewick and Kevin Wayne.


Last updated: Tue Jul 28 10:06:44 EDT 2015.

IndexMaxPQ.java
Below is the syntax highlighted version
of IndexMaxPQ.java from Algorithms.
Here is the Javadoc.

/
***********************************************************
**************
* Compilation: javac IndexMaxPQ.java
* Execution:
java IndexMaxPQ
* Dependencies: StdOut.java
*
* Maximum-oriented indexed PQ implementation using a
binary heap.
*
***********************************************************
**********/
import java.util.Iterator;
import java.util.NoSuchElementException;
/**

* The <tt>IndexMaxPQ</tt> class represents an indexed


priority queue of generic keys.
* It supports the usual <em>insert</em> and <em>deletethe-maximum</em>
* operations, along with <em>delete</em> and <em>changethe-key</em>
* methods. In order to let the client refer to items on
the priority queue,
* an integer between 0 and maxN-1 is associated with each
key&mdash;the client
* uses this integer to specify which key to delete or
change.
* It also supports methods for peeking at a maximum key,
* testing if the priority queue is empty, and iterating
through
* the keys.
* <p>
* This implementation uses a binary heap along with an
array to associate
* keys with integers in the given range.
* The <em>insert</em>, <em>delete-the-maximum</em>,
<em>delete</em>,
* <em>change-key</em>, <em>decrease-key</em>, and
<em>increase-key</em>
* operations take logarithmic time.
* The <em>is-empty</em>, <em>size</em>, <em>maxindex</em>, <em>max-key</em>, and <em>key-of</em>
* operations take constant time.
* Construction takes time proportional to the specified
capacity.
* <p>
* For additional documentation, see <a
href="http://algs4.cs.princeton.edu/24pq">Section 2.4</a>
of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class IndexMaxPQ<Key extends Comparable<Key>>
implements Iterable<Integer> {
private int N;
// number of elements on PQ
private int[] pq;
// binary heap using 1-based
indexing
private int[] qp;
// inverse of pq - qp[pq[i]] =
pq[qp[i]] = i

private Key[] keys;

// keys[i] = priority of i

/**
* Initializes an empty indexed priority queue with
indices between 0 and maxN-1.
* @param maxN the keys on the priority queue are index
from 0 to maxN-1
* @throws java.lang.IllegalArgumentException if maxN <
0
*/
public IndexMaxPQ(int maxN) {
keys = (Key[]) new Comparable[maxN + 1];
// make
this of length maxN??
pq
= new int[maxN + 1];
qp
= new int[maxN + 1];
// make
this of length maxN??
for (int i = 0; i <= maxN; i++)
qp[i] = -1;
}
/**
* Is the priority queue empty?
* @return true if the priority queue is empty; false
otherwise
*/
public boolean isEmpty() { return N == 0; }
/**
* Is i an index on the priority queue?
* @param i an index
* @throws java.lang.IndexOutOfBoundsException unless
(0 &le; i < maxN)
*/
public boolean contains(int i) {
return qp[i] != -1;
}
/**
* Returns
* @return
*/
public int
return
}

the number of keys on the priority queue.


the number of keys on the priority queue
size() {
N;

/**
* Associate key with index i.

* @param i an index
* @param key the key to associate with index i
* @throws java.lang.IndexOutOfBoundsException unless 0
&le; i < maxN
* @throws java.util.IllegalArgumentException if there
already is an item associated with index i
*/
public void insert(int i, Key key) {
if (contains(i)) throw new
IllegalArgumentException("index is already in the priority
queue");
N++;
qp[i] = N;
pq[N] = i;
keys[i] = key;
swim(N);
}
/**
* Returns an index associated with a maximum key.
* @return an index associated with a maximum key
* @throws java.util.NoSuchElementException if priority
queue is empty
*/
public int maxIndex() {
if (N == 0) throw new
NoSuchElementException("Priority queue underflow");
return pq[1];
}
/**
* Return a maximum key.
* @return a maximum key
* @throws java.util.NoSuchElementException if priority
queue is empty
*/
public Key maxKey() {
if (N == 0) throw new
NoSuchElementException("Priority queue underflow");
return keys[pq[1]];
}
/**
* Removes a maximum key and returns its associated
index.
* @return an index associated with a maximum key

* @throws java.util.NoSuchElementException if priority


queue is empty
*/
public int delMax() {
if (N == 0) throw new
NoSuchElementException("Priority queue underflow");
int min = pq[1];
exch(1, N--);
sink(1);
qp[min] = -1;
// delete
keys[pq[N+1]] = null;
// to help with garbage
collection
pq[N+1] = -1;
// not needed
return min;
}
/**
* Returns the key associated with index i.
* @param i the index of the key to return
* @return the key associated with index i
* @throws java.lang.IndexOutOfBoundsException unless 0
&le; i < maxN
* @throws java.util.NoSuchElementException no key is
associated with index i
*/
public Key keyOf(int i) {
if (!contains(i)) throw new
NoSuchElementException("index is not in the priority
queue");
else return keys[i];
}
/**
* Change the key associated with index i to the
specified value.
* @param i the index of the key to change
* @param key change the key assocated with index i to
this key
* @throws java.lang.IndexOutOfBoundsException unless 0
&le; i < maxN
* @deprecated Replaced by changeKey()
*/
@Deprecated public void change(int i, Key key) {
changeKey(i, key);
}
/**

* Change the key associated with index i to the


specified value.
* @param i the index of the key to change
* @param key change the key assocated with index i to
this key
* @throws java.lang.IndexOutOfBoundsException unless 0
&le; i < maxN
*/
public void changeKey(int i, Key key) {
if (!contains(i)) throw new
NoSuchElementException("index is not in the priority
queue");
keys[i] = key;
swim(qp[i]);
sink(qp[i]);
}
/**
* Increase the key associated with index i to the
specified value.
* @param i the index of the key to increase
* @param key increase the key assocated with index i
to this key
* @throws java.lang.IndexOutOfBoundsException unless 0
&le; i < maxN
* @throws java.lang.IllegalArgumentException if key
&le; key associated with index i
* @throws java.util.NoSuchElementException no key is
associated with index i
*/
public void increaseKey(int i, Key key) {
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");
keys[i] = key;
swim(qp[i]);
}
/**
* Decrease the key associated with index i to the
specified value.

* @param i the index of the key to decrease


* @param key decrease the key assocated with index i
to this key
* @throws java.lang.IndexOutOfBoundsException unless 0
&le; i < maxN
* @throws java.lang.IllegalArgumentException if key
&ge; key associated with index i
* @throws java.util.NoSuchElementException no key is
associated with index i
*/
public void decreaseKey(int i, Key key) {
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");
keys[i] = key;
sink(qp[i]);
}
/**
* Remove the key associated with index i.
* @param i the index of the key to remove
* @throws java.lang.IndexOutOfBoundsException unless 0
&le; i < maxN
* @throws java.util.NoSuchElementException no key is
associated with index i
*/
public void delete(int i) {
if (!contains(i)) throw new
NoSuchElementException("index is not in the priority
queue");
int index = qp[i];
exch(index, N--);
swim(index);
sink(index);
keys[i] = null;
qp[i] = -1;
}

/**********************************************************
****

* General helper functions.


***********************************************************
***/
private boolean less(int i, int j) {
return keys[pq[i]].compareTo(keys[pq[j]]) < 0;
}
private void exch(int i, int j) {
int swap = pq[i];
pq[i] = pq[j];
pq[j] = swap;
qp[pq[i]] = i;
qp[pq[j]] = j;
}

/**********************************************************
****
* Heap helper functions.
***********************************************************
***/
private void swim(int k) {
while (k > 1 && less(k/2, k)) {
exch(k, k/2);
k = k/2;
}
}
private void sink(int k) {
while (2*k <= N) {
int j = 2*k;
if (j < N && less(j, j+1)) j++;
if (!less(k, j)) break;
exch(k, j);
k = j;
}
}

/**********************************************************
*************
* Iterators.

***********************************************************
***********/
/**
* Returns an iterator that iterates over the keys on
the
* priority queue in descending order.
* The iterator doesn't implement <tt>remove()</tt>
since it's optional.
* @return an iterator that iterates over the keys in
descending order
*/
public Iterator<Integer> iterator() { return new
HeapIterator(); }
private class HeapIterator implements Iterator<Integer>
{
// create a new pq
private IndexMaxPQ<Key> copy;
// add all elements to copy of heap
// takes linear time since already in heap order so
no keys move
public HeapIterator() {
copy = new IndexMaxPQ<Key>(pq.length - 1);
for (int i = 1; i <= N; i++)
copy.insert(pq[i], keys[pq[i]]);
}
public boolean hasNext()

{ return !copy.isEmpty();

}
public void remove()
UnsupportedOperationException();

{ throw new
}

public Integer next() {


if (!hasNext()) throw new
NoSuchElementException();
return copy.delMax();
}
}
/**
* Unit tests the <tt>IndexMaxPQ</tt> data type.
*/
public static void main(String[] args) {
// insert a bunch of strings

String[] strings = { "it", "was", "the", "best",


"of", "times", "it", "was", "the", "worst" };
IndexMaxPQ<String> pq = new
IndexMaxPQ<String>(strings.length);
for (int i = 0; i < strings.length; i++) {
pq.insert(i, strings[i]);
}
// print each key using the iterator
for (int i : pq) {
StdOut.println(i + " " + strings[i]);
}
StdOut.println();
// increase or decrease the key
for (int i = 0; i < strings.length; i++) {
if (StdRandom.uniform() < 0.5)
pq.increaseKey(i, strings[i] + strings[i]);
else
pq.decreaseKey(i, strings[i].substring(0,
1));
}
// delete and print each key
while (!pq.isEmpty()) {
String key = pq.maxKey();
int i = pq.delMax();
StdOut.println(i + " " + key);
}
StdOut.println();
// reinsert the same strings
for (int i = 0; i < strings.length; i++) {
pq.insert(i, strings[i]);
}
// delete them in random order
int[] perm = new int[strings.length];
for (int i = 0; i < strings.length; i++)
perm[i] = i;
StdRandom.shuffle(perm);
for (int i = 0; i < perm.length; i++) {
String key = pq.keyOf(perm[i]);
pq.delete(perm[i]);
StdOut.println(perm[i] + " " + key);

}
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Tue Jul 28 10:06:44 EDT 2015.

Multiway.java
Below is the syntax highlighted version
of Multiway.java from 2.4 Priority Queues.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac Multiway.java
* Execution:
java Multiway input1.txt input2.txt
input3.txt ...
* Dependencies: IndexMinPQ.java In.java StdOut.java
*
* Merges together the sorted input stream given as
command-line arguments
* into a single sorted output stream on standard output.

*
*
*
*
*
*
*
*
*
*
*
*
*

% more m1.txt
A B C F G I I Z
% more m2.txt
B D H P Q Q
% 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

***********************************************************
**************/
/**
* The <tt>Multiway</tt> class provides a client for
reading in several
* sorted text files and merging them together into a
single sorted
* text stream.
* This implementation uses a {@link IndexMinPQ} to
perform the multiway
* merge.
* <p>
* For additional documentation, see <a
href="http://algs4.cs.princeton.edu/24pq">Section 2.4</a>
* of <i>Algorithms, 4th Edition</i> by Robert Sedgewick
and Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class Multiway {
// This class should not be instantiated.
private Multiway() { }
// merge together the sorted input streams and write
the sorted result to standard output
private static void merge(In[] streams) {
int N = streams.length;
IndexMinPQ<String> pq = new IndexMinPQ<String>(N);
for (int i = 0; i < N; i++)

if (!streams[i].isEmpty())
pq.insert(i, streams[i].readString());
// Extract and print min and read next from its
stream.
while (!pq.isEmpty()) {
StdOut.print(pq.minKey() + " ");
int i = pq.delMin();
if (!streams[i].isEmpty())
pq.insert(i, streams[i].readString());
}
StdOut.println();
}
/**
* Reads sorted text files specified as command-line
arguments;
* merges them together into a sorted output; and
writes
* the results to standard output.
* Note: this client does not check that the input
files are sorted.
*/
public static void main(String[] args) {
int N = args.length;
In[] streams = new In[N];
for (int i = 0; i < N; i++)
streams[i] = new In(args[i]);
merge(streams);
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Wed Sep 25 11:19:34 EDT 2013.

Heap.java
Below is the syntax highlighted version
of Heap.java from 2.4 Priority Queues.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac Heap.java
* Execution:
java Heap < input.txt
* Dependencies: StdOut.java StdIn.java
* Data files:
http://algs4.cs.princeton.edu/24pq/tiny.txt
*
http://algs4.cs.princeton.edu/24pq/words3.txt
*
* Sorts a sequence of strings from standard input using
heapsort.

*
* % more tiny.txt
* S O R T E X A M P L E
*
* % java Heap < tiny.txt
* A E E L M O P R S T X
line ]
*
* % more words3.txt
* bed bug dad yes zoo ... all bad yet
*
* % java Heap < words3.txt
* all bad bed bug dad ... yes yet zoo
line ]
*

[ one string per

[ one string per

***********************************************************
**************/
/**
* The <tt>Heap</tt> class provides a static methods for
heapsorting
* an array.
* <p>
* For additional documentation, see <a
href="http://algs4.cs.princeton.edu/24pq">Section 2.4</a>
of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class Heap {
// This class should not be instantiated.
private Heap() { }
/**
* Rearranges the array in ascending order, using the
natural order.
* @param pq the array to be sorted
*/
public static void sort(Comparable[] pq) {
int N = pq.length;
for (int k = N/2; k >= 1; k--)
sink(pq, k, N);

while (N > 1) {
exch(pq, 1, N--);
sink(pq, 1, N);
}
}
/**********************************************************
*************
* Helper functions to restore the heap invariant.
***********************************************************
***********/
private static void sink(Comparable[] pq, int k, int N)
{
while (2*k <= N) {
int j = 2*k;
if (j < N && less(pq, j, j+1)) j++;
if (!less(pq, k, j)) break;
exch(pq, k, j);
k = j;
}
}
/**********************************************************
*************
* Helper functions for comparisons and swaps.
* Indices are "off-by-one" to support 1-based indexing.
***********************************************************
***********/
private static boolean less(Comparable[] pq, int i, int
j) {
return pq[i-1].compareTo(pq[j-1]) < 0;
}
private static void exch(Object[] pq, int i, int j) {
Object swap = pq[i-1];
pq[i-1] = pq[j-1];
pq[j-1] = swap;
}
// is v < w ?
private static boolean less(Comparable v, Comparable w)
{
return (v.compareTo(w) < 0);

/**********************************************************
*************
* Check if array is sorted - useful for debugging.
***********************************************************
************/
private static boolean isSorted(Comparable[] a) {
for (int i = 1; i < a.length; i++)
if (less(a[i], a[i-1])) return false;
return true;
}
// print array to standard output
private static void show(Comparable[] a) {
for (int i = 0; i < a.length; i++) {
StdOut.println(a[i]);
}
}
/**
* Reads in a sequence of strings from standard input;
heapsorts them;
* and prints them to standard output in ascending
order.
*/
public static void main(String[] args) {
String[] a = StdIn.readAllStrings();
Heap.sort(a);
show(a);
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Tue Jul 28 13:36:52 EDT 2015.

FrequencyCounter.java
Below is the syntax highlighted version
of FrequencyCounter.java from 3.1 Elementary Symbol Tables.
Here is the Javadoc.

/
***********************************************************
**************
* Compilation: javac FrequencyCounter.java
* Execution:
java FrequencyCounter L < input.txt
* Dependencies: ST.java StdIn.java StdOut.java
* Data files:
http://algs4.cs.princeton.edu/31elementary/tnyTale.txt
*
http://algs4.cs.princeton.edu/31elementary/tale.txt

*
http://algs4.cs.princeton.edu/31elementary/leipzig100K.txt
*
http://algs4.cs.princeton.edu/31elementary/leipzig300K.txt
*
http://algs4.cs.princeton.edu/31elementary/leipzig1M.txt
*
* Read in a list of words from standard input and print
out
* the most frequently occurring word that has length
greater than
* a given threshold.
*
* % java FrequencyCounter 1 < tinyTale.txt
* it 10
*
* % java FrequencyCounter 8 < tale.txt
* business 122
*
* % java FrequencyCounter 10 < leipzig1M.txt
* government 24763
*
*
***********************************************************
**************/
/**
* The <tt>FrequencyCounter</tt> 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.
* <p>
* For additional documentation, see <a
href="http://algs4.cs.princeton.edu/31elementary">Section
3.1</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class FrequencyCounter {

/**
* Reads in a command-line integer and sequence of
words from
* standard input and prints out a word (whose length
exceeds
* the threshold) that occurs most frequently to
standard output.
* It also prints out the number of words whose length
exceeds
* the threshold and the number of distinct such words.
*/
public static void main(String[] args) {
int distinct = 0, words = 0;
int minlen = Integer.parseInt(args[0]);
ST<String, Integer> st = new ST<String, Integer>();
// compute frequency counts
while (!StdIn.isEmpty()) {
String key = StdIn.readString();
if (key.length() < minlen) continue;
words++;
if (st.contains(key)) {
st.put(key, st.get(key) + 1);
}
else {
st.put(key, 1);
distinct++;
}
}
// find a key with the highest frequency count
String max = "";
st.put(max, 0);
for (String word : st.keys()) {
if (st.get(word) > st.get(max))
max = word;
}
StdOut.println(max + " " + st.get(max));
StdOut.println("distinct = " + distinct);
StdOut.println("words
= " + words);
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Sat Oct 5 06:29:24 EDT 2013.

SequentialSearchST.java
Below is the syntax highlighted version
of SequentialSearchST.java from 3.1 Elementary Symbol
Tables.
Here is the Javadoc.

/
***********************************************************
**************
* Compilation: javac SequentialSearchST.java
* Execution:
java SequentialSearchST
* Dependencies: StdIn.java StdOut.java
* Data files:
http://algs4.cs.princeton.edu/31elementary/tinyST.txt

*
*
an
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*

Symbol table implementation with sequential search in


unordered linked list of key-value pairs.
% more tinyST.txt
S E A R C H E X A M P L E
%
L
P
M
X
H
C
R
A
E
S

java SequentialSearchST < tiny.txt


11
10
9
7
5
4
3
8
12
0

***********************************************************
**************/
/**
* The <tt>SequentialSearchST</tt> class represents an
(unordered)
* symbol table of generic key-value pairs.
* It supports the usual <em>put</em>, <em>get</em>,
<em>contains</em>,
* <em>delete</em>, <em>size</em>, and <em>is-empty</em>
methods.
* It also provides a <em>keys</em> method for iterating
over all of the keys.
* A symbol table implements the <em>associative array</em>
abstraction:
* when associating a value with a key that is already in
the symbol table,
* the convention is to replace the old value with the new
value.
* The class also uses the convention that values cannot
be <tt>null</tt>. Setting the
* value associated with a key to <tt>null</tt> is
equivalent to deleting the key
* from the symbol table.
* <p>

* This implementation uses a singly-linked list and


sequential search.
* It relies on the <tt>equals()</tt> method to test
whether two keys
* are equal. It does not call either the
<tt>compareTo()</tt> or
* <tt>hashCode()</tt> method.
* The <em>put</em> and <em>delete</em> operations take
linear time; the
* <em>get</em> and <em>contains</em> operations takes
linear time in the worst case.
* The <em>size</em>, and <em>is-empty</em> operations
take constant time.
* Construction takes constant time.
* <p>
* For additional documentation, see <a
href="http://algs4.cs.princeton.edu/31elementary">Section
3.1</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class SequentialSearchST<Key, Value> {
private int N;
// number of key-value pairs
private Node first;
// the linked list of keyvalue pairs
// a helper linked list data type
private class Node {
private Key key;
private Value val;
private Node next;
public Node(Key
this.key =
this.val =
this.next =
}

key, Value val, Node next)


key;
val;
next;

}
/**
* Initializes an empty symbol table.
*/
public SequentialSearchST() {
}

/**
* Returns
table.
* @return
table
*/
public int
return
}

the number of key-value pairs in this symbol


the number of key-value pairs in this symbol
size() {
N;

/**
* Is this symbol table empty?
* @return <tt>true</tt> if this symbol table is empty
and <tt>false</tt> otherwise
*/
public boolean isEmpty() {
return size() == 0;
}
/**
* Does this symbol table contain the given key?
* @param key the key
* @return <tt>true</tt> if this symbol table contains
<tt>key</tt> and
*
<tt>false</tt> otherwise
*/
public boolean contains(Key key) {
return get(key) != null;
}
/**
* Returns the value associated with the given key.
* @param key the key
* @return the value associated with the given key if
the key is in the symbol table
*
and <tt>null</tt> if the key is not in the
symbol table
*/
public Value get(Key key) {
for (Node x = first; x != null; x = x.next) {
if (key.equals(x.key))
return x.val;
}
return null;
}

/**
* Inserts the key-value pair into the symbol table,
overwriting the old value
* with the new value if the key is already in the
symbol table.
* If the value is <tt>null</tt>, this effectively
deletes the key from the symbol table.
* @param key the key
* @param val the value
*/
public void put(Key key, Value val) {
if (val == null) {
delete(key);
return;
}
for (Node x = first; x != null; x = x.next) {
if (key.equals(x.key)) {
x.val = val;
return;
}
}
first = new Node(key, val, first);
N++;
}
/**
* Removes the key and associated value from the symbol
table
* (if the key is in the symbol table).
* @param key the key
*/
public void delete(Key key) {
first = delete(first, key);
}
// delete key in linked list beginning at Node x
// warning: function call stack too large if table is
large
private Node delete(Node x, Key key) {
if (x == null) return null;
if (key.equals(x.key)) {
N--;
return x.next;
}
x.next = delete(x.next, key);
return x;

}
/**
* Returns all keys in the symbol table as an
<tt>Iterable</tt>.
* To iterate over all of the keys in the symbol table
named <tt>st</tt>,
* use the foreach notation: <tt>for (Key key :
st.keys())</tt>.
* @return all keys in the sybol table as an
<tt>Iterable</tt>
*/
public Iterable<Key> keys() {
Queue<Key> queue = new Queue<Key>();
for (Node x = first; x != null; x = x.next)
queue.enqueue(x.key);
return queue;
}
/**
* Unit tests the <tt>SequentialSearchST</tt> data
type.
*/
public static void main(String[] args) {
SequentialSearchST<String, Integer> st = new
SequentialSearchST<String, Integer>();
for (int i = 0; !StdIn.isEmpty(); i++) {
String key = StdIn.readString();
st.put(key, i);
}
for (String s : st.keys())
StdOut.println(s + " " + st.get(s));
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Tue Jul 28 06:21:05 EDT 2015.

BinarySearchST.java
Below is the syntax highlighted version
of BinarySearchST.java from 3.1 Elementary Symbol Tables.
Here is the Javadoc.

/
***********************************************************
**************
* Compilation: javac BinarySearchST.java
* Execution:
java BinarySearchST
* Dependencies: StdIn.java StdOut.java
* Data files:
http://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
* E 12
* H 5
* L 11
* M 9
* P 10
* R 3
* S 0
* X 7
*
***********************************************************
**************/
import java.util.NoSuchElementException;
public class BinarySearchST<Key extends Comparable<Key>,
Value> {
private static final int INIT_CAPACITY = 2;
private Key[] keys;
private Value[] vals;
private int N = 0;
// create an empty symbol table with default initial
capacity
public BinarySearchST() {
this(INIT_CAPACITY);
}
// create an empty symbol table with given initial
capacity
public BinarySearchST(int capacity) {
keys = (Key[]) new Comparable[capacity];
vals = (Value[]) new Object[capacity];
}
// resize the underlying arrays
private void resize(int capacity) {
assert capacity >= N;

Key[]
tempk = (Key[])
new Comparable[capacity];
Value[] tempv = (Value[]) new Object[capacity];
for (int i = 0; i < N; i++) {
tempk[i] = keys[i];
tempv[i] = vals[i];
}
vals = tempv;
keys = tempk;
}
// is the key in the table?
public boolean contains(Key key) {
return get(key) != null;
}
// number of key-value pairs in the table
public int size() {
return N;
}
// is the symbol table empty?
public boolean isEmpty() {
return size() == 0;
}
// return the value associated with the given key, or
null if no such key
public Value get(Key key) {
if (isEmpty()) return null;
int i = rank(key);
if (i < N && keys[i].compareTo(key) == 0) return
vals[i];
return null;
}
// return the number of keys in the table that are
smaller than given key
public int rank(Key key) {
int lo = 0, hi = N-1;
while (lo <= hi) {
int m = lo + (hi - lo) / 2;
int cmp = key.compareTo(keys[m]);
if
(cmp < 0) hi = m - 1;
else if (cmp > 0) lo = m + 1;
else return m;
}

return lo;
}
// Search for key. Update value if found; grow table if
new.
public void put(Key key, Value val)
if (val == null) {
delete(key);
return;
}

int i = rank(key);
// key is already in table
if (i < N && keys[i].compareTo(key) == 0) {
vals[i] = val;
return;
}
// insert new key-value pair
if (N == keys.length) resize(2*keys.length);
for (int j = N; j > i; j--)
keys[j] = keys[j-1];
vals[j] = vals[j-1];
}
keys[i] = key;
vals[i] = val;
N++;

assert check();
}
// Remove the key-value pair if present
public void delete(Key key) {
if (isEmpty()) return;
// compute rank
int i = rank(key);
// key not in table
if (i == N || keys[i].compareTo(key) != 0) {
return;
}

for (int j = i; j < N-1; j++)


keys[j] = keys[j+1];
vals[j] = vals[j+1];
}
N--;
keys[N] = null;
vals[N] = null;

// to avoid loitering

// resize if 1/4 full


if (N > 0 && N == keys.length/4)
resize(keys.length/2);
assert check();
}
// delete the minimum key and its associated value
public void deleteMin() {
if (isEmpty()) throw new
NoSuchElementException("Symbol table underflow error");
delete(min());
}
// delete the maximum key and its associated value
public void deleteMax() {
if (isEmpty()) throw new
NoSuchElementException("Symbol table underflow error");
delete(max());
}

/**********************************************************
*******************
* Ordered symbol table methods.
***********************************************************
******************/
public Key min() {
if (isEmpty()) return null;
return keys[0];
}
public Key max() {
if (isEmpty()) return null;
return keys[N-1];
}

public Key select(int k) {


if (k < 0 || k >= N) return null;
return keys[k];
}
public Key floor(Key key) {
int i = rank(key);
if (i < N && key.compareTo(keys[i]) == 0) return
keys[i];
if (i == 0) return null;
else return keys[i-1];
}
public Key ceiling(Key key) {
int i = rank(key);
if (i == N) return null;
else return keys[i];
}
public int size(Key lo, Key hi) {
if (lo.compareTo(hi) > 0) return 0;
if (contains(hi)) return rank(hi) - rank(lo) + 1;
else
return rank(hi) - rank(lo);
}
public Iterable<Key> keys() {
return keys(min(), max());
}
public Iterable<Key> keys(Key lo, Key hi) {
Queue<Key> queue = new Queue<Key>();
// if (lo == null && hi == null) return queue;
if (lo == null) throw new NullPointerException("lo
is null in keys()");
if (hi == null) throw new NullPointerException("hi
is null in keys()");
if (lo.compareTo(hi) > 0) return queue;
for (int i = rank(lo); i < rank(hi); i++)
queue.enqueue(keys[i]);
if (contains(hi)) queue.enqueue(keys[rank(hi)]);
return queue;
}

/**********************************************************
*******************
* Check internal invariants.
***********************************************************
******************/
private boolean check() {
return isSorted() && rankCheck();
}
// are the items in the array in ascending order?
private boolean isSorted() {
for (int i = 1; i < size(); i++)
if (keys[i].compareTo(keys[i-1]) < 0) return
false;
return true;
}
// check that rank(select(i)) = i
private boolean rankCheck() {
for (int i = 0; i < size(); i++)
if (i != rank(select(i))) return false;
for (int i = 0; i < size(); i++)
if (keys[i].compareTo(select(rank(keys[i]))) !=
0) return false;
return true;
}

/**********************************************************
*******************
* Test client.
***********************************************************
******************/
public static void main(String[] args) {
BinarySearchST<String, Integer> st = new
BinarySearchST<String, Integer>();
for (int i = 0; !StdIn.isEmpty(); i++) {
String key = StdIn.readString();
st.put(key, i);
}
for (String s : st.keys())
StdOut.println(s + " " + st.get(s));
}

}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Tue Jul 28 06:21:05 EDT 2015.

BST.java
Below is the syntax highlighted version
of BST.java from 3.2 Binary Search Trees.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac BST.java
* Execution:
java BST
* Dependencies: StdIn.java StdOut.java Queue.java
* Data files:
http://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
%
A
C
E
H
L
M
P
R
S
X

java BST < tinyST.txt


8
4
12
5
11
9
10
3
0
7

***********************************************************
**************/
import java.util.NoSuchElementException;
public class BST<Key extends Comparable<Key>, Value> {
private Node root;
// root of BST
private class Node {
private Key key;
private Value val;
private Node left, right;
subtrees
private int N;
subtree

// sorted by key
// associated data
// left and right
// number of nodes in

public Node(Key key, Value val, int N) {


this.key = key;
this.val = val;
this.N = N;
}
}
// is the symbol table empty?
public boolean isEmpty() {
return size() == 0;
}
// return number of key-value pairs in BST
public int size() {
return size(root);

}
// return number of key-value pairs in BST rooted at x
private int size(Node x) {
if (x == null) return 0;
else return x.N;
}
/**********************************************************
*************
* Search BST for given key, and return associated
value if found,
* return null if not found.
***********************************************************
************/
// does there exist a key-value pair with given key?
public boolean contains(Key key) {
return get(key) != null;
}
// return value associated with the given key, or null
if no such key exists
public Value get(Key key) {
return get(root, key);
}
private Value get(Node x, Key key) {
if (x == null) return null;
int cmp = key.compareTo(x.key);
if
(cmp < 0) return get(x.left, key);
else if (cmp > 0) return get(x.right, key);
else
return x.val;
}
/**********************************************************
*************
* Insert key-value pair into BST
* If key already exists, update with new value.
***********************************************************
************/
public void put(Key key, Value val) {
if (val == null) {
delete(key);
return;

}
root = put(root, key, val);
assert check();
}
private Node put(Node x, Key key, Value val)
if (x == null) return new Node(key, val,
int cmp = key.compareTo(x.key);
if
(cmp < 0) x.left = put(x.left,
else if (cmp > 0) x.right = put(x.right,
else
x.val
= val;
x.N = 1 + size(x.left) + size(x.right);
return x;
}

{
1);
key, val);
key, val);

/**********************************************************
*************
* Delete.
***********************************************************
************/
public void deleteMin() {
if (isEmpty()) throw new
NoSuchElementException("Symbol table underflow");
root = deleteMin(root);
assert check();
}
private Node deleteMin(Node x) {
if (x.left == null) return x.right;
x.left = deleteMin(x.left);
x.N = size(x.left) + size(x.right) + 1;
return x;
}
public void deleteMax() {
if (isEmpty()) throw new
NoSuchElementException("Symbol table underflow");
root = deleteMax(root);
assert check();
}
private Node deleteMax(Node x) {
if (x.right == null) return x.left;
x.right = deleteMax(x.right);

x.N = size(x.left) + size(x.right) + 1;


return x;
}
public void delete(Key key) {
root = delete(root, key);
assert check();
}
private Node delete(Node x, Key key) {
if (x == null) return null;
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 {
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.N = size(x.left) + size(x.right) + 1;
return x;
}

/**********************************************************
*************
* Min, max, floor, and ceiling.
***********************************************************
************/
public Key min() {
if (isEmpty()) return null;
return min(root).key;
}
private Node min(Node x) {
if (x.left == null) return x;
else
return min(x.left);
}
public Key max() {
if (isEmpty()) return null;
return max(root).key;

}
private Node max(Node x) {
if (x.right == null) return x;
else
return max(x.right);
}
public Key floor(Key key) {
Node x = floor(root, key);
if (x == null) return null;
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);
if (t != null) return t;
else return x;
}
public Key ceiling(Key key) {
Node x = ceiling(root, key);
if (x == null) return null;
else return x.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) {
Node t = ceiling(x.left, key);
if (t != null) return t;
else return x;
}
return ceiling(x.right, key);
}
/**********************************************************
*************
* Rank and selection.

***********************************************************
************/
public Key select(int k) {
if (k < 0 || k >= size()) return null;
Node x = select(root, k);
return x.key;
}
// 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;
}
public int rank(Key key) {
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);
}
/**********************************************************
*************
* Range count and range search.
***********************************************************
************/
public Iterable<Key> keys() {
return keys(min(), max());
}
public Iterable<Key> keys(Key lo, Key hi) {
Queue<Key> queue = new Queue<Key>();
keys(root, queue, lo, hi);
return queue;
}

private void keys(Node x, Queue<Key> queue, Key lo, Key


hi) {
if (x == null) return;
int cmplo = lo.compareTo(x.key);
int cmphi = hi.compareTo(x.key);
if (cmplo < 0) keys(x.left, queue, lo, hi);
if (cmplo <= 0 && cmphi >= 0) queue.enqueue(x.key);
if (cmphi > 0) keys(x.right, queue, lo, hi);
}
public int size(Key lo, Key hi) {
if (lo.compareTo(hi) > 0) return 0;
if (contains(hi)) return rank(hi) - rank(lo) + 1;
else
return rank(hi) - rank(lo);
}
// height of this BST (one-node tree has height 0)
public int height() {
return height(root);
}
private int height(Node x) {
if (x == null) return -1;
return 1 + Math.max(height(x.left),
height(x.right));
}
// level order traversal
public Iterable<Key> levelOrder() {
Queue<Key> keys = new Queue<Key>();
Queue<Node> queue = new Queue<Node>();
queue.enqueue(root);
while (!queue.isEmpty()) {
Node x = queue.dequeue();
if (x == null) continue;
keys.enqueue(x.key);
queue.enqueue(x.left);
queue.enqueue(x.right);
}
return keys;
}
/**********************************************************
***************

Check integrity of BST data structure.

***********************************************************
**************/
private boolean check() {
if (!isBST())
StdOut.println("Not in
symmetric order");
if (!isSizeConsistent()) StdOut.println("Subtree
counts not consistent");
if (!isRankConsistent()) StdOut.println("Ranks not
consistent");
return isBST() && isSizeConsistent() &&
isRankConsistent();
}
// does this binary tree satisfy symmetric order?
// Note: this test also ensures that data structure is
a binary tree since order is strict
private boolean isBST() {
return isBST(root, null, null);
}
// is the tree rooted at x a BST with all keys strictly
between min and max
// (if min or max is null, treat as empty constraint)
// Credit: Bob Dondero's elegant solution
private boolean isBST(Node x, Key min, Key max) {
if (x == null) return true;
if (min != null && x.key.compareTo(min) <= 0) return
false;
if (max != null && x.key.compareTo(max) >= 0) return
false;
return isBST(x.left, min, x.key) && isBST(x.right,
x.key, max);
}
// are the size fields correct?
private boolean isSizeConsistent() { return
isSizeConsistent(root); }
private boolean isSizeConsistent(Node x) {
if (x == null) return true;
if (x.N != size(x.left) + size(x.right) + 1) return
false;
return isSizeConsistent(x.left) &&
isSizeConsistent(x.right);
}

// check that ranks are consistent


private boolean isRankConsistent() {
for (int i = 0; i < size(); i++)
if (i != rank(select(i))) return false;
for (Key key : keys())
if (key.compareTo(select(rank(key))) != 0)
return false;
return true;
}

/**********************************************************
*******************
* Test client.
***********************************************************
******************/
public static void main(String[] args) {
BST<String, Integer> st = new BST<String,
Integer>();
for (int i = 0; !StdIn.isEmpty(); i++) {
String key = StdIn.readString();
st.put(key, i);
}
for (String s : st.levelOrder())
StdOut.println(s + " " + st.get(s));
StdOut.println();
for (String s : st.keys())
StdOut.println(s + " " + st.get(s));
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Tue Jul 28 06:21:05 EDT 2015.

RedBlackBST.java
Below is the syntax highlighted version
of RedBlackBST.java from 3.3 Balanced Search Trees.
is the Javadoc.

Here

/
***********************************************************
**************
* Compilation: javac RedBlackBST.java
* Execution:
java RedBlackBST < input.txt
* Dependencies: StdIn.java StdOut.java
* Data files:
http://algs4.cs.princeton.edu/33balanced/tinyST.txt
*
* A symbol table implemented using a left-leaning redblack BST.
* This is the 2-3 version.
*
* Note: commented out assertions because DrJava now
enables assertions

*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*

by default.
% more tinyST.txt
S E A R C H E X A M P L E
%
A
C
E
H
L
M
P
R
S
X

java RedBlackBST < tinyST.txt


8
4
12
5
11
9
10
3
0
7

***********************************************************
**************/
import java.util.NoSuchElementException;
public class RedBlackBST<Key extends Comparable<Key>, Value>
{
private static final boolean RED
= true;
private static final boolean BLACK = false;
private Node root;

// root of the BST

// BST helper node data type


private class Node {
private Key key;
private Value val;
private Node left, right;
right subtrees
private boolean color;
private int N;

// key
// associated data
// links to left and
// color of parent link
// subtree count

public Node(Key key, Value val, boolean color, int


N) {
this.key = key;
this.val = val;
this.color = color;
this.N = N;
}

}
/**********************************************************
***************
* Node helper methods.
***********************************************************
**************/
// is node x red; false if x is null ?
private boolean isRed(Node x) {
if (x == null) return false;
return (x.color == RED);
}
// number of node in subtree rooted at x; 0 if x is
null
private int size(Node x) {
if (x == null) return 0;
return x.N;
}

/**********************************************************
***************
* Size methods.
***********************************************************
**************/
// return number of key-value pairs in this symbol
table
public int size() { return size(root); }
// is this symbol table empty?
public boolean isEmpty() {
return root == null;
}
/**********************************************************
***************
* Standard BST search.
***********************************************************
**************/

// value associated with the given key; null if no such


key
public Value get(Key key) { return get(root, key); }
// value associated with the given key in subtree
rooted at x; null if no such key
private Value get(Node x, Key key) {
while (x != null) {
int cmp = key.compareTo(x.key);
if
(cmp < 0) x = x.left;
else if (cmp > 0) x = x.right;
else
return x.val;
}
return null;
}
// is there a key-value pair with the given key?
public boolean contains(Key key) {
return get(key) != null;
}
// is there a key-value pair with the given key in the
subtree rooted at x?
// private boolean contains(Node x, Key key) {
//
return (get(x, key) != null);
// }
/**********************************************************
***************
* Red-black tree insertion.
***********************************************************
**************/
// insert the key-value pair; overwrite the old value
with the new value
// if the key is already present
public void put(Key key, Value val) {
root = put(root, key, val);
root.color = BLACK;
// assert check();
}
// insert the key-value pair in the subtree rooted at h
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);
else
h.val
= val;
// fix-up any right-leaning links
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);
h.N = size(h.left) + size(h.right) + 1;
return h;
}
/**********************************************************
***************
* Red-black tree deletion.
***********************************************************
**************/
// delete the key-value pair with the minimum key
public void deleteMin() {
if (isEmpty()) throw new NoSuchElementException("BST
underflow");
// if both children of root are black, set root to
red
if (!isRed(root.left) && !isRed(root.right))
root.color = RED;
root = deleteMin(root);
if (!isEmpty()) root.color = BLACK;
// assert check();
}
// delete the key-value pair with the minimum key
rooted at h
private Node deleteMin(Node h) {
if (h.left == null)
return null;

if (!isRed(h.left) && !isRed(h.left.left))


h = moveRedLeft(h);
h.left = deleteMin(h.left);
return balance(h);
}
// delete the key-value pair with the maximum key
public void deleteMax() {
if (isEmpty()) throw new NoSuchElementException("BST
underflow");
// if both children of root are black, set root to
red
if (!isRed(root.left) && !isRed(root.right))
root.color = RED;
root = deleteMax(root);
if (!isEmpty()) root.color = BLACK;
// assert check();
}
// delete the key-value pair with the maximum key
rooted at h
private Node deleteMax(Node h) {
if (isRed(h.left))
h = rotateRight(h);
if (h.right == null)
return null;
if (!isRed(h.right) && !isRed(h.right.left))
h = moveRedRight(h);
h.right = deleteMax(h.right);
return balance(h);
}
// delete the key-value pair with the given key
public void delete(Key key) {
if (!contains(key)) {
System.err.println("symbol table does not
contain " + key);
return;
}

// if both children of root are black, set root to


red
if (!isRed(root.left) && !isRed(root.right))
root.color = RED;
root = delete(root, key);
if (!isEmpty()) root.color = BLACK;
// assert check();
}
// delete the key-value pair with the given key rooted
at h
private Node delete(Node h, Key key) {
// assert get(h, key) != null;
if (key.compareTo(h.key) < 0) {
if (!isRed(h.left) && !isRed(h.left.left))
h = moveRedLeft(h);
h.left = delete(h.left, key);
}
else {
if (isRed(h.left))
h = rotateRight(h);
if (key.compareTo(h.key) == 0 && (h.right ==
null))
return null;
if (!isRed(h.right) && !isRed(h.right.left))
h = moveRedRight(h);
if (key.compareTo(h.key) == 0) {
Node x = min(h.right);
h.key = x.key;
h.val = x.val;
// h.val = get(h.right, min(h.right).key);
// h.key = min(h.right).key;
h.right = deleteMin(h.right);
}
else h.right = delete(h.right, key);
}
return balance(h);
}
/**********************************************************
***************
* Red-black tree helper functions.

***********************************************************
**************/
// make a left-leaning link lean to the right
private Node rotateRight(Node h) {
// assert (h != null) && isRed(h.left);
Node x = h.left;
h.left = x.right;
x.right = h;
x.color = x.right.color;
x.right.color = RED;
x.N = h.N;
h.N = size(h.left) + size(h.right) + 1;
return x;
}
// make a right-leaning link lean to the left
private Node rotateLeft(Node h) {
// assert (h != null) && isRed(h.right);
Node x = h.right;
h.right = x.left;
x.left = h;
x.color = x.left.color;
x.left.color = RED;
x.N = h.N;
h.N = size(h.left) + size(h.right) + 1;
return x;
}
// flip the colors of a node and its two children
private void flipColors(Node h) {
// h must have opposite color of its two children
// assert (h != null) && (h.left != null) &&
(h.right != null);
// assert (!isRed(h) && isRed(h.left) &&
isRed(h.right))
//
|| (isRed(h) && !isRed(h.left) && !
isRed(h.right));
h.color = !h.color;
h.left.color = !h.left.color;
h.right.color = !h.right.color;
}
// Assuming that h is red and both h.left and
h.left.left
// are black, make h.left or one of its children red.

private Node moveRedLeft(Node h) {


// assert (h != null);
// assert isRed(h) && !isRed(h.left) && !
isRed(h.left.left);
flipColors(h);
if (isRed(h.right.left)) {
h.right = rotateRight(h.right);
h = rotateLeft(h);
flipColors(h);
}
return h;
}
// Assuming that h is red and both h.right and
h.right.left
// are black, make h.right or one of its children red.
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)) {
h = rotateRight(h);
flipColors(h);
}
return h;
}
// restore red-black tree invariant
private Node balance(Node h) {
// assert (h != null);
if (isRed(h.right))
h =
rotateLeft(h);
if (isRed(h.left) && isRed(h.left.left)) h =
rotateRight(h);
if (isRed(h.left) && isRed(h.right))
flipColors(h);
h.N = size(h.left) + size(h.right) + 1;
return h;
}

/**********************************************************
***************
* Utility functions.
***********************************************************
**************/
// height of tree (1-node tree has height 0)
public int height() { return height(root); }
private int height(Node x) {
if (x == null) return -1;
return 1 + Math.max(height(x.left),
height(x.right));
}
/**********************************************************
***************
* Ordered symbol table methods.
***********************************************************
**************/
// the smallest key; null if no such key
public Key min() {
if (isEmpty()) return null;
return min(root).key;
}
// the smallest key in subtree rooted at x; null if no
such key
private Node min(Node x) {
// assert x != null;
if (x.left == null) return x;
else
return min(x.left);
}
// the largest key; null if no such key
public Key max() {
if (isEmpty()) return null;
return max(root).key;
}
// the largest key in the subtree rooted at x; null if
no such key
private Node max(Node x) {
// assert x != null;

if (x.right == null) return x;


else
return max(x.right);
}
// the largest key less than or equal to the given key
public Key floor(Key key) {
Node x = floor(root, key);
if (x == null) return null;
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) {
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);
if (t != null) return t;
else
return x;
}
// the smallest key greater than or equal to the given
key
public Key ceiling(Key key) {
Node x = ceiling(root, key);
if (x == null) return null;
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) {
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;
else
return x;
}
// the key of rank k
public Key select(int k) {
if (k < 0 || k >= size())

return null;

Node x = select(root, k);


return x.key;
}
// 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;
}
// number of keys less than key
public int rank(Key key) {
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);
}
/**********************************************************
*************
* Range count and range search.
***********************************************************
************/
// all of the keys, as an Iterable
public Iterable<Key> keys() {
return keys(min(), max());
}
// the keys between lo and hi, as an Iterable
public Iterable<Key> keys(Key lo, Key hi) {
Queue<Key> queue = new Queue<Key>();

// if (isEmpty() || lo.compareTo(hi) > 0) return


queue;
keys(root, queue, lo, hi);
return queue;
}
// add the keys between lo and hi in the subtree rooted
at x
// to the queue
private void keys(Node x, Queue<Key> queue, Key lo, Key
hi) {
if (x == null) return;
int cmplo = lo.compareTo(x.key);
int cmphi = hi.compareTo(x.key);
if (cmplo < 0) keys(x.left, queue, lo, hi);
if (cmplo <= 0 && cmphi >= 0) queue.enqueue(x.key);
if (cmphi > 0) keys(x.right, queue, lo, hi);
}
// number keys between lo and hi
public int size(Key lo, Key hi) {
if (lo.compareTo(hi) > 0) return 0;
if (contains(hi)) return rank(hi) - rank(lo) + 1;
else
return rank(hi) - rank(lo);
}

/**********************************************************
***************
* Check integrity of red-black tree data structure.
***********************************************************
**************/
private boolean check() {
if (!isBST())
StdOut.println("Not in
symmetric order");
if (!isSizeConsistent()) StdOut.println("Subtree
counts not consistent");
if (!isRankConsistent()) StdOut.println("Ranks not
consistent");
if (!is23())
StdOut.println("Not a 2-3
tree");
if (!isBalanced())
StdOut.println("Not
balanced");
return isBST() && isSizeConsistent() &&
isRankConsistent() && is23() && isBalanced();

}
// does this binary tree satisfy symmetric order?
// Note: this test also ensures that data structure is
a binary tree since order is strict
private boolean isBST() {
return isBST(root, null, null);
}
// is the tree rooted at x a BST with all keys strictly
between min and max
// (if min or max is null, treat as empty constraint)
// Credit: Bob Dondero's elegant solution
private boolean isBST(Node x, Key min, Key max) {
if (x == null) return true;
if (min != null && x.key.compareTo(min) <= 0) return
false;
if (max != null && x.key.compareTo(max) >= 0) return
false;
return isBST(x.left, min, x.key) && isBST(x.right,
x.key, max);
}
// are the size fields correct?
private boolean isSizeConsistent() { return
isSizeConsistent(root); }
private boolean isSizeConsistent(Node x) {
if (x == null) return true;
if (x.N != size(x.left) + size(x.right) + 1) return
false;
return isSizeConsistent(x.left) &&
isSizeConsistent(x.right);
}
// check that ranks are consistent
private boolean isRankConsistent() {
for (int i = 0; i < size(); i++)
if (i != rank(select(i))) return false;
for (Key key : keys())
if (key.compareTo(select(rank(key))) != 0)
return false;
return true;
}
// Does the tree have no red right links, and at most
one (left)
// red links in a row on any path?

private boolean is23() { return is23(root); }


private boolean is23(Node x) {
if (x == null) return true;
if (isRed(x.right)) return false;
if (x != root && isRed(x) && isRed(x.left))
return false;
return is23(x.left) && is23(x.right);
}
// do all paths from root to leaf have same number of
black edges?
private boolean isBalanced() {
int black = 0;
// number of black links on path
from root to min
Node x = root;
while (x != null) {
if (!isRed(x)) black++;
x = x.left;
}
return isBalanced(root, black);
}
// does every path from the root to a leaf have the
given number of black links?
private boolean isBalanced(Node x, int black) {
if (x == null) return black == 0;
if (!isRed(x)) black--;
return isBalanced(x.left, black) &&
isBalanced(x.right, black);
}

/**********************************************************
*******************
* Test client.
***********************************************************
******************/
public static void main(String[] args) {
RedBlackBST<String, Integer> st = new
RedBlackBST<String, Integer>();
for (int i = 0; !StdIn.isEmpty(); i++) {
String key = StdIn.readString();
st.put(key, i);
}
for (String s : st.keys())

StdOut.println(s + " " + st.get(s));


StdOut.println();
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Tue Jul 28 06:54:04 EDT 2015.

SeparateChainingHashST.java
Below is the syntax highlighted version
of SeparateChainingHashST.java from 3.4 Hash Tables.
is the Javadoc.

Here

/
***********************************************************
**************
* Compilation: javac SeparateChainingHashST.java
* Execution:
java SeparateChainingHashST
* Dependencies: StdIn.java StdOut.java
*
* A symbol table implemented with a separate-chaining
hash table.
*

***********************************************************
**************/
public class SeparateChainingHashST<Key, Value> {
private static final int INIT_CAPACITY = 4;
// largest prime <= 2^i for i = 3 to 31
// not currently used for doubling and shrinking
// private static final int[] PRIMES = {
//
7, 13, 31, 61, 127, 251, 509, 1021, 2039, 4093,
8191, 16381,
//
32749, 65521, 131071, 262139, 524287, 1048573,
2097143, 4194301,
//
8388593, 16777213, 33554393, 67108859, 134217689,
268435399,
//
536870909, 1073741789, 2147483647
// };
private int N;
of key-value pairs
private int M;
table size
private SequentialSearchST<Key, Value>[] st;
of linked-list symbol tables

// number
// hash
// array

// create separate chaining hash table


public SeparateChainingHashST() {
this(INIT_CAPACITY);
}
// create separate chaining hash table with M lists
public SeparateChainingHashST(int M) {
this.M = M;
st = (SequentialSearchST<Key, Value>[]) new
SequentialSearchST[M];
for (int i = 0; i < M; i++)
st[i] = new SequentialSearchST<Key, Value>();
}
// resize the hash table to have the given number of
chains b rehashing all of the keys
private void resize(int chains) {
SeparateChainingHashST<Key, Value> temp = new
SeparateChainingHashST<Key, Value>(chains);
for (int i = 0; i < M; i++) {

for (Key key : st[i].keys()) {


temp.put(key, st[i].get(key));
}
}
this.M = temp.M;
this.N = temp.N;
this.st = temp.st;
}
// hash value between 0 and M-1
private int hash(Key key) {
return (key.hashCode() & 0x7fffffff) % M;
}
// return number of key-value pairs in symbol table
public int size() {
return N;
}
// is the symbol table empty?
public boolean isEmpty() {
return size() == 0;
}
// is the key in the symbol table?
public boolean contains(Key key) {
return get(key) != null;
}
// return value associated with key, null if no such
key
public Value get(Key key) {
int i = hash(key);
return st[i].get(key);
}
// insert key-value pair into the table
public void put(Key key, Value val) {
if (val == null) {
delete(key);
return;
}
// double table size if average length of list >=
10
if (N >= 10*M) resize(2*M);

int i = hash(key);
if (!st[i].contains(key)) N++;
st[i].put(key, val);
}
// delete key (and associated value) if key is in the
table
public void delete(Key key) {
int i = hash(key);
if (st[i].contains(key)) N--;
st[i].delete(key);
// halve table size if average length of list <= 2
if (M > INIT_CAPACITY && N <= 2*M) resize(M/2);
}
// return keys in symbol table as an Iterable
public Iterable<Key> keys() {
Queue<Key> queue = new Queue<Key>();
for (int i = 0; i < M; i++) {
for (Key key : st[i].keys())
queue.enqueue(key);
}
return queue;
}

/**********************************************************
*************
* Unit test client.
***********************************************************
************/
public static void main(String[] args) {
SeparateChainingHashST<String, Integer> st = new
SeparateChainingHashST<String, Integer>();
for (int i = 0; !StdIn.isEmpty(); i++) {
String key = StdIn.readString();
st.put(key, i);
}
// print keys
for (String s : st.keys())
StdOut.println(s + " " + st.get(s));
}

}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Tue Jul 28 07:01:08 EDT 2015.

LinearProbingHashST.java
Below is the syntax highlighted version
of LinearProbingHashST.java from 3.4 Hash Tables.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac LinearProbingHashST.java
* Execution:
java LinearProbingHashST
* Dependencies: StdIn.java StdOut.java
*
* Symbol table implementation with linear probing hash
table.
*
* % java LinearProbingHashST
* 128.112.136.11
* 208.216.181.15
* null

*
*
***********************************************************
**************/
public class LinearProbingHashST<Key, Value> {
private static final int INIT_CAPACITY = 4;
private int N;
in the symbol table
private int M;
table
private Key[] keys;
private Value[] vals;

// number of key-value pairs


// size of linear probing
// the keys
// the values

// create an empty hash table - use 16 as default size


public LinearProbingHashST() {
this(INIT_CAPACITY);
}
// create linear proving hash table of given capacity
public LinearProbingHashST(int capacity) {
M = capacity;
keys = (Key[])
new Object[M];
vals = (Value[]) new Object[M];
}
// return the number of key-value pairs in the symbol
table
public int size() {
return N;
}
// is the symbol table empty?
public boolean isEmpty() {
return size() == 0;
}
// does a key-value pair with the given key exist in
the symbol table?
public boolean contains(Key key) {
return get(key) != null;
}

// hash function for keys - returns value between 0 and


M-1
private int hash(Key key) {
return (key.hashCode() & 0x7fffffff) % M;
}
// resize the hash table to the given capacity by rehashing all of the keys
private void resize(int capacity) {
LinearProbingHashST<Key, Value> temp = new
LinearProbingHashST<Key, Value>(capacity);
for (int i = 0; i < M; i++) {
if (keys[i] != null) {
temp.put(keys[i], vals[i]);
}
}
keys = temp.keys;
vals = temp.vals;
M
= temp.M;
}
// insert the key-value pair into the symbol table
public void put(Key key, Value val) {
if (val == null) {
delete(key);
return;
}
// double table size if 50% full
if (N >= M/2) resize(2*M);
int i;
for (i = hash(key); keys[i] != null; i = (i + 1) %
M) {
if (keys[i].equals(key)) {
vals[i] = val;
return;
}
}
keys[i] = key;
vals[i] = val;
N++;
}
// return the value associated with the given key, null
if no such value
public Value get(Key key) {

for (int i = hash(key); keys[i] != null; i = (i + 1)


% M)
if (keys[i].equals(key))
return vals[i];
return null;
}
// delete the key (and associated value) from the
symbol table
public void delete(Key key) {
if (!contains(key)) return;
// find position i of key
int i = hash(key);
while (!key.equals(keys[i])) {
i = (i + 1) % M;
}
// delete key and associated value
keys[i] = null;
vals[i] = null;
// rehash all keys in same cluster
i = (i + 1) % M;
while (keys[i] != null) {
// delete keys[i] an vals[i] and reinsert
Key
keyToRehash = keys[i];
Value valToRehash = vals[i];
keys[i] = null;
vals[i] = null;
N--;
put(keyToRehash, valToRehash);
i = (i + 1) % M;
}
N--;
// halves size of array if it's 12.5% full or less
if (N > 0 && N <= M/8) resize(M/2);
assert check();
}
// return all of the keys as in Iterable
public Iterable<Key> keys() {
Queue<Key> queue = new Queue<Key>();
for (int i = 0; i < M; i++)

if (keys[i] != null) queue.enqueue(keys[i]);


return queue;
}
// integrity check - don't check after each put()
because
// integrity not maintained during a delete()
private boolean check() {
// check that hash table is at most 50% full
if (M < 2*N) {
System.err.println("Hash table size M = " + M +
"; array size N = " + N);
return false;
}
// check that each key in table can be found by
get()
for (int i = 0; i < M; i++) {
if (keys[i] == null) continue;
else if (get(keys[i]) != vals[i]) {
System.err.println("get[" + keys[i] + "] = "
+ get(keys[i]) + "; vals[i] = " + vals[i]);
return false;
}
}
return true;
}
/
***********************************************************
************
* Unit test client.
***********************************************************
************/
public static void main(String[] args) {
LinearProbingHashST<String, Integer> st = new
LinearProbingHashST<String, Integer>();
for (int i = 0; !StdIn.isEmpty(); i++) {
String key = StdIn.readString();
st.put(key, i);
}
// print keys
for (String s : st.keys())

StdOut.println(s + " " + st.get(s));


}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Tue Jul 28 07:14:41 EDT 2015.

ST.java
Below is the syntax highlighted version of ST.java from
Algorithms.
Here is the Javadoc.

/
***********************************************************
**************
* Compilation: javac ST.java
* Execution:
java ST
* Dependencies: StdIn.java StdOut.java
*
* Sorted symbol table implementation using a
java.util.TreeMap.
* Does not allow duplicates.
*
* % java ST

*
***********************************************************
**************/
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.TreeMap;
/**
* The <tt>ST</tt> class represents an ordered symbol
table of generic
* key-value pairs.
* It supports the usual <em>put</em>, <em>get</em>,
<em>contains</em>,
* <em>delete</em>, <em>size</em>, and <em>is-empty</em>
methods.
* It also provides ordered methods for finding the
<em>minimum</em>,
* <em>maximum</em>, <em>floor</em>, and <em>ceiling</em>.
* It also provides a <em>keys</em> method for iterating
over all of the keys.
* A symbol table implements the <em>associative array</em>
abstraction:
* when associating a value with a key that is already in
the symbol table,
* the convention is to replace the old value with the new
value.
* Unlike {@link java.util.Map}, this class uses the
convention that
* values cannot be <tt>null</tt>&mdash;setting the
* value associated with a key to <tt>null</tt> is
equivalent to deleting the key
* from the symbol table.
* <p>
* This implementation uses a balanced binary search tree.
It requires that
* the key type implements the <tt>Comparable</tt>
interface and calls the
* <tt>compareTo()</tt> and method to compare two keys. It
does not call either
* <tt>equals()</tt> or <tt>hashCode()</tt>.
* The <em>put</em>, <em>contains</em>, <em>remove</em>,
<em>minimum</em>,
* <em>maximum</em>, <em>ceiling</em>, and <em>floor</em>
operations each take
* logarithmic time in the worst case.

* The <em>size</em>, and <em>is-empty</em> operations


take constant time.
* Construction takes constant time.
* <p>
* For additional documentation, see <a
href="http://algs4.cs.princeton.edu/35applications">Section
3.5</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*/
public class ST<Key extends Comparable<Key>, Value>
implements Iterable<Key> {
private TreeMap<Key, Value> st;
/**
* Initializes an empty symbol table.
*/
public ST() {
st = new TreeMap<Key, Value>();
}
/**
* Returns the value associated with the given key.
* @param key the key
* @return the value associated with the given key if
the key is in the symbol table
*
and <tt>null</tt> if the key is not in the
symbol table
* @throws NullPointerException if <tt>key</tt> is
<tt>null</tt>
*/
public Value get(Key key) {
if (key == null) throw new
NullPointerException("called get() with null key");
return st.get(key);
}
/**
* Inserts the key-value pair into the symbol table,
overwriting the old value
* with the new value if the key is already in the
symbol table.
* If the value is <tt>null</tt>, this effectively
deletes the key from the symbol table.
* @param key the key

* @param val the value


* @throws NullPointerException if <tt>key</tt> is
<tt>null</tt>
*/
public void put(Key key, Value val) {
if (key == null) throw new
NullPointerException("called put() with null key");
if (val == null) st.remove(key);
else
st.put(key, val);
}
/**
* Removes the key and associated value from the symbol
table
* (if the key is in the symbol table).
* @param key the key
* @throws NullPointerException if <tt>key</tt> is
<tt>null</tt>
*/
public void delete(Key key) {
if (key == null) throw new
NullPointerException("called delete() with null key");
st.remove(key);
}
/**
* Does this symbol table contain the given key?
* @param key the key
* @return <tt>true</tt> if this symbol table contains
<tt>key</tt> and
*
<tt>false</tt> otherwise
* @throws NullPointerException if <tt>key</tt> is
<tt>null</tt>
*/
public boolean contains(Key key) {
if (key == null) throw new
NullPointerException("called contains() with null key");
return st.containsKey(key);
}
/**
* Returns the number of key-value pairs in this symbol
table.
* @return the number of key-value pairs in this symbol
table
*/
public int size() {

return st.size();
}
/**
* Is this symbol table empty?
* @return <tt>true</tt> if this symbol table is empty
and <tt>false</tt> otherwise
*/
public boolean isEmpty() {
return size() == 0;
}
/**
* Returns all keys in the symbol table as an
<tt>Iterable</tt>.
* To iterate over all of the keys in the symbol table
named <tt>st</tt>,
* use the foreach notation: <tt>for (Key key :
st.keys())</tt>.
* @return all keys in the sybol table as an
<tt>Iterable</tt>
*/
public Iterable<Key> keys() {
return st.keySet();
}
/**
* Returns all of the keys in the symbol table as an
iterator.
* To iterate over all of the keys in a symbol table
named <tt>st</tt>, use the
* foreach notation: <tt>for (Key key : st)</tt>.
* This method is provided for backward compatibility
with the version from
* <em>Introduction to Programming in Java: An
Interdisciplinary Approach.</em>
* @return an iterator to all of the keys in the symbol
table
* @deprecated Use {@link #keys} instead.
*/
public Iterator<Key> iterator() {
return st.keySet().iterator();
}
/**
* Returns the smallest key in the symbol table.
* @return the smallest key in the symbol table

* @throws NoSuchElementException if the symbol table


is empty
*/
public Key min() {
if (isEmpty()) throw new
NoSuchElementException("called min() with empty symbol
table");
return st.firstKey();
}
/**
* Returns the largest key in the symbol table.
* @return the largest key in the symbol table
* @throws NoSuchElementException if the symbol table
is empty
*/
public Key max() {
if (isEmpty()) throw new
NoSuchElementException("called max() with empty symbol
table");
return st.lastKey();
}
/**
* Returns the smallest key in the symbol table greater
than or equal to <tt>key</tt>.
* @param key the key
* @return the smallest key in the symbol table greater
than or equal to <tt>key</tt>
* @throws NoSuchElementException if there is no such
key
* @throws NullPointerException if <tt>key</tt> is
<tt>null</tt>
*/
public Key ceiling(Key key) {
if (key == null) throw new
NullPointerException("called ceiling() with null key");
Key k = st.ceilingKey(key);
if (k == null) throw new NoSuchElementException("all
keys are less than " + key);
return k;
}
/**
* Returns the largest key in the symbol table less
than or equal to <tt>key</tt>.
* @param key the key

* @return the largest key in the symbol table less


than or equal to <tt>key</tt>
* @throws NoSuchElementException if there is no such
key
* @throws NullPointerException if <tt>key</tt> is
<tt>null</tt>
*/
public Key floor(Key key) {
if (key == null) throw new
NullPointerException("called floor() with null key");
Key k = st.floorKey(key);
if (k == null) throw new NoSuchElementException("all
keys are greater than " + key);
return k;
}
/**
* Unit tests the <tt>ST</tt> data type.
*/
public static void main(String[] args) {
ST<String, Integer> st = new ST<String, Integer>();
for (int i = 0; !StdIn.isEmpty(); i++) {
String key = StdIn.readString();
st.put(key, i);
}
for (String s : st.keys())
StdOut.println(s + " " + st.get(s));
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Thu Jul 23 17:05:46 EDT 2015.

SET.java
Below is the syntax highlighted version of SET.java from
Algorithms.
Here is the Javadoc.

/
***********************************************************
**************
* Compilation: javac SET.java
* Execution:
java SET
* Dependencies: StdOut.java
*
* Set implementation using Java's TreeSet library.
* Does not allow duplicates.
*
* % java SET
* 128.112.136.11
* 208.216.181.15
* null

*
***********************************************************
**************/
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.TreeSet;
/**
* The <tt>SET</tt> class represents an ordered set of
comparable keys.
* It supports the usual <em>add</em>, <em>contains</em>,
and <em>delete</em>
* methods. It also provides ordered methods for finding
the <em>minimum</em>,
* <em>maximum</em>, <em>floor</em>, and <em>ceiling</em>
and set methods
* for <em>union</em>, <em>intersection</em>, and
<em>equality</em>.
* <p>
* Even though this implementation include the method
<tt>equals()</tt>, it
* does not support the method <tt>hashCode()</tt> because
sets are mutable.
* <p>
* This implementation uses a balanced binary search tree.
It requires that
* the key type implements the <tt>Comparable</tt>
interface and calls the
* <tt>compareTo()</tt> and method to compare two keys. It
does not call either
* <tt>equals()</tt> or <tt>hashCode()</tt>.
* The <em>add</em>, <em>contains</em>, <em>delete</em>,
<em>minimum</em>,
* <em>maximum</em>, <em>ceiling</em>, and <em>floor</em>
methods take
* logarithmic time in the worst case.
* The <em>size</em>, and <em>is-empty</em> operations
take constant time.
* Construction takes constant time.
* <p>
* This implementation uses a balanced binary search tree.
It requires that
* For additional documentation, see

* <a
href="http://algs4.cs.princeton.edu/35applications">Section
3.5</a> of
* <i>Algorithms in Java, 4th Edition</i> by Robert
Sedgewick and Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class SET<Key extends Comparable<Key>> implements
Iterable<Key> {
private TreeSet<Key> set;
/**
* Initializes an empty set.
*/
public SET() {
set = new TreeSet<Key>();
}
/**
* Adds the key to the set if it is not already
present.
* @param key the key to add
* @throws NullPointerException if <tt>key</tt> is
<tt>null</tt>
*/
public void add(Key key) {
if (key == null) throw new
NullPointerException("called add() with a null key");
set.add(key);
}
/**
* Does the set contain the given key?
* @param key the key
* @return <tt>true</tt> if the set contains
<tt>key</tt> and
*
<tt>false</tt> otherwise
* @throws NullPointerException if <tt>key</tt> is
<tt>null</tt>
*/
public boolean contains(Key key) {
if (key == null) throw new
NullPointerException("called contains() with a null key");

return set.contains(key);
}
/**
* Removes the key from the set if the key is present.
* @param key the key
* @throws NullPointerException if <tt>key</tt> is
<tt>null</tt>
*/
public void delete(Key key) {
if (key == null) throw new
NullPointerException("called delete() with a null key");
set.remove(key);
}
/**
* Returns
* @return
*/
public int
return
}

the number of keys in the set.


the number of keys in the set
size() {
set.size();

/**
* Is the set empty?
* @return <tt>true</tt> if the set is empty, and
<tt>false</tt> otherwise
*/
public boolean isEmpty() {
return size() == 0;
}
/**
* Returns all of the keys in the set, as an iterator.
* To iterate over all of the keys in a set named
<tt>set</tt>, use the
* foreach notation: <tt>for (Key key : set)</tt>.
* @return an iterator to all of the keys in the set
*/
public Iterator<Key> iterator() {
return set.iterator();
}
/**
* Returns the largest key in the set.
* @return the largest key in the set
* @throws NoSuchElementException if the set is empty

*/
public Key max() {
if (isEmpty()) throw new
NoSuchElementException("called max() with empty set");
return set.last();
}
/**
* Returns the smallest key in the set.
* @return the smallest key in the set
* @throws NoSuchElementException if the set is empty
*/
public Key min() {
if (isEmpty()) throw new
NoSuchElementException("called min() with empty set");
return set.first();
}
/**
* Returns the smallest key in the set greater than or
equal to <tt>key</tt>.
* @param key the key
* @return the smallest key in the set greater than or
equal to <tt>key</tt>
* @throws NoSuchElementException if there is no such
key
* @throws NullPointerException if <tt>key</tt> is
<tt>null</tt>
*/
public Key ceiling(Key key) {
if (key == null) throw new
NullPointerException("called ceiling() with a null key");
Key k = set.ceiling(key);
if (k == null) throw new NoSuchElementException("all
keys are less than " + key);
return k;
}
/**
* Returns the largest key in the set less than or
equal to <tt>key</tt>.
* @param key the key
* @return the largest key in the set table less than
or equal to <tt>key</tt>
* @throws NoSuchElementException if there is no such
key

* @throws NullPointerException if <tt>key</tt> is


<tt>null</tt>
*/
public Key floor(Key key) {
if (key == null) throw new
NullPointerException("called floor() with a null key");
Key k = set.floor(key);
if (k == null) throw new NoSuchElementException("all
keys are greater than " + key);
return k;
}
/**
* Returns the union of this set and that set.
* @param that the other set
* @return the union of this set and that set
* @throws NullPointerException if <tt>that</tt> is
<tt>null</tt>
*/
public SET<Key> union(SET<Key> that) {
if (that == null) throw new
NullPointerException("called union() with a null argument");
SET<Key> c = new SET<Key>();
for (Key x : this) {
c.add(x);
}
for (Key x : that) {
c.add(x);
}
return c;
}
/**
* Returns the intersection of this set and that set.
* @param that the other set
* @return the intersection of this set and that set
* @throws NullPointerException if <tt>that</tt> is
<tt>null</tt>
*/
public SET<Key> intersects(SET<Key> that) {
if (that == null) throw new
NullPointerException("called intersects() with a null
argument");
SET<Key> c = new SET<Key>();
if (this.size() < that.size()) {
for (Key x : this) {
if (that.contains(x)) c.add(x);

}
}
else {
for (Key x : that) {
if (this.contains(x)) c.add(x);
}
}
return c;
}
/**
* Does this set equal <tt>y</tt>?
* Note that this method declares two empty sets to be
equal
* even if they are parameterized by different generic
types.
* This is consistent with the behavior of
<tt>equals()</tt>
* within Java's Collections framework.
* @param y the other set
* @return <tt>true</tt> if the two sets are equal;
<tt>false</tt> otherwise
*/
public boolean equals(Object y) {
if (y == this) return true;
if (y == null) return false;
if (y.getClass() != this.getClass()) return false;
SET<Key> that = (SET<Key>) y;
if (this.size() != that.size()) return false;
try {
for (Key k : this)
if (!that.contains(k)) return false;
}
catch (ClassCastException exception) {
return false;
}
return true;
}
/**
* This operation is not supported because sets are
mutable.
* @return does not return a value
* @throws UnsupportedOperationException if called
*/
public int hashCode() {

throw new UnsupportedOperationException("hashCode()


is not supported because sets are mutable");
}
/**
* Returns a string representation of this set.
* @return a string representation of this set, with
the keys separated
*
by single spaces
*/
public String toString() {
StringBuilder s = new StringBuilder();
for (Key key : this)
s.append(key + " ");
return s.toString();
}
/**
* Unit tests the <tt>SET</tt> data type.
*/
public static void main(String[] args) {
SET<String> set = new SET<String>();
// insert some keys
set.add("www.cs.princeton.edu");
set.add("www.cs.princeton.edu");
old value
set.add("www.princeton.edu");
set.add("www.math.princeton.edu");
set.add("www.yale.edu");
set.add("www.amazon.com");
set.add("www.simpsons.com");
set.add("www.stanford.edu");
set.add("www.google.com");
set.add("www.ibm.com");
set.add("www.apple.com");
set.add("www.slashdot.com");
set.add("www.whitehouse.gov");
set.add("www.espn.com");
set.add("www.snopes.com");
set.add("www.movies.com");
set.add("www.cnn.com");
set.add("www.iitb.ac.in");

// overwrite

StdOut.println(set.contains("www.cs.princeton.edu"));
StdOut.println(!
set.contains("www.harvardsucks.com"));
StdOut.println(set.contains("www.simpsons.com"));
StdOut.println();
StdOut.println("ceiling(www.simpsonr.com)
set.ceiling("www.simpsonr.com"));
StdOut.println("ceiling(www.simpsons.com)
set.ceiling("www.simpsons.com"));
StdOut.println("ceiling(www.simpsont.com)
set.ceiling("www.simpsont.com"));
StdOut.println("floor(www.simpsonr.com)
set.floor("www.simpsonr.com"));
StdOut.println("floor(www.simpsons.com)
set.floor("www.simpsons.com"));
StdOut.println("floor(www.simpsont.com)
set.floor("www.simpsont.com"));
StdOut.println();

= " +
= " +
= " +
= " +
= " +
= " +

// print out all keys in the set in lexicographic


order
for (String s : set) {
StdOut.println(s);
}
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Fri Jul 24 09:57:21 EDT 2015.

DeDup.java
Below is the syntax highlighted version
of DeDup.java from 3.5 Searching Applications.

/
***********************************************************
**************
* Compilation: javac DeDup.java
* Execution:
java DeDup < input.txt
* Dependencies: SET StdIn.java StdOut.java
* Data files:
http://algs4.cs.princeton.edu/35applications/tinyTale.txt

*
* 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
* it was the spring of hope it was the winter of despair
*
* % java DeDup < tinyTale.txt
* it
* was
* the
* best
* of
* times
* worst
* age
* wisdom
* ...
* winter
* despair
*
***********************************************************
**************/
public class DeDup {
public static void main(String[] args) {
SET<String> set = new SET<String>();
// read in strings and add to set
while (!StdIn.isEmpty()) {
String key = StdIn.readString();
if (!set.contains(key)) {
set.add(key);
StdOut.println(key);
}
}
}
}

Copyright 20022010, Robert Sedgewick and Kevin Wayne.


Last updated: Mon May 23 07:57:15 EDT 2011.

WhiteFilter.java
Below is the syntax highlighted version
of WhiteFilter.java from 3.5 Searching Applications.

/
***********************************************************
**************
* Compilation: javac WhiteFilter.java
* Execution:
java WhiteFilter whitelist.txt <
input.txt
* Dependencies: SET In.java StdIn.java StdOut.java
* Data files:
http://algs4.cs.princeton.edu/35applications/tinyTale.txt

*
http://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
* 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
* 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
* it was the of it was the of
* it was the of it was the of
* it was the of it was the of
* it was the of it was the of
* it was the of it was the of
*
***********************************************************
**************/
public class WhiteFilter {
public static void main(String[] args) {
SET<String> set = new SET<String>();
// read in strings and add to set
In in = new In(args[0]);
while (!in.isEmpty()) {
String word = in.readString();
set.add(word);
}
// read in string from standard input, printing out
all exceptions
while (!StdIn.isEmpty()) {
String word = StdIn.readString();

if (set.contains(word))
StdOut.println(word);
}
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Mon May 23 07:57:15 EDT 2011.

BlackFilter.java
Below is the syntax highlighted version
of BlackFilter.java from 3.5 Searching Applications.

/
***********************************************************
**************
* Compilation: javac BlackFilter.java
* Execution:
java BlackFilter blacklist.txt <
input.txt
* Dependencies: SET In.java StdIn.java StdOut.java

* Data files:
http://algs4.cs.princeton.edu/35applications/tinyTale.txt
*
http://algs4.cs.princeton.edu/35applications/list.txt
*
* Read in a blacklist of words from a file. Then read in
a list of
* words from standard input and print out all those words
that
* are not 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
* it was the spring of hope it was the winter of despair
*
* % more list.txt
* was it the of
*
* % java BlackFilter list.txt < tinyTale.txt
* best times worst times
* age wisdom age foolishness
* epoch belief epoch incredulity
* season light season darkness
* spring hope winter despair
*
***********************************************************
**************/
public class BlackFilter {
public static void main(String[] args) {
SET<String> set = new SET<String>();
// read in strings and add to set
In in = new In(args[0]);
while (!in.isEmpty()) {
String word = in.readString();
set.add(word);
}
// read in string from standard input, printing out
all exceptions

while (!StdIn.isEmpty()) {
String word = StdIn.readString();
if (!set.contains(word))
StdOut.println(word);
}
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Mon May 23 07:57:15 EDT 2011.

LookupCSV.java
Below is the syntax highlighted version
of LookupCSV.java from 3.5 Searching Applications.

/
***********************************************************
**************
* Compilation: javac LookupCSV.java
* Execution:
java LookupCSV file.csv keyField valField
* Dependencies: ST.java In.java StdIn.java StdOut.java

* Data files:
http://algs4.cs.princeton.edu/35applications/DJIA.csv
*
http://algs4.cs.princeton.edu/35applications/UPC.csv
*
http://algs4.cs.princeton.edu/35applications/amino.csv
*
http://algs4.cs.princeton.edu/35applications/elements.csv
*
http://algs4.cs.princeton.edu/35applications/ip.csv
*
http://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
*
1738.74
*
*
***********************************************************
**************/
public class LookupCSV
public static void
int keyField =
int valField =
// symbol table

{
main(String[] args) {
Integer.parseInt(args[1]);
Integer.parseInt(args[2]);

ST<String, String> st = new ST<String, String>();


// read in the data from csv file
In in = new In(args[0]);
while (in.hasNextLine()) {
String line = in.readLine();
String[] tokens = line.split(",");
String key = tokens[keyField];
String val = tokens[valField];
st.put(key, val);
}
while (!StdIn.isEmpty()) {
String s = StdIn.readString();
if (st.contains(s)) StdOut.println(st.get(s));
else
StdOut.println("Not found");
}
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Mon May 23 07:59:28 EDT 2011.

LookupIndex.java
Below is the syntax highlighted version
of LookupIndex.java from 3.5 Searching Applications.

LookupIndex.java
Below is the syntax highlighted version
of LookupIndex.java from 3.5 Searching Applications.

/
***********************************************************
**************
* Compilation: javac LookupIndex.java
* Execution:
java LookupIndex movies.txt "/"
* Dependencies: ST.java Queue.java In.java StdIn.java
StdOut.java
* Data files:
http://algs4.cs.princeton.edu/35applications/aminoI.txt
*
http://algs4.cs.princeton.edu/35applications/movies.txt
*
* % java LookupIndex aminoI.txt ","
* Serine
*
TCT
*
TCA
*
TCG
*
AGT
*
AGC
* TCG
*
Serine
*
* % java LookupIndex movies.txt "/"
* Bacon, Kevin
*
Animal House (1978)
*
Apollo 13 (1995)
*
Beauty Shop (2005)
*
Diner (1982)
*
Few Good Men, A (1992)
*
Flatliners (1990)
*
Footloose (1984)
*
Friday the 13th (1980)
*
...
* Tin Men (1987)
*
DeBoy, David
*
Blumenfeld, Alan
*
...
*
***********************************************************
**************/
public class LookupIndex {
public static void main(String[] args) {
String filename = args[0];
String separator = args[1];

In in = new In(filename);
ST<String, Queue<String>> st = new ST<String,
Queue<String>>();
ST<String, Queue<String>> ts = new ST<String,
Queue<String>>();
while (in.hasNextLine()) {
String line = in.readLine();
String[] fields = line.split(separator);
String key = fields[0];
for (int i = 1; i < fields.length; i++) {
String val = fields[i];
if (!st.contains(key)) st.put(key, new
Queue<String>());
if (!ts.contains(val)) ts.put(val, new
Queue<String>());
st.get(key).enqueue(val);
ts.get(val).enqueue(key);
}
}
StdOut.println("Done indexing");
// read queries from standard input, one per line
while (!StdIn.isEmpty()) {
String query = StdIn.readLine();
if (st.contains(query))
for (String vals : st.get(query))
StdOut.println(" " + vals);
if (ts.contains(query))
for (String keys : ts.get(query))
StdOut.println(" " + keys);
}
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Mon May 23 08:09:39 EDT 2011.
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Fri Mar 23 06:34:05 EDT 2012.

FileIndex.java
Below is the syntax highlighted version
of FileIndex.java from 3.5 Searching Applications.

/
***********************************************************
**************
* Compilation: javac FileIndex.java
* Execution:
java FileIndex file1.txt file2.txt
file3.txt ...
* Dependencies: ST.java SET.java In.java StdIn.java
StdOut.java
* Data files:
http://algs4.cs.princeton.edu/35applications/ex1.txt
*
http://algs4.cs.princeton.edu/35applications/ex2.txt

*
http://algs4.cs.princeton.edu/35applications/ex3.txt
*
http://algs4.cs.princeton.edu/35applications/ex4.txt
*
* % java FileIndex ex*.txt
* age
*
ex3.txt
*
ex4.txt
* best
*
ex1.txt
* was
*
ex1.txt
*
ex2.txt
*
ex3.txt
*
ex4.txt
*
* % java FileIndex *.txt
*
* % java FileIndex *.java
*
***********************************************************
**************/
import java.io.File;
public class FileIndex {
public static void main(String[] args) {
// key = word, value = set of files containing that
word
ST<String, SET<File>> st = new ST<String,
SET<File>>();
// create inverted index of all files
StdOut.println("Indexing files");
for (String filename : args) {
StdOut.println(" " + filename);
File file = new File(filename);
In in = new In(file);
while (!in.isEmpty()) {
String word = in.readString();
if (!st.contains(word)) st.put(word, new
SET<File>());
SET<File> set = st.get(word);

set.add(file);
}
}
// read queries from standard input, one per line
while (!StdIn.isEmpty()) {
String query = StdIn.readString();
if (st.contains(query)) {
SET<File> set = st.get(query);
for (File file : set) {
StdOut.println(" " + file.getName());
}
}
}
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Sat Aug 11 17:39:20 EDT 2012.

SparseVector.java
Below is the syntax highlighted version
of SparseVector.java from 3.5 Searching Applications.
Here is the Javadoc.

/
***********************************************************
**************
* Compilation: javac SparseVector.java
* Execution:
java SparseVector
* Dependencies: StdOut.java
*
* A sparse vector, implementing using a symbol table.
*
* [Not clear we need the instance variable N except for
error checking.]

*
***********************************************************
**************/
public class SparseVector {
private int N;
private ST<Integer, Double> st;
represented by index-value pairs

// length
// the vector,

// initialize the all 0s vector of length N


public SparseVector(int N) {
this.N = N;
this.st = new ST<Integer, Double>();
}
// put st[i] = value
public void put(int i, double value) {
if (i < 0 || i >= N) throw new
IndexOutOfBoundsException("Illegal index");
if (value == 0.0) st.delete(i);
else
st.put(i, value);
}
// return st[i]
public double get(int i) {
if (i < 0 || i >= N) throw
IndexOutOfBoundsException("Illegal
if (st.contains(i)) return
else
return
}

new
index");
st.get(i);
0.0;

// return the number of nonzero entries


public int nnz() {
return st.size();
}
// return the size of the vector
public int size() {
return N;
}
// return the dot product of this vector with that
vector
public double dot(SparseVector that) {
if (this.N != that.N) throw new
IllegalArgumentException("Vector lengths disagree");

double sum = 0.0;


// iterate over the vector with the fewest nonzeros
if (this.st.size() <= that.st.size()) {
for (int i : this.st.keys())
if (that.st.contains(i)) sum += this.get(i)
* that.get(i);
}
else {
for (int i : that.st.keys())
if (this.st.contains(i)) sum += this.get(i)
* that.get(i);
}
return sum;
}
// return the dot product of this vector and that array
public double dot(double[] that) {
double sum = 0.0;
for (int i : st.keys())
sum += that[i] * this.get(i);
return sum;
}
// return the 2-norm
public double norm() {
SparseVector a = this;
return Math.sqrt(a.dot(a));
}
// return alpha * this
public SparseVector scale(double alpha) {
SparseVector c = new SparseVector(N);
for (int i : this.st.keys()) c.put(i, alpha *
this.get(i));
return c;
}
// return this + that
public SparseVector plus(SparseVector that) {
if (this.N != that.N) throw new
IllegalArgumentException("Vector lengths disagree");
SparseVector c = new SparseVector(N);
for (int i : this.st.keys()) c.put(i, this.get(i));
// c = this

for (int i : that.st.keys()) c.put(i, that.get(i) +


c.get(i));
// c = c + that
return c;
}
// return a string representation
public String toString() {
StringBuilder s = new StringBuilder();
for (int i : st.keys()) {
s.append("(" + i + ", " + st.get(i) + ") ");
}
return s.toString();
}
// test client
public static void main(String[] args) {
SparseVector a = new SparseVector(10);
SparseVector b = new SparseVector(10);
a.put(3, 0.50);
a.put(9, 0.75);
a.put(6, 0.11);
a.put(6, 0.00);
b.put(3, 0.60);
b.put(4, 0.90);
StdOut.println("a = " + a);
StdOut.println("b = " + b);
StdOut.println("a dot b = " + a.dot(b));
StdOut.println("a + b
= " + a.plus(b));
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Tue Jul 28 07:14:41 EDT 2015.

Graph.java
Below is the syntax highlighted version of Graph.java from
Algorithms.
Here is the Javadoc.

/
***********************************************************
**************
* Compilation: javac Graph.java
* Execution:
java Graph input.txt
* Dependencies: Bag.java In.java StdOut.java
* Data files:
http://algs4.cs.princeton.edu/41undirected/tinyG.txt
*
* A graph, implemented using an array of sets.
* Parallel edges and self-loops allowed.
*
* % java Graph tinyG.txt
* 13 vertices, 13 edges
* 0: 6 2 1 5
* 1: 0
* 2: 0

* 3: 5 4
* 4: 5 6 3
* 5: 3 4 0
* 6: 0 4
* 7: 8
* 8: 7
* 9: 11 10 12
* 10: 9
* 11: 9 12
* 12: 11 9
*
* % java Graph mediumG.txt
* 250 vertices, 1273 edges
* 0: 225 222 211 209 204 202 191 176 163 160 149 114 97
80 68 59 58 49 44 24 15
* 1: 220 203 200 194 189 164 150 130 107 72
* 2: 141 110 108 86 79 51 42 18 14
* ...
*
***********************************************************
**************/
/**
* The <tt>Graph</tt> class represents an undirected graph
of vertices
* named 0 through <em>V</em> - 1.
* It supports the following two primary operations: add
an edge to the graph,
* iterate over all of the vertices adjacent to a vertex.
It also provides
* methods for returning the number of vertices <em>V</em>
and the number
* of edges <em>E</em>. Parallel edges and self-loops are
permitted.
* <p>
* 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.
* <p>

* For additional documentation, see <a


href="http://algs4.cs.princeton.edu/41undirected">Section
4.1</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class Graph {
private static final String NEWLINE =
System.getProperty("line.separator");
private final int V;
private int E;
private Bag<Integer>[] adj;
/**
* Initializes an empty graph with <tt>V</tt> vertices
and 0 edges.
* param V the number of vertices
* @throws java.lang.IllegalArgumentException if
<tt>V</tt> < 0
*/
public Graph(int V) {
if (V < 0) throw new
IllegalArgumentException("Number of vertices must be
nonnegative");
this.V = V;
this.E = 0;
adj = (Bag<Integer>[]) new Bag[V];
for (int v = 0; v < V; v++) {
adj[v] = new Bag<Integer>();
}
}
/**
* Initializes a graph from an input stream.
* The format is the number of vertices <em>V</em>,
* followed by the number of edges <em>E</em>,
* followed by <em>E</em> pairs of vertices, with each
entry separated by whitespace.
* @param in the input stream
* @throws java.lang.IndexOutOfBoundsException if the
endpoints of any edge are not in prescribed range
* @throws java.lang.IllegalArgumentException if the
number of vertices or edges is negative

*/
public Graph(In in) {
this(in.readInt());
int E = in.readInt();
if (E < 0) throw new
IllegalArgumentException("Number of edges must be
nonnegative");
for (int i = 0; i < E; i++) {
int v = in.readInt();
int w = in.readInt();
addEdge(v, w);
}
}
/**
* Initializes a new graph that is a deep copy of
<tt>G</tt>.
* @param G the graph to copy
*/
public Graph(Graph G) {
this(G.V());
this.E = G.E();
for (int v = 0; v < G.V(); v++) {
// reverse so that adjacency list is in same
order as original
Stack<Integer> reverse = new Stack<Integer>();
for (int w : G.adj[v]) {
reverse.push(w);
}
for (int w : reverse) {
adj[v].add(w);
}
}
}
/**
* Returns
* @return
*/
public int
return
}

the number of vertices in the graph.


the number of vertices in the graph
V() {
V;

/**
* Returns the number of edges in the graph.
* @return the number of edges in the graph
*/

public int E() {


return E;
}
// throw an IndexOutOfBoundsException unless 0 <= v < V
private void validateVertex(int v) {
if (v < 0 || v >= V)
throw new IndexOutOfBoundsException("vertex " +
v + " is not between 0 and " + (V-1));
}
/**
* Adds the undirected edge v-w to the graph.
* @param v one vertex in the edge
* @param w the other vertex in the edge
* @throws java.lang.IndexOutOfBoundsException unless
both 0 <= v < V and 0 <= w < V
*/
public void addEdge(int v, int w) {
validateVertex(v);
validateVertex(w);
E++;
adj[v].add(w);
adj[w].add(v);
}
/**
* Returns the vertices adjacent to vertex <tt>v</tt>.
* @param v the vertex
* @return the vertices adjacent to vertex <tt>v</tt>
as an Iterable
* @throws java.lang.IndexOutOfBoundsException unless 0
<= v < V
*/
public Iterable<Integer> adj(int v) {
validateVertex(v);
return adj[v];
}
/**
* Returns the degree of vertex <tt>v</tt>.
* @param v the vertex
* @return the degree of vertex <tt>v</tt>
* @throws java.lang.IndexOutOfBoundsException unless 0
<= v < V
*/

public int degree(int v) {


validateVertex(v);
return adj[v].size();
}
/**
* Returns a string representation of the graph.
* This method takes time proportional to <em>E</em> +
<em>V</em>.
* @return the number of vertices <em>V</em>, followed
by the number of edges <em>E</em>,
*
followed by the <em>V</em> adjacency lists
*/
public String toString() {
StringBuilder s = new StringBuilder();
s.append(V + " vertices, " + E + " edges " +
NEWLINE);
for (int v = 0; v < V; v++) {
s.append(v + ": ");
for (int w : adj[v]) {
s.append(w + " ");
}
s.append(NEWLINE);
}
return s.toString();
}
/**
* Unit tests the <tt>Graph</tt> data type.
*/
public static void main(String[] args) {
In in = new In(args[0]);
Graph G = new Graph(in);
StdOut.println(G);
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Sun Jul 26 11:21:27 EDT 2015.

GraphGenerator.java
Below is the syntax highlighted version
of GraphGenerator.java from 4.1 Undirected Graphs.
is the Javadoc.

Here

/
***********************************************************
**************
* Compilation: javac GraphGenerator.java
* Execution:
java GraphGenerator V E
* Dependencies: Graph.java
*
* A graph generator.
*
* For many more graph generators, see
*
http://networkx.github.io/documentation/latest/reference/gen
erators.html
*
***********************************************************
**************/

/**
* The <tt>GraphGenerator</tt> class provides static
methods for creating
* various graphs, including Erdos-Renyi random graphs,
random bipartite
* graphs, random k-regular graphs, and random rooted
trees.
* <p>
* For additional documentation, see <a
href="http://algs4.cs.princeton.edu/41undirected">Section
4.1</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class GraphGenerator {
private static final class Edge implements
Comparable<Edge> {
private int v;
private int w;
private Edge(int
if (v < w) {
this.v =
this.w =
}
else {
this.v =
this.w =
}
}

v, int w) {
v;
w;
w;
v;

public int compareTo(Edge that)


if (this.v < that.v) return
if (this.v > that.v) return
if (this.w < that.w) return
if (this.w > that.w) return
return 0;
}

{
-1;
+1;
-1;
+1;

}
/**
* Returns a random simple graph containing <tt>V</tt>
vertices and <tt>E</tt> edges.

* @param V the number of vertices


* @param E the number of vertices
* @return a random simple graph on <tt>V</tt>
vertices, containing a total
*
of <tt>E</tt> edges
* @throws IllegalArgumentException if no such simple
graph exists
*/
public static Graph simple(int V, int E) {
if (E > (long) V*(V-1)/2) throw new
IllegalArgumentException("Too many edges");
if (E < 0)
throw new
IllegalArgumentException("Too few edges");
Graph G = new Graph(V);
SET<Edge> set = new SET<Edge>();
while (G.E() < E) {
int v = StdRandom.uniform(V);
int w = StdRandom.uniform(V);
Edge e = new Edge(v, w);
if ((v != w) && !set.contains(e)) {
set.add(e);
G.addEdge(v, w);
}
}
return G;
}
/**
* Returns a random simple graph on <tt>V</tt>
vertices, with an
* edge between any two vertices with probability
<tt>p</tt>. This is sometimes
* referred to as the Erdos-Renyi random graph model.
* @param V the number of vertices
* @param p the probability of choosing an edge
* @return a random simple graph on <tt>V</tt>
vertices, with an edge between
*
any two vertices with probability <tt>p</tt>
* @throws IllegalArgumentException if probability is
not between 0 and 1
*/
public static Graph simple(int V, double p) {
if (p < 0.0 || p > 1.0)
throw new IllegalArgumentException("Probability
must be between 0 and 1");
Graph G = new Graph(V);
for (int v = 0; v < V; v++)

for (int w = v+1; w < V; w++)


if (StdRandom.bernoulli(p))
G.addEdge(v, w);
return G;
}
/**
* Returns the complete graph on <tt>V</tt> vertices.
* @param V the number of vertices
* @return the complete graph on <tt>V</tt> vertices
*/
public static Graph complete(int V) {
return simple(V, 1.0);
}
/**
* Returns a complete bipartite graph on <tt>V1</tt>
and <tt>V2</tt> vertices.
* @param V1 the number of vertices in one partition
* @param V2 the number of vertices in the other
partition
* @return a complete bipartite graph on <tt>V1</tt>
and <tt>V2</tt> vertices
* @throws IllegalArgumentException if probability is
not between 0 and 1
*/
public static Graph completeBipartite(int V1, int V2) {
return bipartite(V1, V2, V1*V2);
}
/**
* Returns a random simple bipartite graph on
<tt>V1</tt> and <tt>V2</tt> vertices
* with <tt>E</tt> edges.
* @param V1 the number of vertices in one partition
* @param V2 the number of vertices in the other
partition
* @param E the number of edges
* @return a random simple bipartite graph on
<tt>V1</tt> and <tt>V2</tt> vertices,
*
containing a total of <tt>E</tt> edges
* @throws IllegalArgumentException if no such simple
bipartite graph exists
*/
public static Graph bipartite(int V1, int V2, int E) {
if (E > (long) V1*V2) throw new
IllegalArgumentException("Too many edges");

if (E < 0)
throw new
IllegalArgumentException("Too few edges");
Graph G = new Graph(V1 + V2);
int[] vertices = new int[V1 + V2];
for (int i = 0; i < V1 + V2; i++)
vertices[i] = i;
StdRandom.shuffle(vertices);
SET<Edge> set = new SET<Edge>();
while (G.E() < E) {
int i = StdRandom.uniform(V1);
int j = V1 + StdRandom.uniform(V2);
Edge e = new Edge(vertices[i], vertices[j]);
if (!set.contains(e)) {
set.add(e);
G.addEdge(vertices[i], vertices[j]);
}
}
return G;
}
/**
* Returns a random simple bipartite graph on
<tt>V1</tt> and <tt>V2</tt> vertices,
* containing each possible edge with probability
<tt>p</tt>.
* @param V1 the number of vertices in one partition
* @param V2 the number of vertices in the other
partition
* @param p the probability that the graph contains an
edge with one endpoint in either side
* @return a random simple bipartite graph on
<tt>V1</tt> and <tt>V2</tt> vertices,
*
containing each possible edge with probability
<tt>p</tt>
* @throws IllegalArgumentException if probability is
not between 0 and 1
*/
public static Graph bipartite(int V1, int V2, double p)
{
if (p < 0.0 || p > 1.0)
throw new IllegalArgumentException("Probability
must be between 0 and 1");
int[] vertices = new int[V1 + V2];
for (int i = 0; i < V1 + V2; i++)
vertices[i] = i;

StdRandom.shuffle(vertices);
Graph G = new Graph(V1 + V2);
for (int i = 0; i < V1; i++)
for (int j = 0; j < V2; j++)
if (StdRandom.bernoulli(p))
G.addEdge(vertices[i], vertices[V1+j]);
return G;
}
/**
* Returns a path graph on <tt>V</tt> vertices.
* @param V the number of vertices in the path
* @return a path graph on <tt>V</tt> vertices
*/
public static Graph path(int V) {
Graph G = new Graph(V);
int[] vertices = new int[V];
for (int i = 0; i < V; i++)
vertices[i] = i;
StdRandom.shuffle(vertices);
for (int i = 0; i < V-1; i++) {
G.addEdge(vertices[i], vertices[i+1]);
}
return G;
}
/**
* Returns a complete binary tree graph on <tt>V</tt>
vertices.
* @param V the number of vertices in the binary tree
* @return a complete binary tree graph on <tt>V</tt>
vertices
*/
public static Graph binaryTree(int V) {
Graph G = new Graph(V);
int[] vertices = new int[V];
for (int i = 0; i < V; i++)
vertices[i] = i;
StdRandom.shuffle(vertices);
for (int i = 1; i < V; i++) {
G.addEdge(vertices[i], vertices[(i-1)/2]);
}
return G;
}
/**
* Returns a cycle graph on <tt>V</tt> vertices.

* @param V the number of vertices in the cycle


* @return a cycle graph on <tt>V</tt> vertices
*/
public static Graph cycle(int V) {
Graph G = new Graph(V);
int[] vertices = new int[V];
for (int i = 0; i < V; i++)
vertices[i] = i;
StdRandom.shuffle(vertices);
for (int i = 0; i < V-1; i++) {
G.addEdge(vertices[i], vertices[i+1]);
}
G.addEdge(vertices[V-1], vertices[0]);
return G;
}
/**
* Returns a wheel graph on <tt>V</tt> vertices.
* @param V the number of vertices in the wheel
* @return a wheel graph on <tt>V</tt> vertices: a
single vertex connected to
*
every vertex in a cycle on <tt>V-1</tt> vertices
*/
public static Graph wheel(int V) {
if (V <= 1) throw new
IllegalArgumentException("Number of vertices must be at
least 2");
Graph G = new Graph(V);
int[] vertices = new int[V];
for (int i = 0; i < V; i++)
vertices[i] = i;
StdRandom.shuffle(vertices);
// simple cycle on V-1 vertices
for (int i = 1; i < V-1; i++) {
G.addEdge(vertices[i], vertices[i+1]);
}
G.addEdge(vertices[V-1], vertices[1]);
// connect vertices[0] to every vertex on cycle
for (int i = 1; i < V; i++) {
G.addEdge(vertices[0], vertices[i]);
}
return G;
}

/**
* Returns a star graph on <tt>V</tt> vertices.
* @param V the number of vertices in the star
* @return a star graph on <tt>V</tt> vertices: a
single vertex connected to
*
every other vertex
*/
public static Graph star(int V) {
if (V <= 0) throw new
IllegalArgumentException("Number of vertices must be at
least 1");
Graph G = new Graph(V);
int[] vertices = new int[V];
for (int i = 0; i < V; i++)
vertices[i] = i;
StdRandom.shuffle(vertices);
// connect vertices[0] to every other vertex
for (int i = 1; i < V; i++) {
G.addEdge(vertices[0], vertices[i]);
}
return G;
}
/**
* Returns a uniformly random <tt>k</tt>-regular graph
on <tt>V</tt> vertices
* (not necessarily simple). The graph is simple with
probability only about e^(-k^2/4),
* which is tiny when k = 14.
* @param V the number of vertices in the graph
* @return a uniformly random <tt>k</tt>-regular graph
on <tt>V</tt> vertices.
*/
public static Graph regular(int V, int k) {
if (V*k % 2 != 0) throw new
IllegalArgumentException("Number of vertices * k must be
even");
Graph G = new Graph(V);
// create k copies of each vertex
int[] vertices = new int[V*k];
for (int v = 0; v < V; v++) {
for (int j = 0; j < k; j++) {
vertices[v + V*j] = v;
}

}
// pick a random perfect matching
StdRandom.shuffle(vertices);
for (int i = 0; i < V*k/2; i++) {
G.addEdge(vertices[2*i], vertices[2*i + 1]);
}
return G;
}
//
http://www.proofwiki.org/wiki/Labeled_Tree_from_Prfer_Sequ
ence
// http://citeseerx.ist.psu.edu/viewdoc/download?
doi=10.1.1.36.6484&rep=rep1&type=pdf
/**
* Returns a uniformly random tree on <tt>V</tt>
vertices.
* This algorithm uses a Prufer sequence and takes time
proportional to <em>V log V</em>.
* @param V the number of vertices in the tree
* @return a uniformly random tree on <tt>V</tt>
vertices
*/
public static Graph tree(int V) {
Graph G = new Graph(V);
// special case
if (V == 1) return G;
// Cayley's theorem: there are V^(V-2) labeled
trees on V vertices
// Prufer sequence: sequence of V-2 values between
0 and V-1
// Prufer's proof of Cayley's theorem: Prufer
sequences are in 1-1
// with labeled trees on V vertices
int[] prufer = new int[V-2];
for (int i = 0; i < V-2; i++)
prufer[i] = StdRandom.uniform(V);
// degree of vertex v = 1 + number of times it
appers in Prufer sequence
int[] degree = new int[V];
for (int v = 0; v < V; v++)
degree[v] = 1;
for (int i = 0; i < V-2; i++)

degree[prufer[i]]++;
// pq contains all vertices of degree 1
MinPQ<Integer> pq = new MinPQ<Integer>();
for (int v = 0; v < V; v++)
if (degree[v] == 1) pq.insert(v);
// repeatedly delMin() degree 1 vertex that has the
minimum index
for (int i = 0; i < V-2; i++) {
int v = pq.delMin();
G.addEdge(v, prufer[i]);
degree[v]--;
degree[prufer[i]]--;
if (degree[prufer[i]] == 1)
pq.insert(prufer[i]);
}
G.addEdge(pq.delMin(), pq.delMin());
return G;
}
/**
* Unit tests the <tt>GraphGenerator</tt> library.
*/
public static void main(String[] args) {
int V = Integer.parseInt(args[0]);
int E = Integer.parseInt(args[1]);
int V1 = V/2;
int V2 = V - V1;
StdOut.println("complete graph");
StdOut.println(complete(V));
StdOut.println();
StdOut.println("simple");
StdOut.println(simple(V, E));
StdOut.println();
StdOut.println("Erdos-Renyi");
double p = (double) E / (V*(V-1)/2.0);
StdOut.println(simple(V, p));
StdOut.println();
StdOut.println("complete bipartite");
StdOut.println(completeBipartite(V1, V2));
StdOut.println();

StdOut.println("bipartite");
StdOut.println(bipartite(V1, V2, E));
StdOut.println();
StdOut.println("Erdos Renyi bipartite");
double q = (double) E / (V1*V2);
StdOut.println(bipartite(V1, V2, q));
StdOut.println();
StdOut.println("path");
StdOut.println(path(V));
StdOut.println();
StdOut.println("cycle");
StdOut.println(cycle(V));
StdOut.println();
StdOut.println("binary tree");
StdOut.println(binaryTree(V));
StdOut.println();
StdOut.println("tree");
StdOut.println(tree(V));
StdOut.println();
StdOut.println("4-regular");
StdOut.println(regular(V, 4));
StdOut.println();
StdOut.println("star");
StdOut.println(star(V));
StdOut.println();
StdOut.println("wheel");
StdOut.println(wheel(V));
StdOut.println();
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Thu Jul 23 17:05:46 EDT 2015.

DepthFirstSearch.java
Below is the syntax highlighted version
of DepthFirstSearch.java from 4.1 Undirected Graphs.
is the Javadoc.

Here

/
***********************************************************
**************
* Compilation: javac DepthFirstSearch.java
* Execution:
java DepthFirstSearch filename.txt s
* Dependencies: Graph.java StdOut.java
* Data files:
http://algs4.cs.princeton.edu/41undirected/tinyG.txt
*
* Run depth first search on an undirected graph.
* Runs in O(E + V) time.
*
* % java DepthFirstSearch tinyG.txt 0
* 0 1 2 3 4 5 6
* NOT connected
*
* % java DepthFirstSearch tinyG.txt 9

*
*
*

9 10 11 12
NOT connected

***********************************************************
**************/
/**
* The <tt>DepthFirstSearch</tt> class represents a data
type for
* determining the vertices connected to a given source
vertex <em>s</em>
* in an undirected graph. For versions that find the
paths, see
* {@link DepthFirstPaths} and {@link BreadthFirstPaths}.
* <p>
* This implementation uses depth-first search.
* The constructor takes time proportional to <em>V</em> +
<em>E</em>
* (in the worst case),
* where <em>V</em> is the number of vertices and
<em>E</em> is the number of edges.
* It uses extra space (not including the graph)
proportional to <em>V</em>.
* <p>
* For additional documentation, see <a
href="/algs4/41graph">Section 4.1</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class DepthFirstSearch {
private boolean[] marked;
// marked[v] = is there an
s-v path?
private int count;
// number of vertices
connected to s
/**
* Computes the vertices in graph <tt>G</tt> that are
* connected to the source vertex <tt>s</tt>.
* @param G the graph
* @param s the source vertex
*/
public DepthFirstSearch(Graph G, int s) {
marked = new boolean[G.V()];

dfs(G, s);
}
// depth first search from v
private void dfs(Graph G, int v) {
count++;
marked[v] = true;
for (int w : G.adj(v)) {
if (!marked[w]) {
dfs(G, w);
}
}
}
/**
* Is there a path between the source vertex <tt>s</tt>
and vertex <tt>v</tt>?
* @param v the vertex
* @return <tt>true</tt> if there is a path,
<tt>false</tt> otherwise
*/
public boolean marked(int v) {
return marked[v];
}
/**
* Returns the number of vertices connected to the
source vertex <tt>s</tt>.
* @return the number of vertices connected to the
source vertex <tt>s</tt>
*/
public int count() {
return count;
}
/**
* Unit tests the <tt>DepthFirstSearch</tt> data type.
*/
public static void main(String[] args) {
In in = new In(args[0]);
Graph G = new Graph(in);
int s = Integer.parseInt(args[1]);
DepthFirstSearch search = new DepthFirstSearch(G,
s);
for (int v = 0; v < G.V(); v++) {
if (search.marked(v))
StdOut.print(v + " ");

}
StdOut.println();
if (search.count() != G.V()) StdOut.println("NOT
connected");
else
StdOut.println("connected");
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Thu Oct 24 15:59:37 EDT 2013.

DepthFirstPaths.java
Below is the syntax highlighted version
of DepthFirstPaths.java from 4.1 Undirected Graphs.
is the Javadoc.

Here

/
***********************************************************
**************
* Compilation: javac DepthFirstPaths.java
* Execution:
java DepthFirstPaths G s
* Dependencies: Graph.java Stack.java StdOut.java
* Data files:
http://algs4.cs.princeton.edu/41undirected/tinyCG.txt
*
* Run depth first search on an undirected graph.
* Runs in O(E + V) time.
*
* % 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
0
0
0
0
0

java DepthFirstPaths tinyCG.txt 0


to 0: 0
to 1: 0-2-1
to 2: 0-2
to 3: 0-2-3
to 4: 0-2-3-4
to 5: 0-2-3-5

***********************************************************
**************/
/**
* The <tt>DepthFirstPaths</tt> class represents a data
type for finding
* paths from a source vertex <em>s</em> to every other
vertex
* in an undirected graph.
* <p>
* This implementation uses depth-first search.
* The constructor takes time proportional to <em>V</em> +
<em>E</em>,
* where <em>V</em> is the number of vertices and
<em>E</em> is the number of edges.
* It uses extra space (not including the graph)
proportional to <em>V</em>.
* <p>
* For additional documentation, see <a
href="/algs4/41graph">Section 4.1</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class DepthFirstPaths {
private boolean[] marked;
// marked[v] = is there an
s-v path?
private int[] edgeTo;
// edgeTo[v] = last edge
on s-v path
private final int s;
// source vertex
/**

* Computes a path between <tt>s</tt> and every other


vertex in graph <tt>G</tt>.
* @param G the graph
* @param s the source vertex
*/
public DepthFirstPaths(Graph G, int s) {
this.s = s;
edgeTo = new int[G.V()];
marked = new boolean[G.V()];
dfs(G, s);
}
// depth first search from v
private void dfs(Graph G, int v) {
marked[v] = true;
for (int w : G.adj(v)) {
if (!marked[w]) {
edgeTo[w] = v;
dfs(G, w);
}
}
}
/**
* Is there a path between the source vertex <tt>s</tt>
and vertex <tt>v</tt>?
* @param v the vertex
* @return <tt>true</tt> if there is a path,
<tt>false</tt> otherwise
*/
public boolean hasPathTo(int v) {
return marked[v];
}
/**
* Returns a path between the source vertex <tt>s</tt>
and vertex <tt>v</tt>, or
* <tt>null</tt> if no such path.
* @param v the vertex
* @return the sequence of vertices on a path between
the source vertex
*
<tt>s</tt> and vertex <tt>v</tt>, as an Iterable
*/
public Iterable<Integer> pathTo(int v) {
if (!hasPathTo(v)) return null;
Stack<Integer> path = new Stack<Integer>();
for (int x = v; x != s; x = edgeTo[x])

path.push(x);
path.push(s);
return path;
}
/**
* Unit tests the <tt>DepthFirstPaths</tt> data type.
*/
public static void main(String[] args) {
In in = new In(args[0]);
Graph G = new Graph(in);
int s = Integer.parseInt(args[1]);
DepthFirstPaths dfs = new DepthFirstPaths(G, s);
for (int v = 0; v < G.V(); v++) {
if (dfs.hasPathTo(v)) {
StdOut.printf("%d to %d: ", s, v);
for (int x : dfs.pathTo(v)) {
if (x == s) StdOut.print(x);
else
StdOut.print("-" + x);
}
StdOut.println();
}
else {
StdOut.printf("%d to %d:

not connected\n",

s, v);
}
}
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Thu Oct 24 15:59:37 EDT 2013.

BreadthFirstPaths.java
Below is the syntax highlighted version
of BreadthFirstPaths.java from 4.1 Undirected Graphs.
Here is the Javadoc.

/
***********************************************************
**************
* Compilation: javac BreadthFirstPaths.java
* Execution:
java BreadthFirstPaths G s
* Dependencies: Graph.java Queue.java Stack.java
StdOut.java
* Data files:
http://algs4.cs.princeton.edu/41undirected/tinyCG.txt
*
* Run breadth first search on an undirected graph.
* Runs in O(E + V) time.
*
* % 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
0
0
0
0
0

java BreadthFirstPaths tinyCG.txt 0


to 0 (0): 0
to 1 (1): 0-1
to 2 (1): 0-2
to 3 (2): 0-2-3
to 4 (2): 0-2-4
to 5 (1): 0-5

%
0
0
0
0
0
0
0

java BreadthFirstPaths largeG.txt 0


to 0 (0): 0
to 1 (418): 0-932942-474885-82707-879889-971961-...
to 2 (323): 0-460790-53370-594358-780059-287921-...
to 3 (168): 0-713461-75230-953125-568284-350405-...
to 4 (144): 0-460790-53370-310931-440226-380102-...
to 5 (566): 0-932942-474885-82707-879889-971961-...
to 6 (349): 0-932942-474885-82707-879889-971961-...

***********************************************************
**************/
/**
* The <tt>BreadthFirstPaths</tt> class represents a data
type for finding
* shortest paths (number of edges) from a source vertex
<em>s</em>
* (or a set of source vertices)
* to every other vertex in an undirected graph.
* <p>
* This implementation uses breadth-first search.
* The constructor takes time proportional to <em>V</em> +
<em>E</em>,
* where <em>V</em> is the number of vertices and
<em>E</em> is the number of edges.
* It uses extra space (not including the graph)
proportional to <em>V</em>.
* <p>
* For additional documentation, see <a
href="/algs4/41graph">Section 4.1</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/

public class BreadthFirstPaths {


private static final int INFINITY = Integer.MAX_VALUE;
private boolean[] marked; // marked[v] = is there an
s-v path
private int[] edgeTo;
// edgeTo[v] = previous edge
on shortest s-v path
private int[] distTo;
// distTo[v] = number of
edges shortest s-v path
/**
* Computes the shortest path between the source vertex
<tt>s</tt>
* and every other vertex in the graph <tt>G</tt>.
* @param G the graph
* @param s the source vertex
*/
public BreadthFirstPaths(Graph G, int s) {
marked = new boolean[G.V()];
distTo = new int[G.V()];
edgeTo = new int[G.V()];
bfs(G, s);
assert check(G, s);
}
/**
* Computes the shortest path between any one of the
source vertices in <tt>sources</tt>
* and every other vertex in graph <tt>G</tt>.
* @param G the graph
* @param sources the source vertices
*/
public BreadthFirstPaths(Graph G, Iterable<Integer>
sources) {
marked = new boolean[G.V()];
distTo = new int[G.V()];
edgeTo = new int[G.V()];
for (int v = 0; v < G.V(); v++)
distTo[v] = INFINITY;
bfs(G, sources);
}
// breadth-first search from a single source
private void bfs(Graph G, int s) {
Queue<Integer> q = new Queue<Integer>();
for (int v = 0; v < G.V(); v++)

distTo[v] = INFINITY;
distTo[s] = 0;
marked[s] = true;
q.enqueue(s);
while (!q.isEmpty()) {
int v = q.dequeue();
for (int w : G.adj(v)) {
if (!marked[w]) {
edgeTo[w] = v;
distTo[w] = distTo[v] + 1;
marked[w] = true;
q.enqueue(w);
}
}
}
}
// breadth-first search from multiple sources
private void bfs(Graph G, Iterable<Integer> sources) {
Queue<Integer> q = new Queue<Integer>();
for (int s : sources) {
marked[s] = true;
distTo[s] = 0;
q.enqueue(s);
}
while (!q.isEmpty()) {
int v = q.dequeue();
for (int w : G.adj(v)) {
if (!marked[w]) {
edgeTo[w] = v;
distTo[w] = distTo[v] + 1;
marked[w] = true;
q.enqueue(w);
}
}
}
}
/**
* Is there a path between the source vertex <tt>s</tt>
(or sources) and vertex <tt>v</tt>?
* @param v the vertex
* @return <tt>true</tt> if there is a path, and
<tt>false</tt> otherwise
*/
public boolean hasPathTo(int v) {

return marked[v];
}
/**
* Returns the number of edges in a shortest path
between the source vertex <tt>s</tt>
* (or sources) and vertex <tt>v</tt>?
* @param v the vertex
* @return the number of edges in a shortest path
*/
public int distTo(int v) {
return distTo[v];
}
/**
* Returns a shortest path between the source vertex
<tt>s</tt> (or sources)
* and <tt>v</tt>, or <tt>null</tt> if no such path.
* @param v the vertex
* @return the sequence of vertices on a shortest path,
as an Iterable
*/
public Iterable<Integer> pathTo(int v) {
if (!hasPathTo(v)) return null;
Stack<Integer> path = new Stack<Integer>();
int x;
for (x = v; distTo[x] != 0; x = edgeTo[x])
path.push(x);
path.push(x);
return path;
}
// check optimality conditions for single source
private boolean check(Graph G, int s) {
// check that the distance of s = 0
if (distTo[s] != 0) {
StdOut.println("distance of source " + s + " to
itself = " + distTo[s]);
return false;
}
// check that for each edge v-w dist[w] <= dist[v]
+ 1
// provided v is reachable from s
for (int v = 0; v < G.V(); v++) {

for (int w : G.adj(v)) {


if (hasPathTo(v) != hasPathTo(w)) {
StdOut.println("edge " + v + "-" + w);
StdOut.println("hasPathTo(" + v + ") = "
+ hasPathTo(v));
StdOut.println("hasPathTo(" + w + ") = "
+ hasPathTo(w));
return false;
}
if (hasPathTo(v) && (distTo[w] > distTo[v] +
1)) {
StdOut.println("edge " + v + "-" + w);
StdOut.println("distTo[" + v + "] = " +
distTo[v]);
StdOut.println("distTo[" + w + "] = " +
distTo[w]);
return false;
}
}
}
// check that v = edgeTo[w] satisfies distTo[w] +
distTo[v] + 1
// provided v is reachable from s
for (int w = 0; w < G.V(); w++) {
if (!hasPathTo(w) || w == s) continue;
int v = edgeTo[w];
if (distTo[w] != distTo[v] + 1) {
StdOut.println("shortest path edge " + v +
"-" + w);
StdOut.println("distTo[" + v + "] = " +
distTo[v]);
StdOut.println("distTo[" + w + "] = " +
distTo[w]);
return false;
}
}
return true;
}
/**
* Unit tests the <tt>BreadthFirstPaths</tt> data type.
*/
public static void main(String[] args) {
In in = new In(args[0]);
Graph G = new Graph(in);

// StdOut.println(G);
int s = Integer.parseInt(args[1]);
BreadthFirstPaths bfs = new BreadthFirstPaths(G, s);
for (int v = 0; v < G.V(); v++) {
if (bfs.hasPathTo(v)) {
StdOut.printf("%d to %d (%d): ", s, v,
bfs.distTo(v));
for (int x : bfs.pathTo(v)) {
if (x == s) StdOut.print(x);
else
StdOut.print("-" + x);
}
StdOut.println();
}
else {
StdOut.printf("%d to %d (-):
connected\n", s, v);
}

not

}
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Thu Jul 23 17:05:46 EDT 2015.

CC.java
Below is the syntax highlighted version of CC.java from 4.1
Undirected Graphs.
Here is the Javadoc.

/
***********************************************************
**************
* Compilation: javac CC.java
* Execution:
java CC filename.txt
* Dependencies: Graph.java StdOut.java Queue.java
* Data files:
http://algs4.cs.princeton.edu/41undirected/tinyG.txt
*
* Compute connected components using depth first search.
* Runs in O(E + V) time.
*
* % java CC tinyG.txt
* 3 components
* 0 1 2 3 4 5 6
* 7 8
* 9 10 11 12
*
* % java CC mediumG.txt
* 1 components
* 0 1 2 3 4 5 6 7 8 9 10 ...
*
* % java -Xss50m CC largeG.txt
* 1 components
* 0 1 2 3 4 5 6 7 8 9 10 ...
*
***********************************************************
**************/

/**
* The <tt>CC</tt> class represents a data type for
* determining the connected components in an undirected
graph.
* The <em>id</em> operation determines in which connected
component
* a given vertex lies; the <em>connected</em> operation
* determines whether two vertices are in the same
connected component;
* the <em>count</em> operation determines the number of
connected
* components; and the <em>size</em> operation determines
the number
* of vertices in the connect component containing a given
vertex.
* The <em>component identifier</em> of a connected
component is one of the
* vertices in the connected component: two vertices have
the same component
* identifier if and only if they are in the same
connected component.
* <p>
* This implementation uses depth-first search.
* The constructor takes time proportional to <em>V</em> +
<em>E</em>
* (in the worst case),
* where <em>V</em> is the number of vertices and
<em>E</em> is the number of edges.
* Afterwards, the <em>id</em>, <em>count</em>,
<em>connected</em>,
* and <em>size</em> operations take constant time.
* <p>
* For additional documentation, see <a
href="/algs4/41graph">Section 4.1</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class CC {
private boolean[] marked;
// marked[v] = has vertex v
been marked?

private int[] id;


component containing v
private int[] size;
vertices in given component
private int count;
components

// id[v] = id of connected
// size[id] = number of
// number of connected

/**
* Computes the connected components of the undirected
graph <tt>G</tt>.
* @param G the graph
*/
public CC(Graph G) {
marked = new boolean[G.V()];
id = new int[G.V()];
size = new int[G.V()];
for (int v = 0; v < G.V(); v++) {
if (!marked[v]) {
dfs(G, v);
count++;
}
}
}
// depth-first search
private void dfs(Graph G, int v) {
marked[v] = true;
id[v] = count;
size[count]++;
for (int w : G.adj(v)) {
if (!marked[w]) {
dfs(G, w);
}
}
}
/**
* Returns the component id of the connected component
containing vertex <tt>v</tt>.
* @param v the vertex
* @return the component id of the connected component
containing vertex <tt>v</tt>
*/
public int id(int v) {
return id[v];
}

/**
* Returns the number of vertices in the connected
component containing vertex <tt>v</tt>.
* @param v the vertex
* @return the number of vertices in the connected
component containing vertex <tt>v</tt>
*/
public int size(int v) {
return size[id[v]];
}
/**
* Returns
* @return
*/
public int
return
}

the number of connected components.


the number of connected components
count() {
count;

/**
* Are vertices <tt>v</tt> and <tt>w</tt> in the same
connected component?
* @param v one vertex
* @param w the other vertex
* @return <tt>true</tt> if vertices <tt>v</tt> and
<tt>w</tt> are in the same
*
connected component, and <tt>false</tt>
otherwise
*/
public boolean connected(int v, int w) {
return id(v) == id(w);
}
/**
* Are vertices <tt>v</tt> and <tt>w</tt> in the same
connected component?
* @param v one vertex
* @param w the other vertex
* @return <tt>true</tt> if vertices <tt>v</tt> and
<tt>w</tt> are in the same
*
connected component, and <tt>false</tt>
otherwise
* @deprecated Use connected(v, w) instead.
*/
public boolean areConnected(int v, int w) {
return id(v) == id(w);
}

/**
* Unit tests the <tt>CC</tt> data type.
*/
public static void main(String[] args) {
In in = new In(args[0]);
Graph G = new Graph(in);
CC cc = new CC(G);
// number of connected components
int M = cc.count();
StdOut.println(M + " components");
// compute list of vertices in each connected
component
Queue<Integer>[] components = (Queue<Integer>[]) new
Queue[M];
for (int i = 0; i < M; i++) {
components[i] = new Queue<Integer>();
}
for (int v = 0; v < G.V(); v++) {
components[cc.id(v)].enqueue(v);
}
// print results
for (int i = 0; i < M; i++) {
for (int v : components[i]) {
StdOut.print(v + " ");
}
StdOut.println();
}
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Fri Apr 4 03:55:03 EDT 2014.

Bipartite.java
Below is the syntax highlighted version
of Bipartite.java from 4.1 Undirected Graphs.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac Bipartite.java
* Execution:
java Bipartite V E F
* Dependencies: Graph.java
*
* Given a graph, find either (i) a bipartition or (ii) an
odd-length cycle.
* Runs in O(E + V) time.
*
*
***********************************************************
**************/
/**
* The <tt>Bipartite</tt> class represents a data type for
* determining whether an undirected graph is bipartite or
whether
* it has an odd-length cycle.
* The <em>isBipartite</em> operation determines whether
the graph is
* bipartite. If so, the <em>color</em> operation
determines a
* bipartition; if not, the <em>oddCycle</em> operation
determines a
* cycle with an odd number of edges.

* <p>
* This implementation uses depth-first search.
* The constructor takes time proportional to <em>V</em> +
<em>E</em>
* (in the worst case),
* where <em>V</em> is the number of vertices and
<em>E</em> is the number of edges.
* Afterwards, the <em>isBipartite</em> and <em>color</em>
operations
* take constant time; the <em>oddCycle</em> operation
takes time proportional
* to the length of the cycle.
* <p>
* For additional documentation, see <a
href="/algs4/41graph">Section 4.1</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class Bipartite {
private boolean isBipartite;
// is the graph
bipartite?
private boolean[] color;
// color[v] gives
vertices on one side of bipartition
private boolean[] marked;
// marked[v] = true if v
has been visited in DFS
private int[] edgeTo;
// edgeTo[v] = last edge
on path to v
private Stack<Integer> cycle; // odd-length cycle
/**
* Determines whether an undirected graph is bipartite
and finds either a
* bipartition or an odd-length cycle.
* @param G the graph
*/
public Bipartite(Graph G) {
isBipartite = true;
color = new boolean[G.V()];
marked = new boolean[G.V()];
edgeTo = new int[G.V()];
for (int v = 0; v < G.V(); v++) {
if (!marked[v]) {
dfs(G, v);

}
}
assert check(G);
}
private void dfs(Graph G, int v) {
marked[v] = true;
for (int w : G.adj(v)) {
// short circuit if odd-length cycle found
if (cycle != null) return;
// found uncolored vertex, so recur
if (!marked[w]) {
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]) {
isBipartite = false;
cycle = new Stack<Integer>();
cycle.push(w); // don't need this unless
you want to include start vertex twice
for (int x = v; x != w; x = edgeTo[x]) {
cycle.push(x);
}
cycle.push(w);
}
}
}
/**
* Is the graph bipartite?
* @return <tt>true</tt> if the graph is bipartite,
<tt>false</tt> otherwise
*/
public boolean isBipartite() {
return isBipartite;
}
/**
* Returns the side of the bipartite that vertex
<tt>v</tt> is on.
* param v the vertex

* @return the side of the bipartition that vertex


<tt>v</tt> is on; two vertices
*
are in the same side of the bipartition if and
only if they have the same color
* @throws UnsupportedOperationException if this method
is called when the graph
*
is not bipartite
*/
public boolean color(int v) {
if (!isBipartite)
throw new UnsupportedOperationException("Graph
is not bipartite");
return color[v];
}
/**
* Returns an odd-length cycle if the graph is not
bipartite, and
* <tt>null</tt> otherwise.
* @return an odd-length cycle (as an iterable) if the
graph is not bipartite
*
(and hence has an odd-length cycle), and
<tt>null</tt> otherwise
*/
public Iterable<Integer> oddCycle() {
return cycle;
}
private boolean check(Graph G) {
// graph is bipartite
if (isBipartite) {
for (int v = 0; v < G.V(); v++) {
for (int w : G.adj(v)) {
if (color[v] == color[w]) {
System.err.printf("edge %d-%d with
%d and %d in same side of bipartition\n", v, w, v, w);
return false;
}
}
}
}
// graph has an odd-length cycle
else {
// verify cycle
int first = -1, last = -1;
for (int v : oddCycle()) {

if (first == -1) first = v;


last = v;
}
if (first != last) {
System.err.printf("cycle begins with %d and
ends with %d\n", first, last);
return false;
}
}
return true;
}
/**
* Unit tests the <tt>Bipartite</tt> data type.
*/
public static void main(String[] args) {
// create random bipartite graph with V vertices
and E edges; then add F random edges
int V = Integer.parseInt(args[0]);
int E = Integer.parseInt(args[1]);
int F = Integer.parseInt(args[2]);
Graph G = new Graph(V);
int[] vertices = new int[V];
for (int i = 0; i < V; i++)
vertices[i] = i;
StdRandom.shuffle(vertices);
for (int i = 0; i < E; i++) {
int v = StdRandom.uniform(V/2);
int w = StdRandom.uniform(V/2);
G.addEdge(vertices[v], vertices[V/2 + w]);
}
// add F extra edges
for (int i = 0; i < F; i++) {
int v = StdRandom.uniform(V);
int w = StdRandom.uniform(V);
G.addEdge(v, w);
}
StdOut.println(G);
Bipartite b = new Bipartite(G);
if (b.isBipartite()) {
StdOut.println("Graph is bipartite");

for (int v = 0; v < G.V(); v++) {


StdOut.println(v + ": " + b.color(v));
}
}
else {
StdOut.print("Graph has an odd-length cycle: ");
for (int x : b.oddCycle()) {
StdOut.print(x + " ");
}
StdOut.println();
}
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Thu Jul 23 17:05:46 EDT 2015.

Cycle.java
Below is the syntax highlighted version
of Cycle.java from 4.1 Undirected Graphs.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac Cycle.java
* Execution:
java Cycle filename.txt
* Dependencies: Graph.java Stack.java In.java StdOut.java
*
* Identifies a cycle.
* Runs in O(E + V) time.
*
* % java Cycle tinyG.txt
* 3 4 5 3
*
* % java Cycle mediumG.txt
* 15 0 225 15
*
* % java Cycle largeG.txt
* 996673 762 840164 4619 785187 194717 996673
*
***********************************************************
**************/
/**
* The <tt>Cycle</tt> class represents a data type for
* determining whether an undirected graph has a cycle.
* The <em>hasCycle</em> operation determines whether the
graph has
* a cycle and, if so, the <em>cycle</em> operation
returns one.
* <p>
* This implementation uses depth-first search.
* The constructor takes time proportional to <em>V</em> +
<em>E</em>

* (in the worst case),


* where <em>V</em> is the number of vertices and
<em>E</em> is the number of edges.
* Afterwards, the <em>hasCycle</em> operation takes
constant time;
* the <em>cycle</em> operation takes time proportional
* to the length of the cycle.
* <p>
* For additional documentation, see <a
href="/algs4/41graph">Section 4.1</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class Cycle {
private boolean[] marked;
private int[] edgeTo;
private Stack<Integer> cycle;
/**
* Determines whether the undirected graph <tt>G</tt>
has a cycle and, if so,
* finds such a cycle.
* @param G the graph
*/
public Cycle(Graph G) {
if (hasSelfLoop(G)) return;
if (hasParallelEdges(G)) return;
marked = new boolean[G.V()];
edgeTo = new int[G.V()];
for (int v = 0; v < G.V(); v++)
if (!marked[v])
dfs(G, -1, v);
}
// does
// side
private
for

this graph have a self loop?


effect: initialize cycle to be self loop
boolean hasSelfLoop(Graph G) {
(int v = 0; v < G.V(); v++) {
for (int w : G.adj(v)) {
if (v == w) {
cycle = new Stack<Integer>();
cycle.push(v);
cycle.push(v);

return true;
}
}
}
return false;
}
// does this graph have two parallel edges?
// side effect: initialize cycle to be two parallel
edges
private boolean hasParallelEdges(Graph G) {
marked = new boolean[G.V()];
for (int v = 0; v < G.V(); v++) {
// check for parallel edges incident to v
for (int w : G.adj(v)) {
if (marked[w]) {
cycle = new Stack<Integer>();
cycle.push(v);
cycle.push(w);
cycle.push(v);
return true;
}
marked[w] = true;
}
// reset so marked[v] = false for all v
for (int w : G.adj(v)) {
marked[w] = false;
}
}
return false;
}
/**
* Does the graph have a cycle?
* @return <tt>true</tt> if the graph has a cycle,
<tt>false</tt> otherwise
*/
public boolean hasCycle() {
return cycle != null;
}
/**
* Returns a cycle if the graph has a cycle, and
<tt>null</tt> otherwise.

* @return a cycle (as an iterable) if the graph has a


cycle,
*
and <tt>null</tt> otherwise
*/
public Iterable<Integer> cycle() {
return cycle;
}
private void dfs(Graph G, int u, int v) {
marked[v] = true;
for (int w : G.adj(v)) {
// short circuit if cycle already found
if (cycle != null) return;
if (!marked[w]) {
edgeTo[w] = v;
dfs(G, v, w);
}
// check for cycle (but disregard reverse of
edge leading to v)
else if (w != u) {
cycle = new Stack<Integer>();
for (int x = v; x != w; x = edgeTo[x]) {
cycle.push(x);
}
cycle.push(w);
cycle.push(v);
}
}
}
/**
* Unit tests the <tt>Cycle</tt> data type.
*/
public static void main(String[] args) {
In in = new In(args[0]);
Graph G = new Graph(in);
Cycle finder = new Cycle(G);
if (finder.hasCycle()) {
for (int v : finder.cycle()) {
StdOut.print(v + " ");
}
StdOut.println();
}
else {

StdOut.println("Graph is acyclic");
}
}
}

Copyright 20022010, Robert Sedgewick and Kevin Wayne.


Last updated: Tue Jul 28 06:21:05 EDT 2015.

SymbolGraph.java
Below is the syntax highlighted version
of SymbolGraph.java from 4.1 Undirected Graphs.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac SymbolGraph.java
* Execution:
java SymbolGraph filename.txt delimiter
* Dependencies: ST.java Graph.java In.java StdIn.java
StdOut.java
* Data files:
http://algs4.cs.princeton.edu/41undirected/routes.txt
*
http://algs4.cs.princeton.edu/41undirected/movies.txt
*
http://algs4.cs.princeton.edu/41undirected/moviestiny.txt
*
http://algs4.cs.princeton.edu/41undirected/moviesG.txt
*
http://algs4.cs.princeton.edu/41undirected/moviestopGrossing
.txt
*
* % java SymbolGraph routes.txt " "
* JFK
*
MCO
*
ATL
*
ORD
* LAX
*
PHX
*
LAS
*
* % java SymbolGraph movies.txt "/"
* Tin Men (1987)
*
Hershey, Barbara
*
Geppi, Cindy
*
Jones, Kathy (II)
*
Herr, Marcia
*
...
*
Blumenfeld, Alan

*
DeBoy, David
* Bacon, Kevin
*
Woodsman, The (2004)
*
Wild Things (1998)
*
Where the Truth Lies (2005)
*
Tremors (1990)
*
...
*
Apollo 13 (1995)
*
Animal House (1978)
*
*
* Assumes that input file is encoded using UTF-8.
* % iconv -f ISO-8859-1 -t UTF-8 movies-iso8859.txt >
movies.txt
*
***********************************************************
**************/
/**
* The <tt>SymbolGraph</tt> class represents an undirected
graph, where the
* vertex names are arbitrary strings.
* By providing mappings between string vertex names and
integers,
* it serves as a wrapper around the
* {@link Graph} data type, which assumes the vertex names
are integers
* between 0 and <em>V</em> - 1.
* It also supports initializing a symbol graph from a
file.
* <p>
* This implementation uses an {@link ST} to map from
strings to integers,
* an array to map from integers to strings, and a {@link
Graph} to store
* the underlying graph.
* The <em>index</em> and <em>contains</em> operations
take time
* proportional to log <em>V</em>, where <em>V</em> is the
number of vertices.
* The <em>name</em> operation takes constant time.
* <p>
* For additional documentation, see <a
href="http://algs4.cs.princeton.edu/41undirected">Section
4.1</a> of

* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and


Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class SymbolGraph {
private ST<String, Integer> st; // string -> index
private String[] keys;
// index -> string
private Graph G;
/**
* Initializes a graph from a file using the specified
delimiter.
* Each line in the file contains
* the name of a vertex, followed by a list of the
names
* of the vertices adjacent to that vertex, separated
by the delimiter.
* @param filename the name of the file
* @param delimiter the delimiter between fields
*/
public SymbolGraph(String filename, String delimiter) {
st = new ST<String, Integer>();
// First pass builds the index by reading strings
to associate
// distinct strings with an index
In in = new In(filename);
// while (in.hasNextLine()) {
while (!in.isEmpty()) {
String[] a = in.readLine().split(delimiter);
for (int i = 0; i < a.length; i++) {
if (!st.contains(a[i]))
st.put(a[i], st.size());
}
}
StdOut.println("Done reading " + filename);
// inverted index to get string keys in an aray
keys = new String[st.size()];
for (String name : st.keys()) {
keys[st.get(name)] = name;
}
// second pass builds the graph by connecting first
vertex on each

// line to all others


G = new Graph(st.size());
in = new In(filename);
while (in.hasNextLine()) {
String[] a = in.readLine().split(delimiter);
int v = st.get(a[0]);
for (int i = 1; i < a.length; i++) {
int w = st.get(a[i]);
G.addEdge(v, w);
}
}
}
/**
* Does the graph contain the vertex named <tt>s</tt>?
* @param s the name of a vertex
* @return <tt>true</tt> if <tt>s</tt> is the name of a
vertex, and <tt>false</tt> otherwise
*/
public boolean contains(String s) {
return st.contains(s);
}
/**
* Returns the integer associated with the vertex named
<tt>s</tt>.
* @param s the name of a vertex
* @return the integer (between 0 and <em>V</em> - 1)
associated with the vertex named <tt>s</tt>
*/
public int index(String s) {
return st.get(s);
}
/**
* Returns the name of the vertex associated with the
integer <tt>v</tt>.
* @param v the integer corresponding to a vertex
(between 0 and <em>V</em> - 1)
* @return the name of the vertex associated with the
integer <tt>v</tt>
*/
public String name(int v) {
return keys[v];
}
/**

* Returns the graph assoicated with the symbol graph.


It is the client's responsibility
* not to mutate the graph.
* @return the graph associated with the symbol graph
*/
public Graph G() {
return G;
}
/**
* Unit tests the <tt>SymbolGraph</tt> data type.
*/
public static void main(String[] args) {
String filename = args[0];
String delimiter = args[1];
SymbolGraph sg = new SymbolGraph(filename,
delimiter);
Graph G = sg.G();
while (StdIn.hasNextLine()) {
String source = StdIn.readLine();
if (sg.contains(source)) {
int s = sg.index(source);
for (int v : G.adj(s)) {
StdOut.println("
" + sg.name(v));
}
}
else {
StdOut.println("input not contain '" +
source + "'");
}
}
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Wed Dec 18 21:57:12 EST 2013.

DegreesOfSeparation.java
Below is the syntax highlighted version
of DegreesOfSeparation.java from 4.1 Undirected Graphs.
Here is the Javadoc.

/
***********************************************************
**************
* Compilation: javac DegreesOfSeparation.java
* Execution:
java DegreesOfSeparation filename
delimiter source
* Dependencies: SymbolGraph.java Graph.java
BreadthFirstPaths.java StdOut.java
* Data files:
http://algs4.cs.princeton.edu/41undirected/routes.txt
*
http://algs4.cs.princeton.edu/41undirected/movies.txt
*
*
* % java DegreesOfSeparation routes.txt " " "JFK"
* LAS
*
JFK
*
ORD
*
DEN
*
LAS
* DFW
*
JFK
*
ORD
*
DFW
* EWR
*
Not in database.
*
* % java DegreesOfSeparation movies.txt "/" "Bacon,
Kevin"
* Kidman, Nicole
*
Bacon, Kevin
*
Woodsman, The (2004)
*
Grier, David Alan
*
Bewitched (2005)
*
Kidman, Nicole
* Grant, Cary

*
Bacon, Kevin
*
Planes, Trains & Automobiles (1987)
*
Martin, Steve (I)
*
Dead Men Don't Wear Plaid (1982)
*
Grant, Cary
*
* % java DegreesOfSeparation movies.txt "/" "Animal House
(1978)"
* Titanic (1997)
*
Animal House (1978)
*
Allen, Karen (I)
*
Raiders of the Lost Ark (1981)
*
Taylor, Rocky (I)
*
Titanic (1997)
* To Catch a Thief (1955)
*
Animal House (1978)
*
Vernon, John (I)
*
Topaz (1969)
*
Hitchcock, Alfred (I)
*
To Catch a Thief (1955)
*
***********************************************************
**************/
/**
* The <tt>DegreesOfSeparation</tt> class provides a
client for finding
* the degree of separation between one distinguished
individual and
* every other individual in a social network.
* As an example, if the social network consists of actors
in which
* two actors are connected by a link if they appeared in
the same movie,
* and Kevin Bacon is the distinguished individual, then
the client
* computes the Kevin Bacon number of every actor in the
network.
* <p>
* The running time is proportional to the number of
individuals and
* connections in the network. If the connections are
given implicitly,
* as in the movie network example (where every two actors
are connected

* if they appear in the same movie), the efficiency of


the algorithm
* is improved by allowing both movie and actor vertices
and connecting
* each movie to all of the actors that appear in that
movie.
* <p>
* For additional documentation,
* see <a
href="http://algs4.cs.princeton.edu/41undirected">Section
4.1</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class DegreesOfSeparation {
// this class cannot be instantiated
private DegreesOfSeparation() { }
/**
* Reads in a social network from a file, and then
repeatedly reads in
* individuals from standard input and prints out
their degrees of
* separation.
* Takes three command-line arguments: the name of a
file,
* a delimiter, and the name of the distinguished
individual.
* Each line in the file contains the name of a
vertex, followed by a
* list of the names of the vertices adjacent to that
vertex,
* separated by the delimiter.
*/
public static void main(String[] args) {
String filename = args[0];
String delimiter = args[1];
String source
= args[2];
// StdOut.println("Source: " + source);
SymbolGraph sg = new SymbolGraph(filename,
delimiter);

Graph G = sg.G();
if (!sg.contains(source)) {
StdOut.println(source + " not in database.");
return;
}
int s = sg.index(source);
BreadthFirstPaths bfs = new BreadthFirstPaths(G, s);
while (!StdIn.isEmpty()) {
String sink = StdIn.readLine();
if (sg.contains(sink)) {
int t = sg.index(sink);
if (bfs.hasPathTo(t)) {
for (int v : bfs.pathTo(t)) {
StdOut.println("
" + sg.name(v));
}
}
else {
StdOut.println("Not connected");
}
}
else {
StdOut.println("
Not in database.");
}
}
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Tue Oct 22 10:21:43 EDT 2013.

Digraph.java
Below is the syntax highlighted version
of Digraph.java from Algorithms.
Here is the Javadoc.

/
***********************************************************
**************
* Compilation: javac Digraph.java
* Execution:
java Digraph filename.txt
* Dependencies: Bag.java In.java StdOut.java
* Data files:
http://algs4.cs.princeton.edu/42directed/tinyDG.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
* 7: 6 9
* 8: 6
* 9: 11 10
* 10: 12
* 11: 4 12
* 12: 9
*
***********************************************************
**************/
import java.util.InputMismatchException;
import java.util.NoSuchElementException;
/**
* The <tt>Digraph</tt> class represents a directed graph
of vertices

* named 0 through <em>V</em> - 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.
* Parallel edges and self-loops are permitted.
* <p>
* 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.
* <p>
* For additional documentation,
* see <a
href="http://algs4.cs.princeton.edu/42directed">Section
4.2</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class Digraph {
private static final String NEWLINE =
System.getProperty("line.separator");
private final int V;
private int E;
private Bag<Integer>[] adj;
/**
* Initializes an empty digraph with <em>V</em>
vertices.
* @param V the number of vertices
* @throws java.lang.IllegalArgumentException if V < 0
*/
public Digraph(int V) {
if (V < 0) throw new
IllegalArgumentException("Number of vertices in a Digraph
must be nonnegative");
this.V = V;
this.E = 0;

adj = (Bag<Integer>[]) new Bag[V];


for (int v = 0; v < V; v++) {
adj[v] = new Bag<Integer>();
}
}
/**
* Initializes a digraph from an input stream.
* The format is the number of vertices <em>V</em>,
* followed by the number of edges <em>E</em>,
* followed by <em>E</em> pairs of vertices, with each
entry separated by whitespace.
* @param in the input stream
* @throws java.lang.IndexOutOfBoundsException if the
endpoints of any edge are not in prescribed range
* @throws java.lang.IllegalArgumentException if the
number of vertices or edges is negative
*/
public Digraph(In in) {
try {
this.V = in.readInt();
if (V < 0) throw new
IllegalArgumentException("Number of vertices in a Digraph
must be nonnegative");
adj = (Bag<Integer>[]) new Bag[V];
for (int v = 0; v < V; v++) {
adj[v] = new Bag<Integer>();
}
int E = in.readInt();
if (E < 0) throw new
IllegalArgumentException("Number of edges in a Digraph must
be nonnegative");
for (int i = 0; i < E; i++) {
int v = in.readInt();
int w = in.readInt();
addEdge(v, w);
}
}
catch (NoSuchElementException e) {
throw new InputMismatchException("Invalid input
format in Digraph constructor");
}
}
/**
* Initializes a new digraph that is a deep copy of
<tt>G</tt>.

* @param G the digraph to copy


*/
public Digraph(Digraph G) {
this(G.V());
this.E = G.E();
for (int v = 0; v < G.V(); v++) {
// reverse so that adjacency list is in same
order as original
Stack<Integer> reverse = new Stack<Integer>();
for (int w : G.adj[v]) {
reverse.push(w);
}
for (int w : reverse) {
adj[v].add(w);
}
}
}
/**
* Returns
* @return
*/
public int
return
}
/**
* Returns
* @return
*/
public int
return
}

the number of vertices in the digraph.


the number of vertices in the digraph
V() {
V;

the number of edges in the digraph.


the number of edges in the digraph
E() {
E;

// throw an IndexOutOfBoundsException unless 0 <= v < V


private void validateVertex(int v) {
if (v < 0 || v >= V)
throw new IndexOutOfBoundsException("vertex " +
v + " is not between 0 and " + (V-1));
}
/**
* Adds the directed edge v->w to the digraph.
* @param v the tail vertex
* @param w the head vertex

* @throws java.lang.IndexOutOfBoundsException unless


both 0 <= v < V and 0 <= w < V
*/
public void addEdge(int v, int w) {
validateVertex(v);
validateVertex(w);
adj[v].add(w);
E++;
}
/**
* Returns the vertices adjacent from vertex <tt>v</tt>
in the digraph.
* @param v the vertex
* @return the vertices adjacent from vertex <tt>v</tt>
in the digraph, as an Iterable
* @throws java.lang.IndexOutOfBoundsException unless 0
<= v < V
*/
public Iterable<Integer> adj(int v) {
validateVertex(v);
return adj[v];
}
/**
* Returns the number of directed edges incident from
vertex <tt>v</tt>.
* This is known as the <em>outdegree</em> of vertex
<tt>v</tt>.
* @param v the vertex
* @return the outdegree of vertex <tt>v</tt>
* @throws java.lang.IndexOutOfBoundsException unless 0
<= v < V
*/
public int outdegree(int v) {
validateVertex(v);
return adj[v].size();
}
/**
* Returns the reverse of the digraph.
* @return the reverse of the digraph
*/
public Digraph reverse() {
Digraph R = new Digraph(V);
for (int v = 0; v < V; v++) {
for (int w : adj(v)) {

R.addEdge(w, v);
}
}
return R;
}
/**
* Returns a string representation of the graph.
* This method takes time proportional to <em>E</em> +
<em>V</em>.
* @return the number of vertices <em>V</em>, followed
by the number of edges <em>E</em>,
*
followed by the <em>V</em> adjacency lists
*/
public String toString() {
StringBuilder s = new StringBuilder();
s.append(V + " vertices, " + E + " edges " +
NEWLINE);
for (int v = 0; v < V; v++) {
s.append(String.format("%d: ", v));
for (int w : adj[v]) {
s.append(String.format("%d ", w));
}
s.append(NEWLINE);
}
return s.toString();
}
/**
* Unit tests the <tt>Digraph</tt> data type.
*/
public static void main(String[] args) {
In in = new In(args[0]);
Digraph G = new Digraph(in);
StdOut.println(G);
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Sun Jul 26 11:21:27 EDT 2015.

DigraphGenerator.java
Below is the syntax highlighted version
of DigraphGenerator.java from 4.2 Directed Graphs.
is the Javadoc.

Here

/
***********************************************************
**************
* Compilation: javac DigraphGenerator.java
* Execution:
java DigraphGenerator V E
* Dependencies: Digraph.java
*
* A digraph generator.
*
***********************************************************
**************/
/**
* The <tt>DigraphGenerator</tt> class provides static
methods for creating
* various digraphs, including Erdos-Renyi random
digraphs, random DAGs,
* random rooted trees, random rooted DAGs, random
tournaments, path digraphs,
* cycle digraphs, and the complete digraph.
* <p>
* For additional documentation, see <a
href="http://algs4.cs.princeton.edu/42digraph">Section
4.2</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class DigraphGenerator {
private static final class Edge implements
Comparable<Edge> {
private int v;
private int w;

private Edge(int v, int w) {


this.v = v;
this.w = w;
}
public int compareTo(Edge that)
if (this.v < that.v) return
if (this.v > that.v) return
if (this.w < that.w) return
if (this.w > that.w) return
return 0;
}

{
-1;
+1;
-1;
+1;

}
/**
* Returns a random simple digraph containing <tt>V</tt>
vertices and <tt>E</tt> edges.
* @param V the number of vertices
* @param E the number of vertices
* @return a random simple digraph on <tt>V</tt>
vertices, containing a total
*
of <tt>E</tt> edges
* @throws IllegalArgumentException if no such simple
digraph exists
*/
public static Digraph simple(int V, int E) {
if (E > (long) V*(V-1)) throw new
IllegalArgumentException("Too many edges");
if (E < 0)
throw new
IllegalArgumentException("Too few edges");
Digraph G = new Digraph(V);
SET<Edge> set = new SET<Edge>();
while (G.E() < E) {
int v = StdRandom.uniform(V);
int w = StdRandom.uniform(V);
Edge e = new Edge(v, w);
if ((v != w) && !set.contains(e)) {
set.add(e);
G.addEdge(v, w);
}
}
return G;
}
/**
* Returns a random simple digraph on <tt>V</tt>
vertices, with an

* edge between any two vertices with probability


<tt>p</tt>. This is sometimes
* referred to as the Erdos-Renyi random digraph model.
* This implementations takes time propotional to V^2
(even if <tt>p</tt> is small).
* @param V the number of vertices
* @param p the probability of choosing an edge
* @return a random simple digraph on <tt>V</tt>
vertices, with an edge between
*
any two vertices with probability <tt>p</tt>
* @throws IllegalArgumentException if probability is
not between 0 and 1
*/
public static Digraph simple(int V, double p) {
if (p < 0.0 || p > 1.0)
throw new IllegalArgumentException("Probability
must be between 0 and 1");
Digraph G = new Digraph(V);
for (int v = 0; v < V; v++)
for (int w = 0; w < V; w++)
if (v != w)
if (StdRandom.bernoulli(p))
G.addEdge(v, w);
return G;
}
/**
* Returns the complete digraph on <tt>V</tt> vertices.
* @param V the number of vertices
* @return the complete digraph on <tt>V</tt> vertices
*/
public static Digraph complete(int V) {
return simple(V, V*(V-1));
}
/**
* Returns a random simple DAG containing <tt>V</tt>
vertices and <tt>E</tt> edges.
* Note: it is not uniformly selected at random among
all such DAGs.
* @param V the number of vertices
* @param E the number of vertices
* @return a random simple DAG on <tt>V</tt> vertices,
containing a total
*
of <tt>E</tt> edges
* @throws IllegalArgumentException if no such simple
DAG exists

*/
public static Digraph dag(int V, int E) {
if (E > (long) V*(V-1) / 2) throw new
IllegalArgumentException("Too many edges");
if (E < 0)
throw new
IllegalArgumentException("Too few edges");
Digraph G = new Digraph(V);
SET<Edge> set = new SET<Edge>();
int[] vertices = new int[V];
for (int i = 0; i < V; i++)
vertices[i] = i;
StdRandom.shuffle(vertices);
while (G.E() < E) {
int v = StdRandom.uniform(V);
int w = StdRandom.uniform(V);
Edge e = new Edge(v, w);
if ((v < w) && !set.contains(e)) {
set.add(e);
G.addEdge(vertices[v], vertices[w]);
}
}
return G;
}
// tournament
/**
* Returns a random tournament digraph on <tt>V</tt>
vertices. A tournament digraph
* is a DAG in which for every two vertices, there is
one directed edge.
* A tournament is an oriented complete graph.
* @param V the number of vertices
* @return a random tournament digraph on <tt>V</tt>
vertices
*/
public static Digraph tournament(int V) {
Digraph G = new Digraph(V);
for (int v = 0; v < G.V(); v++) {
for (int w = v+1; w < G.V(); w++) {
if (StdRandom.bernoulli(0.5)) G.addEdge(v,
w);
else
G.addEdge(w,
v);
}
}
return G;
}

/**
* Returns a random rooted-in DAG on <tt>V</tt>
vertices and <tt>E</tt> edges.
* A rooted in-tree is a DAG in which there is a single
vertex
* reachable from every other vertex.
* The DAG returned is not chosen uniformly at random
among all such DAGs.
* @param V the number of vertices
* @param E the number of edges
* @return a random rooted-in DAG on <tt>V</tt>
vertices and <tt>E</tt> edges
*/
public static Digraph rootedInDAG(int V, int E) {
if (E > (long) V*(V-1) / 2) throw new
IllegalArgumentException("Too many edges");
if (E < V-1)
throw new
IllegalArgumentException("Too few edges");
Digraph G = new Digraph(V);
SET<Edge> set = new SET<Edge>();
// fix a topological order
int[] vertices = new int[V];
for (int i = 0; i < V; i++)
vertices[i] = i;
StdRandom.shuffle(vertices);
// one edge pointing from each vertex, other than
the root = vertices[V-1]
for (int v = 0; v < V-1; v++) {
int w = StdRandom.uniform(v+1, V);
Edge e = new Edge(v, w);
set.add(e);
G.addEdge(vertices[v], vertices[w]);
}
while (G.E() < E) {
int v = StdRandom.uniform(V);
int w = StdRandom.uniform(V);
Edge e = new Edge(v, w);
if ((v < w) && !set.contains(e)) {
set.add(e);
G.addEdge(vertices[v], vertices[w]);
}
}
return G;

}
/**
* Returns a random rooted-out DAG on <tt>V</tt>
vertices and <tt>E</tt> edges.
* A rooted out-tree is a DAG in which every vertex is
reachable from a
* single vertex.
* The DAG returned is not chosen uniformly at random
among all such DAGs.
* @param V the number of vertices
* @param E the number of edges
* @return a random rooted-out DAG on <tt>V</tt>
vertices and <tt>E</tt> edges
*/
public static Digraph rootedOutDAG(int V, int E) {
if (E > (long) V*(V-1) / 2) throw new
IllegalArgumentException("Too many edges");
if (E < V-1)
throw new
IllegalArgumentException("Too few edges");
Digraph G = new Digraph(V);
SET<Edge> set = new SET<Edge>();
// fix a topological order
int[] vertices = new int[V];
for (int i = 0; i < V; i++)
vertices[i] = i;
StdRandom.shuffle(vertices);
// one edge pointing from each vertex, other than
the root = vertices[V-1]
for (int v = 0; v < V-1; v++) {
int w = StdRandom.uniform(v+1, V);
Edge e = new Edge(w, v);
set.add(e);
G.addEdge(vertices[w], vertices[v]);
}
while (G.E() < E) {
int v = StdRandom.uniform(V);
int w = StdRandom.uniform(V);
Edge e = new Edge(w, v);
if ((v < w) && !set.contains(e)) {
set.add(e);
G.addEdge(vertices[w], vertices[v]);
}
}

return G;
}
/**
* Returns a random rooted-in tree on <tt>V</tt>
vertices.
* A rooted in-tree is an oriented tree in which there
is a single vertex
* reachable from every other vertex.
* The tree returned is not chosen uniformly at random
among all such trees.
* @param V the number of vertices
* @return a random rooted-in tree on <tt>V</tt>
vertices
*/
public static Digraph rootedInTree(int V) {
return rootedInDAG(V, V-1);
}
/**
* Returns a random rooted-out tree on <tt>V</tt>
vertices. A rooted out-tree
* is an oriented tree in which each vertex is
reachable from a single vertex.
* It is also known as a <em>arborescence</em> or
<em>branching</em>.
* The tree returned is not chosen uniformly at random
among all such trees.
* @param V the number of vertices
* @return a random rooted-out tree on <tt>V</tt>
vertices
*/
public static Digraph rootedOutTree(int V) {
return rootedOutDAG(V, V-1);
}
/**
* Returns a path digraph on <tt>V</tt> vertices.
* @param V the number of vertices in the path
* @return a digraph that is a directed path on
<tt>V</tt> vertices
*/
public static Digraph path(int V) {
Digraph G = new Digraph(V);
int[] vertices = new int[V];
for (int i = 0; i < V; i++)
vertices[i] = i;

StdRandom.shuffle(vertices);
for (int i = 0; i < V-1; i++) {
G.addEdge(vertices[i], vertices[i+1]);
}
return G;
}
/**
* Returns a complete binary tree digraph on <tt>V</tt>
vertices.
* @param V the number of vertices in the binary tree
* @return a digraph that is a complete binary tree on
<tt>V</tt> vertices
*/
public static Digraph binaryTree(int V) {
Digraph G = new Digraph(V);
int[] vertices = new int[V];
for (int i = 0; i < V; i++)
vertices[i] = i;
StdRandom.shuffle(vertices);
for (int i = 1; i < V; i++) {
G.addEdge(vertices[i], vertices[(i-1)/2]);
}
return G;
}
/**
* Returns a cycle digraph on <tt>V</tt> vertices.
* @param V the number of vertices in the cycle
* @return a digraph that is a directed cycle on
<tt>V</tt> vertices
*/
public static Digraph cycle(int V) {
Digraph G = new Digraph(V);
int[] vertices = new int[V];
for (int i = 0; i < V; i++)
vertices[i] = i;
StdRandom.shuffle(vertices);
for (int i = 0; i < V-1; i++) {
G.addEdge(vertices[i], vertices[i+1]);
}
G.addEdge(vertices[V-1], vertices[0]);
return G;
}
/**

* Returns a random simple digraph on <tt>V</tt>


vertices, <tt>E</tt>
* edges and (at least) <tt>c</tt> strong components.
The vertices are randomly
* assigned integer labels between <tt>0</tt> and
<tt>c-1</tt> (corresponding to
* strong components). Then, a strong component is
creates among the vertices
* with the same label. Next, random edges (either
between two vertices with
* the same labels or from a vetex with a smaller label
to a vertex with a
* larger label). The number of components will be
equal to the number of
* distinct labels that are assigned to vertices.
*
* @param V the number of vertices
* @param E the number of edges
* @param c the (maximum) number of strong components
* @return a random simple digraph on <tt>V</tt>
vertices and
<tt>E</tt> edges, with (at most) <tt>c</tt>
strong components
* @throws IllegalArgumentException if <tt>c</tt> is
larger than <tt>V</tt>
*/
public static Digraph strong(int V, int E, int c) {
if (c >= V || c <= 0)
throw new IllegalArgumentException("Number of
components must be between 1 and V");
if (E <= 2*(V-c))
throw new IllegalArgumentException("Number of
edges must be at least 2(V-c)");
if (E > (long) V*(V-1) / 2)
throw new IllegalArgumentException("Too many
edges");
// the digraph
Digraph G = new Digraph(V);
// edges added to G (to avoid duplicate edges)
SET<Edge> set = new SET<Edge>();
int[] label = new int[V];
for (int v = 0; v < V; v++)
label[v] = StdRandom.uniform(c);

// make all vertices with label c a strong


component by
// combining a rooted in-tree and a rooted out-tree
for (int i = 0; i < c; i++) {
// how many vertices in component c
int count = 0;
for (int v = 0; v < G.V(); v++) {
if (label[v] == i) count++;
}
// if (count == 0) System.err.println("less
than desired number of strong components");
int[] vertices = new int[count];
int j = 0;
for (int v = 0; v < V; v++) {
if (label[v] == i) vertices[j++] = v;
}
StdRandom.shuffle(vertices);
// rooted-in tree with root = vertices[count-1]
for (int v = 0; v < count-1; v++) {
int w = StdRandom.uniform(v+1, count);
Edge e = new Edge(w, v);
set.add(e);
G.addEdge(vertices[w], vertices[v]);
}
// rooted-out tree with root = vertices[count1]
for (int v = 0; v < count-1; v++) {
int w = StdRandom.uniform(v+1, count);
Edge e = new Edge(v, w);
set.add(e);
G.addEdge(vertices[v], vertices[w]);
}
}
while (G.E() < E) {
int v = StdRandom.uniform(V);
int w = StdRandom.uniform(V);
Edge e = new Edge(v, w);
if (!set.contains(e) && v != w && label[v] <=
label[w]) {
set.add(e);
G.addEdge(v, w);
}

}
return G;
}
/**
* Unit tests the <tt>DigraphGenerator</tt> library.
*/
public static void main(String[] args) {
int V = Integer.parseInt(args[0]);
int E = Integer.parseInt(args[1]);
System.out.println("complete graph");
System.out.println(complete(V));
System.out.println();
System.out.println("simple");
System.out.println(simple(V, E));
System.out.println();
System.out.println("path");
System.out.println(path(V));
System.out.println();
System.out.println("cycle");
System.out.println(cycle(V));
System.out.println();
System.out.println("binary tree");
System.out.println(binaryTree(V));
System.out.println();
System.out.println("tournament");
System.out.println(tournament(V));
System.out.println();
System.out.println("DAG");
System.out.println(dag(V, E));
System.out.println();
System.out.println("rooted-in DAG");
System.out.println(rootedInDAG(V, E));
System.out.println();
System.out.println("rooted-out DAG");
System.out.println(rootedOutDAG(V, E));
System.out.println();

System.out.println("rooted-in tree");
System.out.println(rootedInTree(V));
System.out.println();
System.out.println("rooted-out DAG");
System.out.println(rootedOutTree(V));
System.out.println();
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Thu Jul 23 17:05:46 EDT 2015.

DirectedDFS.java
Below is the syntax highlighted version
of DirectedDFS.java from 4.2 Directed Graphs.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac DirectedDFS.java
* Execution:
java DirectedDFS V E
* Dependencies: Digraph.java Bag.java In.java StdOut.java
* Data files:
http://www.cs.princeton.edu/algs4/42directed/tinyDG.txt
*
* Determine single-source or multiple-source reachability
in a digraph
* using depth first search.
* Runs in O(E + V) time.
*
* % java DirectedDFS tinyDG.txt 1
* 1
*
* % java DirectedDFS tinyDG.txt 2
* 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
*
***********************************************************
**************/
/**
* The <tt>DirectedDFS</tt> class represents a data type
for
* determining the vertices reachable from a given source
vertex <em>s</em>
* (or set of source vertices) in a digraph. For versions
that find the paths,
* see {@link DepthFirstDirectedPaths} and {@link
BreadthFirstDirectedPaths}.
* <p>
* This implementation uses depth-first search.

* The constructor takes time proportional to <em>V</em> +


<em>E</em>
* (in the worst case),
* where <em>V</em> is the number of vertices and
<em>E</em> is the number of edges.
* <p>
* For additional documentation, see <a
href="/algs4/41graph">Section 4.1</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class DirectedDFS {
private boolean[] marked; // marked[v] = true if v is
reachable
// from source (or sources)
private int count;
// number of vertices
reachable from s
/**
* Computes the vertices in digraph <tt>G</tt> that are
* reachable from the source vertex <tt>s</tt>.
* @param G the digraph
* @param s the source vertex
*/
public DirectedDFS(Digraph G, int s) {
marked = new boolean[G.V()];
dfs(G, s);
}
/**
* Computes the vertices in digraph <tt>G</tt> that are
* connected to any of the source vertices
<tt>sources</tt>.
* @param G the graph
* @param sources the source vertices
*/
public DirectedDFS(Digraph G, Iterable<Integer> sources)
{
marked = new boolean[G.V()];
for (int v : sources) {
if (!marked[v]) dfs(G, v);
}
}

private void dfs(Digraph G, int v) {


count++;
marked[v] = true;
for (int w : G.adj(v)) {
if (!marked[w]) dfs(G, w);
}
}
/**
* Is there a directed path from the source vertex (or
any
* of the source vertices) and vertex <tt>v</tt>?
* @param v the vertex
* @return <tt>true</tt> if there is a directed path,
<tt>false</tt> otherwise
*/
public boolean marked(int v) {
return marked[v];
}
/**
* Returns the number of vertices reachable from the
source vertex
* (or source vertices).
* @return the number of vertices reachable from the
source vertex
*
(or source vertices)
*/
public int count() {
return count;
}
/**
* Unit tests the <tt>DirectedDFS</tt> data type.
*/
public static void main(String[] args) {
// read in digraph from command-line argument
In in = new In(args[0]);
Digraph G = new Digraph(in);
// read in sources from command-line arguments
Bag<Integer> sources = new Bag<Integer>();
for (int i = 1; i < args.length; i++) {
int s = Integer.parseInt(args[i]);
sources.add(s);
}

// multiple-source reachability
DirectedDFS dfs = new DirectedDFS(G, sources);
// print out vertices reachable from sources
for (int v = 0; v < G.V(); v++) {
if (dfs.marked(v)) StdOut.print(v + " ");
}
StdOut.println();
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Mon Nov 4 11:41:40 EST 2013.

DepthFirstDirectedPaths.java
Below is the syntax highlighted version
of DepthFirstDirectedPaths.java from 4.2 Directed Graphs.
Here is the Javadoc.

/
***********************************************************
**************
* Compilation: javac DepthFirstDirectedPaths.java
* Execution:
java DepthFirstDirectedPaths G s
* Dependencies: Digraph.java Stack.java
*
* Determine reachability in a digraph from a given vertex
using
* depth first search.
* Runs in O(E + V) time.
*
* % tinyDG.txt 3
* 3 to 0: 3-5-4-2-0
* 3 to 1: 3-5-4-2-0-1
* 3 to 2: 3-5-4-2
* 3 to 3: 3
* 3 to 4: 3-5-4
* 3 to 5: 3-5
* 3 to 6: not connected
* 3 to 7: not connected
* 3 to 8: not connected
* 3 to 9: not connected
* 3 to 10: not connected
* 3 to 11: not connected
* 3 to 12: not connected
*
***********************************************************
**************/
/**
* The <tt>DepthFirstDirectedPaths</tt> class represents a
data type for finding
* directed paths from a source vertex <em>s</em> to every
* other vertex in the digraph.
* <p>
* This implementation uses depth-first search.

* The constructor takes time proportional to <em>V</em> +


<em>E</em>,
* where <em>V</em> is the number of vertices and
<em>E</em> is the number of edges.
* It uses extra space (not including the graph)
proportional to <em>V</em>.
* <p>
* For additional documentation, see <a
href="/algs4/41graph">Section 4.1</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class DepthFirstDirectedPaths {
private boolean[] marked; // marked[v] = true if v is
reachable from s
private int[] edgeTo;
// edgeTo[v] = last edge on
path from s to v
private final int s;
// source vertex
/**
* Computes a directed path from <tt>s</tt> to every
other vertex in digraph <tt>G</tt>.
* @param G the digraph
* @param s the source vertex
*/
public DepthFirstDirectedPaths(Digraph G, int s) {
marked = new boolean[G.V()];
edgeTo = new int[G.V()];
this.s = s;
dfs(G, s);
}
private void dfs(Digraph G, int v) {
marked[v] = true;
for (int w : G.adj(v)) {
if (!marked[w]) {
edgeTo[w] = v;
dfs(G, w);
}
}
}
/**

* Is there a directed path from the source vertex


<tt>s</tt> to vertex <tt>v</tt>?
* @param v the vertex
* @return <tt>true</tt> if there is a directed path
from the source
*
vertex <tt>s</tt> to vertex <tt>v</tt>,
<tt>false</tt> otherwise
*/
public boolean hasPathTo(int v) {
return marked[v];
}
/**
* Returns a directed path from the source vertex
<tt>s</tt> to vertex <tt>v</tt>, or
* <tt>null</tt> if no such path.
* @param v the vertex
* @return the sequence of vertices on a directed path
from the source vertex
*
<tt>s</tt> to vertex <tt>v</tt>, as an Iterable
*/
public Iterable<Integer> pathTo(int v) {
if (!hasPathTo(v)) return null;
Stack<Integer> path = new Stack<Integer>();
for (int x = v; x != s; x = edgeTo[x])
path.push(x);
path.push(s);
return path;
}
/**
* Unit tests the <tt>DepthFirstDirectedPaths</tt> data
type.
*/
public static void main(String[] args) {
In in = new In(args[0]);
Digraph G = new Digraph(in);
// StdOut.println(G);
int s = Integer.parseInt(args[1]);
DepthFirstDirectedPaths dfs = new
DepthFirstDirectedPaths(G, s);
for (int v = 0; v < G.V(); v++) {
if (dfs.hasPathTo(v)) {
StdOut.printf("%d to %d: ", s, v);

for (int x : dfs.pathTo(v)) {


if (x == s) StdOut.print(x);
else
StdOut.print("-" + x);
}
StdOut.println();
}
else {
StdOut.printf("%d to %d:

not connected\n",

s, v);
}
}
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Thu Oct 24 15:59:37 EDT 2013.

DirectedCycle.java

Below is the syntax highlighted version


of DirectedCycle.java from 4.2 Directed Graphs.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac DirectedCycle.java
* Execution:
java DirectedCycle < input.txt
* Dependencies: Digraph.java Stack.java StdOut.java
In.java
* Data files:
http://algs4.cs.princeton.edu/42directed/tinyDG.txt
*
http://algs4.cs.princeton.edu/42directed/tinyDAG.txt
*
* Finds a directed cycle in a digraph.
* Runs in O(E + V) time.
*
* % java DirectedCycle tinyDG.txt
* Cycle: 3 5 4 3
*
* % java DirectedCycle tinyDAG.txt
* No cycle
*
***********************************************************
**************/
/**
* The <tt>DirectedCycle</tt> class represents a data type
for
* determining whether a digraph has a directed cycle.
* The <em>hasCycle</em> operation determines whether the
digraph has
* a directed cycle and, and of so, the <em>cycle</em>
operation
* returns one.
* <p>
* This implementation uses depth-first search.
* The constructor takes time proportional to <em>V</em> +
<em>E</em>
* (in the worst case),

* where <em>V</em> is the number of vertices and


<em>E</em> is the number of edges.
* Afterwards, the <em>hasCycle</em> operation takes
constant time;
* the <em>cycle</em> operation takes time proportional
* to the length of the cycle.
* <p>
* See {@link Topological} to compute a topological order
if the
* digraph is acyclic.
* <p>
* For additional documentation, see <a
href="/algs4/42digraph">Section 4.2</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class DirectedCycle {
private boolean[] marked;
// marked[v] = has
vertex v been marked?
private int[] edgeTo;
// edgeTo[v] =
previous vertex on path to v
private boolean[] onStack;
// onStack[v] = is
vertex on the stack?
private Stack<Integer> cycle;
// directed cycle (or
null if no such cycle)
/**
* Determines whether the digraph <tt>G</tt> has a
directed cycle and, if so,
* finds such a cycle.
* @param G the digraph
*/
public DirectedCycle(Digraph G) {
marked = new boolean[G.V()];
onStack = new boolean[G.V()];
edgeTo = new int[G.V()];
for (int v = 0; v < G.V(); v++)
if (!marked[v]) dfs(G, v);
}
// check that algorithm computes either the topological
order or finds a directed cycle
private void dfs(Digraph G, int v) {
onStack[v] = true;

marked[v] = true;
for (int w : G.adj(v)) {
// short circuit if directed cycle found
if (cycle != null) return;
//found new vertex, so recur
else if (!marked[w]) {
edgeTo[w] = v;
dfs(G, w);
}
// trace back directed cycle
else if (onStack[w]) {
cycle = new Stack<Integer>();
for (int x = v; x != w; x = edgeTo[x]) {
cycle.push(x);
}
cycle.push(w);
cycle.push(v);
}
}
onStack[v] = false;
}
/**
* Does the digraph have a directed cycle?
* @return <tt>true</tt> if the digraph has a directed
cycle, <tt>false</tt> otherwise
*/
public boolean hasCycle() {
return cycle != null;
}
/**
* Returns a directed cycle if the digraph has a
directed cycle, and <tt>null</tt> otherwise.
* @return a directed cycle (as an iterable) if the
digraph has a directed cycle,
*
and <tt>null</tt> otherwise
*/
public Iterable<Integer> cycle() {
return cycle;
}

// certify that digraph is either acyclic or has a


directed cycle
private boolean check(Digraph G) {
if (hasCycle()) {
// verify cycle
int first = -1, last = -1;
for (int v : cycle()) {
if (first == -1) first = v;
last = v;
}
if (first != last) {
System.err.printf("cycle begins with %d and
ends with %d\n", first, last);
return false;
}
}
return true;
}
/**
* Unit tests the <tt>DirectedCycle</tt> data type.
*/
public static void main(String[] args) {
In in = new In(args[0]);
Digraph G = new Digraph(in);
DirectedCycle finder = new DirectedCycle(G);
if (finder.hasCycle()) {
StdOut.print("Cycle: ");
for (int v : finder.cycle()) {
StdOut.print(v + " ");
}
StdOut.println();
}
else {
StdOut.println("No cycle");
}
}
}

Copyright 20022010, Robert Sedgewick and Kevin Wayne.


Last updated: Sun Oct 20 07:00:47 EDT 2013.

DepthFirstOrder.java

Below is the syntax highlighted version


of DepthFirstOrder.java from 4.2 Directed Graphs.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac DepthFirstOrder.java
* Execution:
java DepthFirstOrder filename.txt
* Dependencies: Digraph.java Queue.java Stack.java
StdOut.java
*
EdgeWeightedDigraph.java
DirectedEdge.java
* Data files:
http://algs4.cs.princeton.edu/42directed/tinyDAG.txt
*
http://algs4.cs.princeton.edu/42directed/tinyDG.txt
*
* Compute preorder and postorder for a digraph or edgeweighted digraph.
* Runs in O(E + V) time.
*
* % java DepthFirstOrder tinyDAG.txt
*
v pre post
* -------------*
0
0
8
*
1
3
2
*
2
9
10
*
3
10
9
*
4
2
0
*
5
1
1
*
6
4
7
*
7
11
11
*
8
12
12
*
9
5
6
*
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
*

***********************************************************
**************/
/**
* The <tt>DepthFirstOrder</tt> 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.
* <p>
* This implementation uses depth-first search.
* The constructor takes time proportional to <em>V</em> +
<em>E</em>
* (in the worst case),
* where <em>V</em> is the number of vertices and
<em>E</em> is the number of edges.
* Afterwards, the <em>preorder</em>, <em>postorder</em>,
and <em>reverse postorder</em>
* operation takes take time proportional to <em>V</em>.
* <p>
* <p>
* For additional documentation, see <a
href="/algs4/42digraph">Section 4.2</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class DepthFirstOrder {
private boolean[] marked;
// marked[v] = has v
been marked in dfs?
private int[] pre;
// pre[v]
=
preorder number of v
private int[] post;
// post[v]
=
postorder number of v
private Queue<Integer> preorder;
// vertices in
preorder
private Queue<Integer> postorder; // vertices in
postorder
private int preCounter;
// counter or
preorder numbering
private int postCounter;
// counter for
postorder numbering

/**
* Determines a depth-first order for the digraph
<tt>G</tt>.
* @param G the digraph
*/
public DepthFirstOrder(Digraph G) {
pre
= new int[G.V()];
post
= new int[G.V()];
postorder = new Queue<Integer>();
preorder = new Queue<Integer>();
marked
= new boolean[G.V()];
for (int v = 0; v < G.V(); v++)
if (!marked[v]) dfs(G, v);
}
/**
* Determines a depth-first order for the edge-weighted
digraph <tt>G</tt>.
* @param G the edge-weighted digraph
*/
public DepthFirstOrder(EdgeWeightedDigraph G) {
pre
= new int[G.V()];
post
= new int[G.V()];
postorder = new Queue<Integer>();
preorder = new Queue<Integer>();
marked
= new boolean[G.V()];
for (int v = 0; v < G.V(); v++)
if (!marked[v]) dfs(G, v);
}
// run DFS in digraph G from vertex v and compute
preorder/postorder
private void dfs(Digraph G, int v) {
marked[v] = true;
pre[v] = preCounter++;
preorder.enqueue(v);
for (int w : G.adj(v)) {
if (!marked[w]) {
dfs(G, w);
}
}
postorder.enqueue(v);
post[v] = postCounter++;
}
// run DFS in edge-weighted digraph G from vertex v and
compute preorder/postorder

private void dfs(EdgeWeightedDigraph G, int v) {


marked[v] = true;
pre[v] = preCounter++;
preorder.enqueue(v);
for (DirectedEdge e : G.adj(v)) {
int w = e.to();
if (!marked[w]) {
dfs(G, w);
}
}
postorder.enqueue(v);
post[v] = postCounter++;
}
/**
* Returns the preorder number of vertex <tt>v</tt>.
* @param v the vertex
* @return the preorder number of vertex <tt>v</tt>
*/
public int pre(int v) {
return pre[v];
}
/**
* Returns the postorder number of vertex <tt>v</tt>.
* @param v the vertex
* @return the postorder number of vertex <tt>v</tt>
*/
public int post(int v) {
return post[v];
}
/**
* Returns the vertices in postorder.
* @return the vertices in postorder, as an iterable of
vertices
*/
public Iterable<Integer> post() {
return postorder;
}
/**
* Returns the vertices in preorder.
* @return the vertices in preorder, as an iterable of
vertices
*/
public Iterable<Integer> pre() {

return preorder;
}
/**
* Returns the vertices in reverse postorder.
* @return the vertices in reverse postorder, as an
iterable of vertices
*/
public Iterable<Integer> reversePost() {
Stack<Integer> reverse = new Stack<Integer>();
for (int v : postorder)
reverse.push(v);
return reverse;
}
// check that pre() and post() are consistent with
pre(v) and post(v)
private boolean check(Digraph G) {
// check that post(v) is consistent with post()
int r = 0;
for (int v : post()) {
if (post(v) != r) {
StdOut.println("post(v) and post()
inconsistent");
return false;
}
r++;
}
// check that pre(v) is consistent with pre()
r = 0;
for (int v : pre()) {
if (pre(v) != r) {
StdOut.println("pre(v) and pre()
inconsistent");
return false;
}
r++;
}
return true;
}
/**

* Unit tests the <tt>DepthFirstOrder</tt> data type.


*/
public static void main(String[] args) {
In in = new In(args[0]);
Digraph G = new Digraph(in);
DepthFirstOrder dfs = new DepthFirstOrder(G);
StdOut.println("
v pre post");
StdOut.println("--------------");
for (int v = 0; v < G.V(); v++) {
StdOut.printf("%4d %4d %4d\n", v, dfs.pre(v),
dfs.post(v));
}
StdOut.print("Preorder: ");
for (int v : dfs.pre()) {
StdOut.print(v + " ");
}
StdOut.println();
StdOut.print("Postorder: ");
for (int v : dfs.post()) {
StdOut.print(v + " ");
}
StdOut.println();
StdOut.print("Reverse postorder: ");
for (int v : dfs.reversePost()) {
StdOut.print(v + " ");
}
StdOut.println();
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Sun Oct 20 18:35:27 EDT 2013.

Topological.java

Below is the syntax highlighted version


of Topological.java from 4.2 Directed Graphs.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac Topoological.java
* Execution:
java Topological filename.txt separator
* Dependencies: Digraph.java DepthFirstOrder.java
DirectedCycle.java
*
EdgeWeightedDigraph.java
EdgeWeightedDirectedCycle.java
*
SymbolDigraph.java
* Data files:
http://algs4.cs.princeton.edu/42directed/jobs.txt
*
* Compute topological ordering of a DAG or edge-weighted
DAG.
* Runs in O(E + V) time.
*
* % java Topological jobs.txt "/"
* Calculus
* Linear Algebra
* Introduction to CS
* Programming Systems
* Algorithms
* Theoretical CS
* Artificial Intelligence
* Machine Learning
* Neural Networks
* Robotics
* Scientific Computing
* Computational Biology
* Databases
*
*
***********************************************************
**************/
/**
* The <tt>Topological</tt> class represents a data type
for

* determining a topological order of a directed acyclic


graph (DAG).
* Recall, a digraph has a topological order if and only
if it is a DAG.
* The <em>hasOrder</em> operation determines whether the
digraph has
* a topological order, and if so, the <em>order</em>
operation
* returns one.
* <p>
* This implementation uses depth-first search.
* The constructor takes time proportional to <em>V</em> +
<em>E</em>
* (in the worst case),
* where <em>V</em> is the number of vertices and
<em>E</em> is the number of edges.
* Afterwards, the <em>hasOrder</em> operation takes
constant time;
* the <em>order</em> operation takes time proportional to
<em>V</em>.
* <p>
* See {@link DirectedCycle} and {@link
EdgeWeightedDirectedCycle} to compute a
* directed cycle if the digraph is not a DAG.
* <p>
* For additional documentation, see <a
href="/algs4/42digraph">Section 4.2</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class Topological {
private Iterable<Integer> order;
// topological
order
/**
* Determines whether the digraph <tt>G</tt> has a
topological order and, if so,
* finds such a topological order.
* @param G the digraph
*/
public Topological(Digraph G) {
DirectedCycle finder = new DirectedCycle(G);
if (!finder.hasCycle()) {
DepthFirstOrder dfs = new DepthFirstOrder(G);

order = dfs.reversePost();
}
}
/**
* Determines whether the edge-weighted digraph
<tt>G</tt> has a topological
* order and, if so, finds such an order.
* @param G the edge-weighted digraph
*/
public Topological(EdgeWeightedDigraph G) {
EdgeWeightedDirectedCycle finder = new
EdgeWeightedDirectedCycle(G);
if (!finder.hasCycle()) {
DepthFirstOrder dfs = new DepthFirstOrder(G);
order = dfs.reversePost();
}
}
/**
* Returns a topological order if the digraph has a
topologial order,
* and <tt>null</tt> otherwise.
* @return a topological order of the vertices (as an
interable) if the
*
digraph has a topological order (or equivalently,
if the digraph is a DAG),
*
and <tt>null</tt> otherwise
*/
public Iterable<Integer> order() {
return order;
}
/**
* Does the digraph have a topological order?
* @return <tt>true</tt> if the digraph has a
topological order (or equivalently,
*
if the digraph is a DAG), and <tt>false</tt>
otherwise
*/
public boolean hasOrder() {
return order != null;
}
/**
* Unit tests the <tt>Topological</tt> data type.
*/

public static void main(String[] args) {


String filename = args[0];
String delimiter = args[1];
SymbolDigraph sg = new SymbolDigraph(filename,
delimiter);
Topological topological = new Topological(sg.G());
for (int v : topological.order()) {
StdOut.println(sg.name(v));
}
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Thu Jul 23 17:05:46 EDT 2015.

BreadthFirstDirectedPaths.java

Below is the syntax highlighted version


of BreadthFirstDirectedPaths.java from 4.2 Directed Graphs.
Here is the Javadoc.

/
***********************************************************
**************
* Compilation: javac BreadthFirstDirectedPaths.java
* Execution:
java BreadthFirstDirectedPaths V E
* Dependencies: Digraph.java Queue.java Stack.java
*
* Run breadth first search on a digraph.
* Runs in O(E + V) time.
*
* % java BreadthFirstDirectedPaths tinyDG.txt 3
* 3 to 0 (2): 3->2->0
* 3 to 1 (3): 3->2->0->1
* 3 to 2 (1): 3->2
* 3 to 3 (0): 3
* 3 to 4 (2): 3->5->4
* 3 to 5 (1): 3->5
* 3 to 6 (-): not connected
* 3 to 7 (-): not connected
* 3 to 8 (-): not connected
* 3 to 9 (-): not connected
* 3 to 10 (-): not connected
* 3 to 11 (-): not connected
* 3 to 12 (-): not connected
*
***********************************************************
**************/
/**
* The <tt>BreadthDirectedFirstPaths</tt> class represents
a data type for finding
* shortest paths (number of edges) from a source vertex
<em>s</em>
* (or set of source vertices) to every other vertex in
the digraph.
* <p>
* This implementation uses breadth-first search.
* The constructor takes time proportional to <em>V</em> +
<em>E</em>,

* where <em>V</em> is the number of vertices and


<em>E</em> is the number of edges.
* It uses extra space (not including the digraph)
proportional to <em>V</em>.
* <p>
* For additional documentation, see <a
href="/algs4/41graph">Section 4.1</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class BreadthFirstDirectedPaths {
private static final int INFINITY = Integer.MAX_VALUE;
private boolean[] marked; // marked[v] = is there an
s->v path?
private int[] edgeTo;
// edgeTo[v] = last edge on
shortest s->v path
private int[] distTo;
// distTo[v] = length of
shortest s->v path
/**
* Computes the shortest path from <tt>s</tt> and every
other vertex in graph <tt>G</tt>.
* @param G the digraph
* @param s the source vertex
*/
public BreadthFirstDirectedPaths(Digraph G, int s) {
marked = new boolean[G.V()];
distTo = new int[G.V()];
edgeTo = new int[G.V()];
for (int v = 0; v < G.V(); v++)
distTo[v] = INFINITY;
bfs(G, s);
}
/**
* Computes the shortest path from any one of the
source vertices in <tt>sources</tt>
* to every other vertex in graph <tt>G</tt>.
* @param G the digraph
* @param sources the source vertices
*/
public BreadthFirstDirectedPaths(Digraph G,
Iterable<Integer> sources) {
marked = new boolean[G.V()];

distTo = new int[G.V()];


edgeTo = new int[G.V()];
for (int v = 0; v < G.V(); v++)
distTo[v] = INFINITY;
bfs(G, sources);
}
// BFS from single source
private void bfs(Digraph G, int s) {
Queue<Integer> q = new Queue<Integer>();
marked[s] = true;
distTo[s] = 0;
q.enqueue(s);
while (!q.isEmpty()) {
int v = q.dequeue();
for (int w : G.adj(v)) {
if (!marked[w]) {
edgeTo[w] = v;
distTo[w] = distTo[v] + 1;
marked[w] = true;
q.enqueue(w);
}
}
}
}
// BFS from multiple sources
private void bfs(Digraph G, Iterable<Integer> sources) {
Queue<Integer> q = new Queue<Integer>();
for (int s : sources) {
marked[s] = true;
distTo[s] = 0;
q.enqueue(s);
}
while (!q.isEmpty()) {
int v = q.dequeue();
for (int w : G.adj(v)) {
if (!marked[w]) {
edgeTo[w] = v;
distTo[w] = distTo[v] + 1;
marked[w] = true;
q.enqueue(w);
}
}
}
}

/**
* Is there a directed path from the source <tt>s</tt>
(or sources) to vertex <tt>v</tt>?
* @param v the vertex
* @return <tt>true</tt> if there is a directed path,
<tt>false</tt> otherwise
*/
public boolean hasPathTo(int v) {
return marked[v];
}
/**
* Returns the number of edges in a shortest path from
the source <tt>s</tt>
* (or sources) to vertex <tt>v</tt>?
* @param v the vertex
* @return the number of edges in a shortest path
*/
public int distTo(int v) {
return distTo[v];
}
/**
* Returns a shortest path from <tt>s</tt> (or sources)
to <tt>v</tt>, or
* <tt>null</tt> if no such path.
* @param v the vertex
* @return the sequence of vertices on a shortest path,
as an Iterable
*/
public Iterable<Integer> pathTo(int v) {
if (!hasPathTo(v)) return null;
Stack<Integer> path = new Stack<Integer>();
int x;
for (x = v; distTo[x] != 0; x = edgeTo[x])
path.push(x);
path.push(x);
return path;
}
/**
* Unit tests the <tt>BreadthFirstDirectedPaths</tt>
data type.
*/
public static void main(String[] args) {
In in = new In(args[0]);
Digraph G = new Digraph(in);

// StdOut.println(G);
int s = Integer.parseInt(args[1]);
BreadthFirstDirectedPaths bfs = new
BreadthFirstDirectedPaths(G, s);
for (int v = 0; v < G.V(); v++) {
if (bfs.hasPathTo(v)) {
StdOut.printf("%d to %d (%d): ", s, v,
bfs.distTo(v));
for (int x : bfs.pathTo(v)) {
if (x == s) StdOut.print(x);
else
StdOut.print("->" + x);
}
StdOut.println();
}
else {
StdOut.printf("%d to %d (-):
connected\n", s, v);
}

not

}
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Thu Jul 23 17:05:46 EDT 2015.

TransitiveClosure.java
Below is the syntax highlighted version
of TransitiveClosure.java from 4.2 Directed Graphs.
is the Javadoc.

Here

/
***********************************************************
**************
* Compilation: javac TransitiveClosure.java
* Execution:
java TransitiveClosure filename.txt
* Dependencies: Digraph.java DepthFirstDirectedPaths.java
In.java StdOut.java
* Data files:
http://algs4.cs.princeton.edu/42directed/tinyDG.txt
*
* Compute transitive closure of a digraph and support
* reachability queries.
*
* Preprocessing time: O(V(E + V)) time.
* Query time: O(1).
* Space: O(V^2).
*
* % java TransitiveClosure tinyDG.txt
*
0 1 2 3 4 5 6 7 8 9 10 11 12
* -------------------------------------------*
0:
T T T T T T
*
1:
T
*
2:
T T T T T T
*
3:
T T T T T T
*
4:
T T T T T T
*
5:
T T T T T T
*
6:
T T T T T T T
T T T T
*
7:
T T T T T T T T T T T T T
*
8:
T T T T T T T T T T T T T
*
9:
T T T T T T
T T T T
*
10:
T T T T T T
T T T T
*
11:
T T T T T T
T T T T
*
12:
T T T T T T
T T T T
*
***********************************************************
**************/
/**
* The <tt>TransitiveClosure</tt> class represents a data
type for
* computing the transitive closure of a digraph.
* <p>
* This implementation runs depth-first search from each
vertex.
* The constructor takes time proportional to
<em>V</em>(<em>V</em> + <em>E</em>)

* (in the worst case) and uses space proportional to


<em>V</em><sup>2</sup>,
* where <em>V</em> is the number of vertices and
<em>E</em> is the number of edges.
* <p>
* For additional documentation, see <a
href="/algs4/42digraph">Section 4.2</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class TransitiveClosure {
private DirectedDFS[] tc; // tc[v] = reachable from v
/**
* Computes the transitive closure of the digraph
<tt>G</tt>.
* @param G the digraph
*/
public TransitiveClosure(Digraph G) {
tc = new DirectedDFS[G.V()];
for (int v = 0; v < G.V(); v++)
tc[v] = new DirectedDFS(G, v);
}
/**
* Is there a directed path from vertex <tt>v</tt> to
vertex <tt>w</tt> in the digraph?
* @param v the source vertex
* @param w the target vertex
* @return <tt>true</tt> if there is a directed path
from <tt>v</tt> to <tt>w</tt>,
*
<tt>false</tt> otherwise
*/
public boolean reachable(int v, int w) {
return tc[v].marked(w);
}
/**
* Unit tests the <tt>TransitiveClosure</tt> data type.
*/
public static void main(String[] args) {
In in = new In(args[0]);
Digraph G = new Digraph(in);

TransitiveClosure tc = new TransitiveClosure(G);


// print header
StdOut.print("
");
for (int v = 0; v < G.V(); v++)
StdOut.printf("%3d", v);
StdOut.println();
StdOut.println("-------------------------------------------");
// print transitive closure
for (int v = 0; v < G.V(); v++) {
StdOut.printf("%3d: ", v);
for (int w = 0; w < G.V(); w++) {
if (tc.reachable(v, w)) StdOut.printf("
T");
else

StdOut.printf("

");
}
StdOut.println();
}
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Sun Oct 20 18:41:17 EDT 2013.

SymbolDigraph.java
Below is the syntax highlighted version
of SymbolDigraph.java from 4.2 Directed Graphs.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac SymbolDigraph.java
* Execution:
java SymbolDigraph
* Dependencies: ST.java Digraph.java In.java
*
* % java SymbolDigraph routes.txt " "
* JFK
*
MCO
*
ATL
*
ORD
* ATL
*
HOU
*
MCO
* LAX
*
***********************************************************
**************/
/**
* The <tt>SymbolDigraph</tt> class represents a digraph,
where the
* vertex names are arbitrary strings.
* By providing mappings between string vertex names and
integers,
* it serves as a wrapper around the
* {@link Digraph} data type, which assumes the vertex
names are integers
* between 0 and <em>V</em> - 1.
* It also supports initializing a symbol digraph from a
file.
* <p>
* This implementation uses an {@link ST} to map from
strings to integers,
* an array to map from integers to strings, and a {@link
Digraph} to store
* the underlying graph.
* The <em>index</em> and <em>contains</em> operations
take time
* proportional to log <em>V</em>, where <em>V</em> is the
number of vertices.
* The <em>name</em> operation takes constant time.
* <p>

* For additional documentation, see <a


href="http://algs4.cs.princeton.edu/42digraph">Section
4.2</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class SymbolDigraph {
private ST<String, Integer> st; // string -> index
private String[] keys;
// index -> string
private Digraph G;
/**
* Initializes a digraph from a file using the
specified delimiter.
* Each line in the file contains
* the name of a vertex, followed by a list of the
names
* of the vertices adjacent to that vertex, separated
by the delimiter.
* @param filename the name of the file
* @param delimiter the delimiter between fields
*/
public SymbolDigraph(String filename, String delimiter)
{
st = new ST<String, Integer>();
// First pass builds the index by reading strings
to associate
// distinct strings with an index
In in = new In(filename);
while (in.hasNextLine()) {
String[] a = in.readLine().split(delimiter);
for (int i = 0; i < a.length; i++) {
if (!st.contains(a[i]))
st.put(a[i], st.size());
}
}
// inverted index to get string keys in an aray
keys = new String[st.size()];
for (String name : st.keys()) {
keys[st.get(name)] = name;
}

// second pass builds the digraph by connecting


first vertex on each
// line to all others
G = new Digraph(st.size());
in = new In(filename);
while (in.hasNextLine()) {
String[] a = in.readLine().split(delimiter);
int v = st.get(a[0]);
for (int i = 1; i < a.length; i++) {
int w = st.get(a[i]);
G.addEdge(v, w);
}
}
}
/**
* Does the digraph contain the vertex named
<tt>s</tt>?
* @param s the name of a vertex
* @return <tt>true</tt> if <tt>s</tt> is the name of a
vertex, and <tt>false</tt> otherwise
*/
public boolean contains(String s) {
return st.contains(s);
}
/**
* Returns the integer associated with the vertex named
<tt>s</tt>.
* @param s the name of a vertex
* @return the integer (between 0 and <em>V</em> - 1)
associated with the vertex named <tt>s</tt>
*/
public int index(String s) {
return st.get(s);
}
/**
* Returns the name of the vertex associated with the
integer <tt>v</tt>.
* @param v the integer corresponding to a vertex
(between 0 and <em>V</em> - 1)
* @return the name of the vertex associated with the
integer <tt>v</tt>
*/
public String name(int v) {
return keys[v];

}
/**
* Returns the digraph assoicated with the symbol
graph. It is the client's responsibility
* not to mutate the digraph.
* @return the digraph associated with the symbol
digraph
*/
public Digraph G() {
return G;
}
/**
* Unit tests the <tt>SymbolDigraph</tt> data type.
*/
public static void main(String[] args) {
String filename = args[0];
String delimiter = args[1];
SymbolDigraph sg = new SymbolDigraph(filename,
delimiter);
Digraph G = sg.G();
while (!StdIn.isEmpty()) {
String t = StdIn.readLine();
for (int v : G.adj(sg.index(t))) {
StdOut.println("
" + sg.name(v));
}
}
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Mon Oct 21 16:58:27 EDT 2013.

KosarajuSharirSCC.java
Below is the syntax highlighted version

of KosarajuSharirSCC.java from 4.2 Directed Graphs.


is the Javadoc.

Here

/
***********************************************************
**************
* Compilation: javac KosarajuSharirSCC.java
* Execution:
java KosarajuSharirSCC filename.txt
* Dependencies: Digraph.java TransitiveClosure.java
StdOut.java In.java
* Data files:
http://algs4.cs.princeton.edu/42directed/tinyDG.txt
*
* Compute the strongly-connected components of a digraph
using the
* Kosaraju-Sharir algorithm.
*
* Runs in O(E + V) time.
*
* % java KosarajuSCC tinyDG.txt
* 5 components
* 1
* 0 2 3 4 5
* 9 10 11 12
* 6 8
* 7
*
* % java KosarajuSharirSCC mediumDG.txt
* 10 components
* 21
* 2 5 6 8 9 11 12 13 15 16 18 19 22 23 25 26 28 29 30 31
32 33 34 35 37 38 39 40 42 43 44 46 47 48 49
* 14
* 3 4 17 20 24 27 36
* 41
* 7
* 45
* 1
* 0
* 10
*
* % java -Xss50m KosarajuSharirSCC mediumDG.txt
* 25 components
* 7 11 32 36 61 84 95 116 121 128 230
...
* 28 73 80 104 115 143 149 164 184 185 ...

*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*

38 40 200 201 207 218 286 387 418 422


12 14 56 78 87 103 216 269 271 272
42 48 112 135 160 217 243 246 273 346
46 76 96 97 224 237 297 303 308 309
9 15 21 22 27 90 167 214 220 225 227
74 99 133 146 161 166 202 205 245 262
43 83 94 120 125 183 195 206 244 254
1 13 54 91 92 93 106 140 156 194 208
10 39 67 69 131 144 145 154 168 258
6 52 66 113 118 122 139 147 212 213
8 127 150 182 203 204 249 367 400 432
63 65 101 107 108 136 169 170 171 173
55 71 102 155 159 198 228 252 325 419
4 25 34 58 70 152 172 196 199 210 226
2 44 50 88 109 138 141 178 197 211
57 89 129 162 174 179 188 209 238 276
33 41 49 119 126 132 148 181 215 221
3 18 23 26 35 64 105 124 157 186 251
5 16 17 20 31 47 81 98 158 180 187
24 29 51 59 75 82 100 114 117 134 151
30 45 53 60 72 85 111 130 137 142 163
19 37 62 77 79 110 153 352 353 361
0 68 86 123 165 176 193 239 289 336

...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...

***********************************************************
**************/
/**
* The <tt>KosarajuSharirSCC</tt> class represents a data
type for
* determining the strong components in a digraph.
* The <em>id</em> operation determines in which strong
component
* a given vertex lies; the <em>areStronglyConnected</em>
operation
* determines whether two vertices are in the same strong
component;
* and the <em>count</em> operation determines the number
of strong
* components.
* The <em>component identifier</em> 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.
* <p>
* This implementation uses the Kosaraju-Sharir algorithm.
* The constructor takes time proportional to <em>V</em> +
<em>E</em>
* (in the worst case),
* where <em>V</em> is the number of vertices and
<em>E</em> is the number of edges.
* Afterwards, the <em>id</em>, <em>count</em>, and
<em>areStronglyConnected</em>
* operations take constant time.
* For alternate implementations of the same API, see
* {@link TarjanSCC} and {@link GabowSCC}.
* <p>
* For additional documentation, see <a
href="/algs4/42digraph">Section 4.2</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class KosarajuSharirSCC {
private boolean[] marked;
// marked[v] = has vertex
v been visited?
private int[] id;
// id[v] = id of strong
component containing v
private int count;
// number of stronglyconnected components
/**
* Computes the strong components of the digraph
<tt>G</tt>.
* @param G the digraph
*/
public KosarajuSharirSCC(Digraph G) {
// compute reverse postorder of reverse graph
DepthFirstOrder dfs = new
DepthFirstOrder(G.reverse());
// run DFS on G, using reverse postorder to guide
calculation
marked = new boolean[G.V()];
id = new int[G.V()];

for (int v : dfs.reversePost()) {


if (!marked[v]) {
dfs(G, v);
count++;
}
}
// check that id[] gives strong components
assert check(G);
}
// DFS on graph G
private void dfs(Digraph G, int v) {
marked[v] = true;
id[v] = count;
for (int w : G.adj(v)) {
if (!marked[w]) dfs(G, w);
}
}
/**
* Returns
* @return
*/
public int
return
}

the number of strong components.


the number of strong components
count() {
count;

/**
* Are vertices <tt>v</tt> and <tt>w</tt> in the same
strong component?
* @param v one vertex
* @param w the other vertex
* @return <tt>true</tt> if vertices <tt>v</tt> and
<tt>w</tt> are in the same
*
strong component, and <tt>false</tt> otherwise
*/
public boolean stronglyConnected(int v, int w) {
return id[v] == id[w];
}
/**
* Returns the component id of the strong component
containing vertex <tt>v</tt>.
* @param v the vertex
* @return the component id of the strong component
containing vertex <tt>v</tt>

*/
public int id(int v) {
return id[v];
}
// does the id[] array contain the strongly connected
components?
private boolean check(Digraph G) {
TransitiveClosure tc = new TransitiveClosure(G);
for (int v = 0; v < G.V(); v++) {
for (int w = 0; w < G.V(); w++) {
if (stronglyConnected(v, w) !=
(tc.reachable(v, w) && tc.reachable(w, v)))
return false;
}
}
return true;
}
/**
* Unit tests the <tt>KosarajuSharirSCC</tt> data type.
*/
public static void main(String[] args) {
In in = new In(args[0]);
Digraph G = new Digraph(in);
KosarajuSharirSCC scc = new KosarajuSharirSCC(G);
// number of connected components
int M = scc.count();
StdOut.println(M + " components");
// compute list of vertices in each strong
component
Queue<Integer>[] components = (Queue<Integer>[]) new
Queue[M];
for (int i = 0; i < M; i++) {
components[i] = new Queue<Integer>();
}
for (int v = 0; v < G.V(); v++) {
components[scc.id(v)].enqueue(v);
}
// print results
for (int i = 0; i < M; i++) {
for (int v : components[i]) {
StdOut.print(v + " ");
}

StdOut.println();
}
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Wed Mar 5 17:30:33 EST 2014.
TarjanSCC.java
Below is the syntax highlighted version
of TarjanSCC.java from 4.2 Directed Graphs.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac TarjanSCC.java
* Execution:
Java TarjanSCC V E
* Dependencies: Digraph.java Stack.java
TransitiveClosure.java StdOut.java
*
* Compute the strongly-connected components of a digraph
using
* Tarjan's algorithm.
*
* Runs in O(E + V) time.
*
* % java TarjanSCC tinyDG.txt
* 5 components
* 1
* 0 2 3 4 5
* 9 10 11 12
* 6 8
* 7
*
***********************************************************
**************/
/**
* The <tt>TarjanSCC</tt> class represents a data type for

* determining the strong components in a digraph.


* The <em>id</em> operation determines in which strong
component
* a given vertex lies; the <em>areStronglyConnected</em>
operation
* determines whether two vertices are in the same strong
component;
* and the <em>count</em> operation determines the number
of strong
* components.
* The <em>component identifier</em> 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.
* <p>
* This implementation uses Tarjan's algorithm.
* The constructor takes time proportional to <em>V</em> +
<em>E</em>
* (in the worst case),
* where <em>V</em> is the number of vertices and
<em>E</em> is the number of edges.
* Afterwards, the <em>id</em>, <em>count</em>, and
<em>areStronglyConnected</em>
* operations take constant time.
* For alternate implementations of the same API, see
* {@link KosarajuSharirSCC} and {@link GabowSCC}.
* <p>
* For additional documentation, see <a
href="/algs4/42digraph">Section 4.2</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class TarjanSCC {
private boolean[] marked;
been visited?
private int[] id;
strong component containing v
private int[] low;
of v

// marked[v] = has v
// id[v] = id of
// low[v] = low number

private int pre;


counter
private int count;
connected components
private Stack<Integer> stack;

// preorder number
// number of strongly-

/**
* Computes the strong components of the digraph
<tt>G</tt>.
* @param G the digraph
*/
public TarjanSCC(Digraph G) {
marked = new boolean[G.V()];
stack = new Stack<Integer>();
id = new int[G.V()];
low = new int[G.V()];
for (int v = 0; v < G.V(); v++) {
if (!marked[v]) dfs(G, v);
}
// check that id[] gives strong components
assert check(G);
}
private void dfs(Digraph G, int v) {
marked[v] = true;
low[v] = pre++;
int min = low[v];
stack.push(v);
for (int w : G.adj(v)) {
if (!marked[w]) dfs(G, w);
if (low[w] < min) min = low[w];
}
if (min < low[v]) {
low[v] = min;
return;
}
int w;
do {
w = stack.pop();
id[w] = count;
low[w] = G.V();
} while (w != v);
count++;
}

/**
* Returns
* @return
*/
public int
return
}

the number of strong components.


the number of strong components
count() {
count;

/**
* Are vertices <tt>v</tt> and <tt>w</tt> in the same
strong component?
* @param v one vertex
* @param w the other vertex
* @return <tt>true</tt> if vertices <tt>v</tt> and
<tt>w</tt> are in the same
*
strong component, and <tt>false</tt> otherwise
*/
public boolean stronglyConnected(int v, int w) {
return id[v] == id[w];
}
/**
* Returns the component id of the strong component
containing vertex <tt>v</tt>.
* @param v the vertex
* @return the component id of the strong component
containing vertex <tt>v</tt>
*/
public int id(int v) {
return id[v];
}
// does the id[] array contain the strongly connected
components?
private boolean check(Digraph G) {
TransitiveClosure tc = new TransitiveClosure(G);
for (int v = 0; v < G.V(); v++) {
for (int w = 0; w < G.V(); w++) {
if (stronglyConnected(v, w) !=
(tc.reachable(v, w) && tc.reachable(w, v)))
return false;
}
}
return true;
}

/**
* Unit tests the <tt>TarjanSCC</tt> data type.
*/
public static void main(String[] args) {
In in = new In(args[0]);
Digraph G = new Digraph(in);
TarjanSCC scc = new TarjanSCC(G);
// number of connected components
int M = scc.count();
StdOut.println(M + " components");
// compute list of vertices in each strong
component
Queue<Integer>[] components = (Queue<Integer>[]) new
Queue[M];
for (int i = 0; i < M; i++) {
components[i] = new Queue<Integer>();
}
for (int v = 0; v < G.V(); v++) {
components[scc.id(v)].enqueue(v);
}
// print results
for (int i = 0; i < M; i++) {
for (int v : components[i]) {
StdOut.print(v + " ");
}
StdOut.println();
}
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Tue Jul 28 06:21:05 EDT 2015.
GabowSCC.java
Below is the syntax highlighted version
of GabowSCC.java from 4.2 Directed Graphs.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac GabowSCC.java
* Execution:
java GabowSCC V E
* Dependencies: Digraph.java Stack.java
TransitiveClosure.java StdOut.java
*
* 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
* 0 2 3 4 5
* 9 10 11 12
* 6 8
* 7
*
***********************************************************
**************/
/**
* The <tt>GabowSCC</tt> class represents a data type for
* determining the strong components in a digraph.
* The <em>id</em> operation determines in which strong
component
* a given vertex lies; the <em>areStronglyConnected</em>
operation
* determines whether two vertices are in the same strong
component;
* and the <em>count</em> operation determines the number
of strong
* components.
* The <em>component identifier</em> 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.
*
*

<p>
This implementation uses the Gabow's algorithm.

* The constructor takes time proportional to <em>V</em> +


<em>E</em>
* (in the worst case),
* where <em>V</em> is the number of vertices and
<em>E</em> is the number of edges.
* Afterwards, the <em>id</em>, <em>count</em>, and
<em>areStronglyConnected</em>
* operations take constant time.
* For alternate implementations of the same API, see
* {@link KosarajuSharirSCC} and {@link TarjanSCC}.
* <p>
* For additional documentation, see <a
href="/algs4/42digraph">Section 4.2</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class GabowSCC {
private boolean[] marked;
been visited?
private int[] id;
strong component containing v
private int[] preorder;
preorder of v
private int pre;
counter
private int count;
connected components
private Stack<Integer> stack1;
private Stack<Integer> stack2;

// marked[v] = has v
// id[v] = id of
// preorder[v] =
// preorder number
// number of strongly-

/**
* Computes the strong components of the digraph
<tt>G</tt>.
* @param G the digraph
*/
public GabowSCC(Digraph G) {
marked = new boolean[G.V()];
stack1 = new Stack<Integer>();
stack2 = new Stack<Integer>();
id = new int[G.V()];
preorder = new int[G.V()];
for (int v = 0; v < G.V(); v++)

id[v] = -1;
for (int v = 0; v < G.V(); v++) {
if (!marked[v]) dfs(G, v);
}
// check that id[] gives strong components
assert check(G);
}
private void dfs(Digraph G, int v) {
marked[v] = true;
preorder[v] = pre++;
stack1.push(v);
stack2.push(v);
for (int w : G.adj(v)) {
if (!marked[w]) dfs(G, w);
else if (id[w] == -1) {
while (preorder[stack2.peek()] >
preorder[w])
stack2.pop();
}
}
// found strong component containing v
if (stack2.peek() == v) {
stack2.pop();
int w;
do {
w = stack1.pop();
id[w] = count;
} while (w != v);
count++;
}
}
/**
* Returns
* @return
*/
public int
return
}

the number of strong components.


the number of strong components
count() {
count;

/**
* Are vertices <tt>v</tt> and <tt>w</tt> in the same
strong component?

* @param v one vertex


* @param w the other vertex
* @return <tt>true</tt> if vertices <tt>v</tt> and
<tt>w</tt> are in the same
*
strong component, and <tt>false</tt> otherwise
*/
public boolean stronglyConnected(int v, int w) {
return id[v] == id[w];
}
/**
* Returns the component id of the strong component
containing vertex <tt>v</tt>.
* @param v the vertex
* @return the component id of the strong component
containing vertex <tt>v</tt>
*/
public int id(int v) {
return id[v];
}
// does the id[] array contain the strongly connected
components?
private boolean check(Digraph G) {
TransitiveClosure tc = new TransitiveClosure(G);
for (int v = 0; v < G.V(); v++) {
for (int w = 0; w < G.V(); w++) {
if (stronglyConnected(v, w) !=
(tc.reachable(v, w) && tc.reachable(w, v)))
return false;
}
}
return true;
}
/**
* Unit tests the <tt>GabowSCC</tt> data type.
*/
public static void main(String[] args) {
In in = new In(args[0]);
Digraph G = new Digraph(in);
GabowSCC scc = new GabowSCC(G);
// number of connected components
int M = scc.count();
StdOut.println(M + " components");

// compute list of vertices in each strong


component
Queue<Integer>[] components = (Queue<Integer>[]) new
Queue[M];
for (int i = 0; i < M; i++) {
components[i] = new Queue<Integer>();
}
for (int v = 0; v < G.V(); v++) {
components[scc.id(v)].enqueue(v);
}
// print results
for (int i = 0; i < M; i++) {
for (int v : components[i]) {
StdOut.print(v + " ");
}
StdOut.println();
}
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Thu Jul 23 17:05:46 EDT 2015.
EdgeWeightedGraph.java
Below is the syntax highlighted version
of EdgeWeightedGraph.java from Algorithms.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac EdgeWeightedGraph.java
* Execution:
java EdgeWeightedGraph filename.txt
* Dependencies: Bag.java Edge.java In.java StdOut.java
* Data files:
http://algs4.cs.princeton.edu/43mst/tinyEWG.txt
*
* An edge-weighted undirected graph, implemented using
adjacency lists.
* Parallel edges and self-loops are permitted.

*
*
*
*
*
*
2-3
*
*
*
*
*
4-7
*

% java EdgeWeightedGraph tinyEWG.txt


8 16
0: 6-0 0.58000 0-2 0.26000 0-4 0.38000
1: 1-3 0.29000 1-2 0.36000 1-7 0.19000
2: 6-2 0.40000 2-7 0.34000 1-2 0.36000
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
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
7: 2-7 0.34000 1-7 0.19000 0-7 0.16000
0.37000

0-7 0.16000
1-5 0.32000
0-2 0.26000
4-5 0.35000
6-2 0.40000
5-7 0.28000

***********************************************************
**************/
/**
* The <tt>EdgeWeightedGraph</tt> class represents an
edge-weighted
* graph of vertices named 0 through <em>V</em> - 1, where
each
* undirected edge is of type {@link Edge} and has a realvalued 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 <em>V</em>
and the number
* of edges <em>E</em>. Parallel edges and self-loops are
permitted.
* <p>
* 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.
* <p>
* For additional documentation,
* see <a
href="http://algs4.cs.princeton.edu/43mst">Section 4.3</a>
of

* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and


Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class EdgeWeightedGraph {
private static final String NEWLINE =
System.getProperty("line.separator");
private final int V;
private int E;
private Bag<Edge>[] adj;
/**
* Initializes an empty edge-weighted graph with
<tt>V</tt> vertices and 0 edges.
* param V the number of vertices
* @throws java.lang.IllegalArgumentException if
<tt>V</tt> < 0
*/
public EdgeWeightedGraph(int V) {
if (V < 0) throw new
IllegalArgumentException("Number of vertices must be
nonnegative");
this.V = V;
this.E = 0;
adj = (Bag<Edge>[]) new Bag[V];
for (int v = 0; v < V; v++) {
adj[v] = new Bag<Edge>();
}
}
/**
* Initializes a random edge-weighted graph with
<tt>V</tt> vertices and <em>E</em> edges.
* param V the number of vertices
* param E the number of edges
* @throws java.lang.IllegalArgumentException if
<tt>V</tt> < 0
* @throws java.lang.IllegalArgumentException if
<tt>E</tt> < 0
*/
public EdgeWeightedGraph(int V, int E) {
this(V);

if (E < 0) throw new


IllegalArgumentException("Number of edges must be
nonnegative");
for (int i = 0; i < E; i++) {
int v = StdRandom.uniform(V);
int w = StdRandom.uniform(V);
double weight = Math.round(100 *
StdRandom.uniform()) / 100.0;
Edge e = new Edge(v, w, weight);
addEdge(e);
}
}
/**
* Initializes an edge-weighted graph from an input
stream.
* The format is the number of vertices <em>V</em>,
* followed by the number of edges <em>E</em>,
* followed by <em>E</em> pairs of vertices and edge
weights,
* with each entry separated by whitespace.
* @param in the input stream
* @throws java.lang.IndexOutOfBoundsException if the
endpoints of any edge are not in prescribed range
* @throws java.lang.IllegalArgumentException if the
number of vertices or edges is negative
*/
public EdgeWeightedGraph(In in) {
this(in.readInt());
int E = in.readInt();
if (E < 0) throw new
IllegalArgumentException("Number of edges must be
nonnegative");
for (int i = 0; i < E; i++) {
int v = in.readInt();
int w = in.readInt();
double weight = in.readDouble();
Edge e = new Edge(v, w, weight);
addEdge(e);
}
}
/**
* Initializes a new edge-weighted graph that is a deep
copy of <tt>G</tt>.
* @param G the edge-weighted graph to copy
*/

public EdgeWeightedGraph(EdgeWeightedGraph G) {
this(G.V());
this.E = G.E();
for (int v = 0; v < G.V(); v++) {
// reverse so that adjacency list is in same
order as original
Stack<Edge> reverse = new Stack<Edge>();
for (Edge e : G.adj[v]) {
reverse.push(e);
}
for (Edge e : reverse) {
adj[v].add(e);
}
}
}
/**
* Returns
graph.
* @return
graph
*/
public int
return
}
/**
* Returns
graph.
* @return
graph
*/
public int
return
}

the number of vertices in the edge-weighted


the number of vertices in the edge-weighted
V() {
V;

the number of edges in the edge-weighted


the number of edges in the edge-weighted
E() {
E;

// throw an IndexOutOfBoundsException unless 0 <= v < V


private void validateVertex(int v) {
if (v < 0 || v >= V)
throw new IndexOutOfBoundsException("vertex " +
v + " is not between 0 and " + (V-1));
}
/**
* Adds the undirected edge <tt>e</tt> to the edgeweighted graph.

* @param e the edge


* @throws java.lang.IndexOutOfBoundsException unless
both endpoints are between 0 and V-1
*/
public void addEdge(Edge e) {
int v = e.either();
int w = e.other(v);
validateVertex(v);
validateVertex(w);
adj[v].add(e);
adj[w].add(e);
E++;
}
/**
* Returns the edges incident on vertex <tt>v</tt>.
* @param v the vertex
* @return the edges incident on vertex <tt>v</tt> as
an Iterable
* @throws java.lang.IndexOutOfBoundsException unless 0
<= v < V
*/
public Iterable<Edge> adj(int v) {
validateVertex(v);
return adj[v];
}
/**
* Returns the degree of vertex <tt>v</tt>.
* @param v the vertex
* @return the degree of vertex <tt>v</tt>
* @throws java.lang.IndexOutOfBoundsException unless 0
<= v < V
*/
public int degree(int v) {
validateVertex(v);
return adj[v].size();
}
/**
* Returns all edges in the edge-weighted graph.
* To iterate over the edges in the edge-weighted
graph, use foreach notation:
* <tt>for (Edge e : G.edges())</tt>.
* @return all edges in the edge-weighted graph as an
Iterable.
*/

public Iterable<Edge> edges() {


Bag<Edge> list = new Bag<Edge>();
for (int v = 0; v < V; v++) {
int selfLoops = 0;
for (Edge e : adj(v)) {
if (e.other(v) > v) {
list.add(e);
}
// only add one copy of each self loop
(self loops will be consecutive)
else if (e.other(v) == v) {
if (selfLoops % 2 == 0) list.add(e);
selfLoops++;
}
}
}
return list;
}
/**
* Returns a string representation of the edge-weighted
graph.
* This method takes time proportional to <em>E</em> +
<em>V</em>.
* @return the number of vertices <em>V</em>, followed
by the number of edges <em>E</em>,
*
followed by the <em>V</em> adjacency lists of
edges
*/
public String toString() {
StringBuilder s = new StringBuilder();
s.append(V + " " + E + NEWLINE);
for (int v = 0; v < V; v++) {
s.append(v + ": ");
for (Edge e : adj[v]) {
s.append(e + " ");
}
s.append(NEWLINE);
}
return s.toString();
}
/**
* Unit tests the <tt>EdgeWeightedGraph</tt> data type.
*/
public static void main(String[] args) {
In in = new In(args[0]);

EdgeWeightedGraph G = new EdgeWeightedGraph(in);


StdOut.println(G);
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Sun Jul 26 11:21:27 EDT 2015.
Edge.java
Below is the syntax highlighted version of Edge.java from
Algorithms.
Here is the Javadoc.

/
***********************************************************
**************
* Compilation: javac Edge.java
* Execution:
java Edge
* Dependencies: StdOut.java
*
* Immutable weighted edge.
*
***********************************************************
**************/
/**
* The <tt>Edge</tt> 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
* the weight. The natural order for this data type is by
* ascending order of weight.
* <p>
* For additional documentation, see <a
href="http://algs4.cs.princeton.edu/43mst">Section 4.3</a>
of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.

*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class Edge implements Comparable<Edge> {
private final int v;
private final int w;
private final double weight;
/**
* Initializes an edge between vertices <tt>v</tt> and
<tt>w</tt> of
* the given <tt>weight</tt>.
* param v one vertex
* param w the other vertex
* param weight the weight of the edge
* @throws IndexOutOfBoundsException if either
<tt>v</tt> or <tt>w</tt>
*
is a negative integer
* @throws IllegalArgumentException if <tt>weight</tt>
is <tt>NaN</tt>
*/
public Edge(int v, int w, double weight) {
if (v < 0) throw new
IndexOutOfBoundsException("Vertex name must be a nonnegative
integer");
if (w < 0) throw new
IndexOutOfBoundsException("Vertex name must be a nonnegative
integer");
if (Double.isNaN(weight)) throw new
IllegalArgumentException("Weight is NaN");
this.v = v;
this.w = w;
this.weight = weight;
}
/**
* Returns the weight of the edge.
* @return the weight of the edge
*/
public double weight() {
return weight;
}
/**
* Returns either endpoint of the edge.

* @return either endpoint of the edge


*/
public int either() {
return v;
}
/**
* Returns the endpoint of the edge that is different
from the given vertex
* (unless the edge represents a self-loop in which
case it returns the same vertex).
* @param vertex one endpoint of the edge
* @return the endpoint of the edge that is different
from the given vertex
*
(unless the edge represents a self-loop in which
case it returns the same vertex)
* @throws java.lang.IllegalArgumentException if the
vertex is not one of the endpoints
*
of the edge
*/
public int other(int vertex) {
if
(vertex == v) return w;
else if (vertex == w) return v;
else throw new IllegalArgumentException("Illegal
endpoint");
}
/**
* Compares two edges by weight.
* @param that the other edge
* @return a negative integer, zero, or positive
integer depending on whether
*
this edge is less than, equal to, or greater than
that edge
*/
public int compareTo(Edge that) {
if
(this.weight() < that.weight()) return -1;
else if (this.weight() > that.weight()) return +1;
else
return 0;
}
/**
* Returns a string representation of the edge.
* @return a string representation of the edge
*/
public String toString() {
return String.format("%d-%d %.5f", v, w, weight);

}
/**
* Unit tests the <tt>Edge</tt> data type.
*/
public static void main(String[] args) {
Edge e = new Edge(12, 34, 5.67);
StdOut.println(e);
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Thu Jul 23 17:05:46 EDT 2015.

LazyPrimMST.java
Below is the syntax highlighted version
of LazyPrimMST.java from 4.3 Minimum Spanning Trees.
is the Javadoc.

Here

/
***********************************************************
**************
* Compilation: javac LazyPrimMST.java
* Execution:
java LazyPrimMST filename.txt
* Dependencies: EdgeWeightedGraph.java Edge.java
Queue.java
*
MinPQ.java UF.java In.java StdOut.java
* Data files:
http://algs4.cs.princeton.edu/43mst/tinyEWG.txt
*
http://algs4.cs.princeton.edu/43mst/mediumEWG.txt
*
http://algs4.cs.princeton.edu/43mst/largeEWG.txt
*
* Compute a minimum spanning forest using a lazy version
of Prim's
* algorithm.
*
* % java LazyPrimMST tinyEWG.txt
* 0-7 0.16000
* 1-7 0.19000
* 0-2 0.26000
* 2-3 0.17000
* 5-7 0.28000
* 4-5 0.35000
* 6-2 0.40000
* 1.81000
*
* % java LazyPrimMST mediumEWG.txt
* 0-225
0.02383
* 49-225 0.03314
* 44-49
0.02107
* 44-204 0.01774
* 49-97
0.03121
* 202-204 0.04207
* 176-202 0.04299
* 176-191 0.02089
* 68-176 0.04396
* 58-68
0.04795
* 10.46351
*
* % java LazyPrimMST largeEWG.txt
* ...
* 647.66307

*
***********************************************************
**************/
/**
* The <tt>LazyPrimMST</tt> class represents a data type
for computing a
* <em>minimum spanning tree</em> 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 <em>minimum
* spanning forest</em>, which is the union of minimum
spanning trees
* in each connected component. The <tt>weight()</tt>
method returns the
* weight of a minimum spanning tree and the
<tt>edges()</tt> method
* returns its edges.
* <p>
* This implementation uses a lazy version of <em>Prim's
algorithm</em>
* with a binary heap of edges.
* The constructor takes time proportional to <em>E</em>
log <em>E</em>
* and extra space (not including the graph) proportional
to <em>E</em>,
* where <em>V</em> is the number of vertices and
<em>E</em> is the number of edges.
* Afterwards, the <tt>weight()</tt> method takes constant
time
* and the <tt>edges()</tt> method takes time proportional
to <em>V</em>.
* <p>
* For additional documentation, see <a
href="/algs4/44sp">Section 4.4</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
* For alternate implementations, see {@link PrimMST},
{@link KruskalMST},
* and {@link BoruvkaMST}.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/

public class LazyPrimMST {


private static final double FLOATING_POINT_EPSILON = 1E12;
private
private
private
on tree
private
in tree

double weight;
Queue<Edge> mst;
boolean[] marked;

// total weight of MST


// edges in the MST
// marked[v] = true if v

MinPQ<Edge> pq;

// edges with one endpoint

/**
* Compute a minimum spanning tree (or forest) of an
edge-weighted graph.
* @param G the edge-weighted graph
*/
public LazyPrimMST(EdgeWeightedGraph G) {
mst = new Queue<Edge>();
pq = new MinPQ<Edge>();
marked = new boolean[G.V()];
for (int v = 0; v < G.V(); v++)
// run Prim
from all vertices to
if (!marked[v]) prim(G, v);
// get a
minimum spanning forest
// check optimality conditions
assert check(G);
}
// run Prim's algorithm
private void prim(EdgeWeightedGraph G, int s) {
scan(G, s);
while (!pq.isEmpty()) {
better to stop when mst has V-1 edges
Edge e = pq.delMin();
smallest edge on pq
int v = e.either(), w = e.other(v);
two endpoints
assert marked[v] || marked[w];
if (marked[v] && marked[w]) continue;
lazy, both v and w already scanned
mst.enqueue(e);
add e to MST
weight += e.weight();
if (!marked[v]) scan(G, v);
becomes part of tree

//
//
//
//
//
// v

if (!marked[w]) scan(G, w);


becomes part of tree
}
}

// w

// add all edges e incident to v onto pq if the other


endpoint has not yet been scanned
private void scan(EdgeWeightedGraph G, int v) {
assert !marked[v];
marked[v] = true;
for (Edge e : G.adj(v))
if (!marked[e.other(v)]) pq.insert(e);
}
/**
* Returns the edges in a minimum spanning tree (or
forest).
* @return the edges in a minimum spanning tree (or
forest) as
*
an iterable of edges
*/
public Iterable<Edge> edges() {
return mst;
}
/**
* Returns the sum of the edge weights in a minimum
spanning tree (or forest).
* @return the sum of the edge weights in a minimum
spanning tree (or forest)
*/
public double weight() {
return weight;
}
// check optimality conditions (takes time proportional
to E V lg* V)
private boolean check(EdgeWeightedGraph G) {
// check weight
double totalWeight = 0.0;
for (Edge e : edges()) {
totalWeight += e.weight();
}
if (Math.abs(totalWeight - weight()) >
FLOATING_POINT_EPSILON) {

System.err.printf("Weight of edges does not


equal weight(): %f vs. %f\n", totalWeight, weight());
return false;
}
// check that it is acyclic
UF uf = new UF(G.V());
for (Edge e : edges()) {
int v = e.either(), w = e.other(v);
if (uf.connected(v, w)) {
System.err.println("Not a forest");
return false;
}
uf.union(v, w);
}
// 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)) {
System.err.println("Not a spanning forest");
return false;
}
}
// check that it is a minimal spanning forest (cut
optimality conditions)
for (Edge e : edges()) {
// all edges in MST except e
uf = new UF(G.V());
for (Edge f : mst) {
int x = f.either(), y = f.other(x);
if (f != e) uf.union(x, y);
}
// 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 (f.weight() < e.weight()) {
System.err.println("Edge " + f + "
violates cut optimality conditions");
return false;
}
}

}
}
return true;
}
/**
* Unit tests the <tt>LazyPrimMST</tt> data type.
*/
public static void main(String[] args) {
In in = new In(args[0]);
EdgeWeightedGraph G = new EdgeWeightedGraph(in);
LazyPrimMST mst = new LazyPrimMST(G);
for (Edge e : mst.edges()) {
StdOut.println(e);
}
StdOut.printf("%.5f\n", mst.weight());
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Sun Jul 26 11:14:34 EDT 2015.
PrimMST.java
Below is the syntax highlighted version
of PrimMST.java from 4.3 Minimum Spanning Trees.
the Javadoc.

Here is

/
***********************************************************
*******************
* Compilation: javac PrimMST.java
* Execution:
java PrimMST filename.txt
* Dependencies: EdgeWeightedGraph.java Edge.java
Queue.java
*
IndexMinPQ.java UF.java In.java
StdOut.java
* Data files:
http://algs4.cs.princeton.edu/43mst/tinyEWG.txt

*
http://algs4.cs.princeton.edu/43mst/mediumEWG.txt
*
http://algs4.cs.princeton.edu/43mst/largeEWG.txt
*
* Compute a minimum spanning forest using Prim's
algorithm.
*
* % java PrimMST tinyEWG.txt
* 1-7 0.19000
* 0-2 0.26000
* 2-3 0.17000
* 4-5 0.35000
* 5-7 0.28000
* 6-2 0.40000
* 0-7 0.16000
* 1.81000
*
* % java PrimMST mediumEWG.txt
* 1-72
0.06506
* 2-86
0.05980
* 3-67
0.09725
* 4-55
0.06425
* 5-102 0.03834
* 6-129 0.05363
* 7-157 0.00516
* ...
* 10.46351
*
* % java PrimMST largeEWG.txt
* ...
* 647.66307
*
***********************************************************
*******************/
/**
* The <tt>PrimMST</tt> class represents a data type for
computing a
* <em>minimum spanning tree</em> 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 <em>minimum

* spanning forest</em>, which is the union of minimum


spanning trees
* in each connected component. The <tt>weight()</tt>
method returns the
* weight of a minimum spanning tree and the
<tt>edges()</tt> method
* returns its edges.
* <p>
* This implementation uses <em>Prim's algorithm</em> with
an indexed
* binary heap.
* The constructor takes time proportional to <em>E</em>
log <em>V</em>
* and extra space (not including the graph) proportional
to <em>V</em>,
* where <em>V</em> is the number of vertices and
<em>E</em> is the number of edges.
* Afterwards, the <tt>weight()</tt> method takes constant
time
* and the <tt>edges()</tt> method takes time proportional
to <em>V</em>.
* <p>
* For additional documentation, see <a
href="/algs4/44sp">Section 4.4</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
* For alternate implementations, see {@link LazyPrimMST},
{@link KruskalMST},
* and {@link BoruvkaMST}.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class PrimMST {
private static final double FLOATING_POINT_EPSILON = 1E12;
private Edge[] edgeTo;
// edgeTo[v] = shortest
edge from tree vertex to non-tree vertex
private double[] distTo;
// distTo[v] = weight of
shortest such edge
private boolean[] marked;
// marked[v] = true if v
on tree, false otherwise
private IndexMinPQ<Double> pq;
/**

* Compute a minimum spanning tree (or forest) of an


edge-weighted graph.
* @param G the edge-weighted graph
*/
public PrimMST(EdgeWeightedGraph G) {
edgeTo = new Edge[G.V()];
distTo = new double[G.V()];
marked = new boolean[G.V()];
pq = new IndexMinPQ<Double>(G.V());
for (int v = 0; v < G.V(); v++)
distTo[v] = Double.POSITIVE_INFINITY;
for (int v = 0; v < G.V(); v++)
each vertex to find
if (!marked[v]) prim(G, v);
spanning forest

// run from
// minimum

// check optimality conditions


assert check(G);
}
// run Prim's algorithm in graph G, starting from
vertex s
private void prim(EdgeWeightedGraph G, int s) {
distTo[s] = 0.0;
pq.insert(s, distTo[s]);
while (!pq.isEmpty()) {
int v = pq.delMin();
scan(G, v);
}
}
// scan vertex v
private void scan(EdgeWeightedGraph G, int v) {
marked[v] = true;
for (Edge e : G.adj(v)) {
int w = e.other(v);
if (marked[w]) continue;
// v-w is
obsolete edge
if (e.weight() < distTo[w]) {
distTo[w] = e.weight();
edgeTo[w] = e;
if (pq.contains(w)) pq.decreaseKey(w,
distTo[w]);
else
pq.insert(w, distTo[w]);
}
}

}
/**
* Returns the edges in a minimum spanning tree (or
forest).
* @return the edges in a minimum spanning tree (or
forest) as
*
an iterable of edges
*/
public Iterable<Edge> edges() {
Queue<Edge> mst = new Queue<Edge>();
for (int v = 0; v < edgeTo.length; v++) {
Edge e = edgeTo[v];
if (e != null) {
mst.enqueue(e);
}
}
return mst;
}
/**
* Returns the sum of the edge weights in a minimum
spanning tree (or forest).
* @return the sum of the edge weights in a minimum
spanning tree (or forest)
*/
public double weight() {
double weight = 0.0;
for (Edge e : edges())
weight += e.weight();
return weight;
}
// check optimality conditions (takes time proportional
to E V lg* V)
private boolean check(EdgeWeightedGraph G) {
// check weight
double totalWeight = 0.0;
for (Edge e : edges()) {
totalWeight += e.weight();
}
if (Math.abs(totalWeight - weight()) >
FLOATING_POINT_EPSILON) {
System.err.printf("Weight of edges does not
equal weight(): %f vs. %f\n", totalWeight, weight());

return false;
}
// check that it is acyclic
UF uf = new UF(G.V());
for (Edge e : edges()) {
int v = e.either(), w = e.other(v);
if (uf.connected(v, w)) {
System.err.println("Not a forest");
return false;
}
uf.union(v, w);
}
// 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)) {
System.err.println("Not a spanning forest");
return false;
}
}
// check that it is a minimal spanning forest (cut
optimality conditions)
for (Edge e : edges()) {
// all edges in MST except e
uf = new UF(G.V());
for (Edge f : edges()) {
int x = f.either(), y = f.other(x);
if (f != e) uf.union(x, y);
}
// 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 (f.weight() < e.weight()) {
System.err.println("Edge " + f + "
violates cut optimality conditions");
return false;
}
}
}

}
return true;
}
/**
* Unit tests the <tt>PrimMST</tt> data type.
*/
public static void main(String[] args) {
In in = new In(args[0]);
EdgeWeightedGraph G = new EdgeWeightedGraph(in);
PrimMST mst = new PrimMST(G);
for (Edge e : mst.edges()) {
StdOut.println(e);
}
StdOut.printf("%.5f\n", mst.weight());
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Sun Jul 26 11:14:34 EDT 2015.
KruskalMST.java
Below is the syntax highlighted version
of KruskalMST.java from 4.3 Minimum Spanning Trees.
is the Javadoc.

Here

/
***********************************************************
**************
* Compilation:
javac KruskalMST.java
* Execution:
java KruskalMST filename.txt
* Dependencies: EdgeWeightedGraph.java Edge.java
Queue.java
*
UF.java In.java StdOut.java
* Data files:
http://algs4.cs.princeton.edu/43mst/tinyEWG.txt
*
http://algs4.cs.princeton.edu/43mst/mediumEWG.txt
*
http://algs4.cs.princeton.edu/43mst/largeEWG.txt

*
* Compute a minimum spanning forest using Kruskal's
algorithm.
*
* % java KruskalMST tinyEWG.txt
* 0-7 0.16000
* 2-3 0.17000
* 1-7 0.19000
* 0-2 0.26000
* 5-7 0.28000
* 4-5 0.35000
* 6-2 0.40000
* 1.81000
*
* % java KruskalMST mediumEWG.txt
* 168-231 0.00268
* 151-208 0.00391
* 7-157
0.00516
* 122-205 0.00647
* 8-152
0.00702
* 156-219 0.00745
* 28-198 0.00775
* 38-126 0.00845
* 10-123 0.00886
* ...
* 10.46351
*
***********************************************************
**************/
/**
* The <tt>KruskalMST</tt> class represents a data type
for computing a
* <em>minimum spanning tree</em> 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 <em>minimum
* spanning forest</em>, which is the union of minimum
spanning trees
* in each connected component. The <tt>weight()</tt>
method returns the
* weight of a minimum spanning tree and the
<tt>edges()</tt> method
* returns its edges.

* <p>
* This implementation uses <em>Krusal's algorithm</em>
and the
* union-find data type.
* The constructor takes time proportional to <em>E</em>
log <em>V</em>
* and extra space (not including the graph) proportional
to <em>V</em>,
* where <em>V</em> is the number of vertices and
<em>E</em> is the number of edges.
* Afterwards, the <tt>weight()</tt> method takes constant
time
* and the <tt>edges()</tt> method takes time proportional
to <em>V</em>.
* <p>
* For additional documentation, see <a
href="/algs4/44sp">Section 4.4</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
* For alternate implementations, see {@link LazyPrimMST},
{@link PrimMST},
* and {@link BoruvkaMST}.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class KruskalMST {
private static final double FLOATING_POINT_EPSILON = 1E12;
private double weight;
of MST
private Queue<Edge> mst = new Queue<Edge>();
in MST

// weight
// edges

/**
* Compute a minimum spanning tree (or forest) of an
edge-weighted graph.
* @param G the edge-weighted graph
*/
public KruskalMST(EdgeWeightedGraph G) {
// more efficient to build heap by passing array of
edges
MinPQ<Edge> pq = new MinPQ<Edge>();
for (Edge e : G.edges()) {
pq.insert(e);
}

// run greedy algorithm


UF uf = new UF(G.V());
while (!pq.isEmpty() && mst.size() < G.V() - 1) {
Edge e = pq.delMin();
int v = e.either();
int w = e.other(v);
if (!uf.connected(v, w)) { // v-w does not
create a cycle
uf.union(v, w); // merge v and w
components
mst.enqueue(e); // add edge e to mst
weight += e.weight();
}
}
// check optimality conditions
assert check(G);
}
/**
* Returns the edges in a minimum spanning tree (or
forest).
* @return the edges in a minimum spanning tree (or
forest) as
*
an iterable of edges
*/
public Iterable<Edge> edges() {
return mst;
}
/**
* Returns the sum of the edge weights in a minimum
spanning tree (or forest).
* @return the sum of the edge weights in a minimum
spanning tree (or forest)
*/
public double weight() {
return weight;
}
// check optimality conditions (takes time proportional
to E V lg* V)
private boolean check(EdgeWeightedGraph G) {
// check total weight
double total = 0.0;

for (Edge e : edges()) {


total += e.weight();
}
if (Math.abs(total - weight()) >
FLOATING_POINT_EPSILON) {
System.err.printf("Weight of edges does not
equal weight(): %f vs. %f\n", total, weight());
return false;
}
// check that it is acyclic
UF uf = new UF(G.V());
for (Edge e : edges()) {
int v = e.either(), w = e.other(v);
if (uf.connected(v, w)) {
System.err.println("Not a forest");
return false;
}
uf.union(v, w);
}
// 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)) {
System.err.println("Not a spanning forest");
return false;
}
}
// check that it is a minimal spanning forest (cut
optimality conditions)
for (Edge e : edges()) {
// all edges in MST except e
uf = new UF(G.V());
for (Edge f : mst) {
int x = f.either(), y = f.other(x);
if (f != e) uf.union(x, y);
}
// 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 (f.weight() < e.weight()) {

System.err.println("Edge " + f + "


violates cut optimality conditions");
return false;
}
}
}
}
return true;
}
/**
* Unit tests the <tt>KruskalMST</tt> data type.
*/
public static void main(String[] args) {
In in = new In(args[0]);
EdgeWeightedGraph G = new EdgeWeightedGraph(in);
KruskalMST mst = new KruskalMST(G);
for (Edge e : mst.edges()) {
StdOut.println(e);
}
StdOut.printf("%.5f\n", mst.weight());
}
}

Copyright 20022010, Robert Sedgewick and Kevin Wayne.


Last updated: Sun Jul 26 11:14:34 EDT 2015.
BoruvkaMST.java
Below is the syntax highlighted version
of BoruvkaMST.java from 4.3 Minimum Spanning Trees.
is the Javadoc.

Here

/
***********************************************************
**************
* Compilation: javac BoruvkaMST.java
* Execution:
java BoruvkaMST filename.txt
* Dependencies: EdgeWeightedGraph.java Edge.java Bag.java

*
UF.java In.java StdOut.java
* Data files:
http://algs4.cs.princeton.edu/43mst/tinyEWG.txt
*
http://algs4.cs.princeton.edu/43mst/mediumEWG.txt
*
http://algs4.cs.princeton.edu/43mst/largeEWG.txt
*
* Compute a minimum spanning forest using Boruvka's
algorithm.
*
* % java BoruvkaMST tinyEWG.txt
* 0-2 0.26000
* 6-2 0.40000
* 5-7 0.28000
* 4-5 0.35000
* 2-3 0.17000
* 1-7 0.19000
* 0-7 0.16000
* 1.81000
*
***********************************************************
**************/
/**
* The <tt>BoruvkaMST</tt> class represents a data type
for computing a
* <em>minimum spanning tree</em> 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 <em>minimum
* spanning forest</em>, which is the union of minimum
spanning trees
* in each connected component. The <tt>weight()</tt>
method returns the
* weight of a minimum spanning tree and the
<tt>edges()</tt> method
* returns its edges.
* <p>
* This implementation uses <em>Boruvka's algorithm</em>
and the union-find
* data type.
* The constructor takes time proportional to <em>E</em>
log <em>V</em>

* and extra space (not including the graph) proportional


to <em>V</em>,
* where <em>V</em> is the number of vertices and
<em>E</em> is the number of edges.
* Afterwards, the <tt>weight()</tt> method takes constant
time
* and the <tt>edges()</tt> method takes time proportional
to <em>V</em>.
* <p>
* For additional documentation, see <a
href="/algs4/44sp">Section 4.4</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
* For alternate implementations, see {@link LazyPrimMST},
{@link PrimMST},
* and {@link KruskalMST}.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class BoruvkaMST {
private static final double FLOATING_POINT_EPSILON = 1E12;
private Bag<Edge> mst = new Bag<Edge>();

// edges in

MST
private double weight;
of MST

// weight

/**
* Compute a minimum spanning tree (or forest) of an
edge-weighted graph.
* @param G the edge-weighted graph
*/
public BoruvkaMST(EdgeWeightedGraph G) {
UF uf = new UF(G.V());
// repeat at most log V times or until we have V-1
edges
for (int t = 1; t < G.V() && mst.size() < G.V() - 1;
t = t + t) {
// foreach tree in forest, find closest edge
// if edge weights are equal, ties are broken
in favor of first edge in G.edges()
Edge[] closest = new Edge[G.V()];
for (Edge e : G.edges()) {

int v = e.either(), w = e.other(v);


int i = uf.find(v), j = uf.find(w);
if (i == j) continue;
// same tree
if (closest[i] == null || less(e,
closest[i])) closest[i] = e;
if (closest[j] == null || less(e,
closest[j])) closest[j] = e;
}
// add newly discovered edges to MST
for (int i = 0; i < G.V(); i++) {
Edge e = closest[i];
if (e != null) {
int v = e.either(), w = e.other(v);
// don't add the same edge twice
if (!uf.connected(v, w)) {
mst.add(e);
weight += e.weight();
uf.union(v, w);
}
}
}
}
// check optimality conditions
assert check(G);
}
/**
* Returns the edges in a minimum spanning tree (or
forest).
* @return the edges in a minimum spanning tree (or
forest) as
*
an iterable of edges
*/
public Iterable<Edge> edges() {
return mst;
}
/**
* Returns the sum of the edge weights in a minimum
spanning tree (or forest).
* @return the sum of the edge weights in a minimum
spanning tree (or forest)
*/
public double weight() {

return weight;
}
// is the weight of edge e strictly less than that of
edge f?
private static boolean less(Edge e, Edge f) {
return e.weight() < f.weight();
}
// check optimality conditions (takes time proportional
to E V lg* V)
private boolean check(EdgeWeightedGraph G) {
// check weight
double totalWeight = 0.0;
for (Edge e : edges()) {
totalWeight += e.weight();
}
if (Math.abs(totalWeight - weight()) >
FLOATING_POINT_EPSILON) {
System.err.printf("Weight of edges does not
equal weight(): %f vs. %f\n", totalWeight, weight());
return false;
}
// check that it is acyclic
UF uf = new UF(G.V());
for (Edge e : edges()) {
int v = e.either(), w = e.other(v);
if (uf.connected(v, w)) {
System.err.println("Not a forest");
return false;
}
uf.union(v, w);
}
// 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)) {
System.err.println("Not a spanning forest");
return false;
}
}
// check that it is a minimal spanning forest (cut
optimality conditions)

for (Edge e : edges()) {


// all edges in MST except e
uf = new UF(G.V());
for (Edge f : mst) {
int x = f.either(), y = f.other(x);
if (f != e) uf.union(x, y);
}
// 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 (f.weight() < e.weight()) {
System.err.println("Edge " + f + "
violates cut optimality conditions");
return false;
}
}
}
}
return true;
}
/**
* Unit tests the <tt>BoruvkaMST</tt> data type.
*/
public static void main(String[] args) {
In in = new In(args[0]);
EdgeWeightedGraph G = new EdgeWeightedGraph(in);
BoruvkaMST mst = new BoruvkaMST(G);
for (Edge e : mst.edges()) {
StdOut.println(e);
}
StdOut.printf("%.5f\n", mst.weight());
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Sun Jul 26 11:14:34 EDT 2015.
EdgeWeightedDigraph.java

Below is the syntax highlighted version


of EdgeWeightedDigraph.java from Algorithms.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac EdgeWeightedDigraph.java
* Execution:
java EdgeWeightedDigraph V E
* Dependencies: Bag.java DirectedEdge.java
*
* An edge-weighted digraph, implemented using adjacency
lists.
*
***********************************************************
**************/
/**
* The <tt>EdgeWeightedDigraph</tt> class represents a
edge-weighted
* digraph of vertices named 0 through <em>V</em> - 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
* to the digraph and iterate over all of edges incident
from a given vertex.
* It also provides
* methods for returning the number of vertices <em>V</em>
and the number
* of edges <em>E</em>. Parallel edges and self-loops are
permitted.
* <p>
* 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.
* <p>

* For additional documentation,


* see <a
href="http://algs4.cs.princeton.edu/44sp">Section 4.4</a>
of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class EdgeWeightedDigraph {
private static final String NEWLINE =
System.getProperty("line.separator");
private final int V;
private int E;
private Bag<DirectedEdge>[] adj;
/**
* Initializes an empty edge-weighted digraph with
<tt>V</tt> vertices and 0 edges.
* param V the number of vertices
* @throws java.lang.IllegalArgumentException if
<tt>V</tt> < 0
*/
public EdgeWeightedDigraph(int V) {
if (V < 0) throw new
IllegalArgumentException("Number of vertices in a Digraph
must be nonnegative");
this.V = V;
this.E = 0;
adj = (Bag<DirectedEdge>[]) new Bag[V];
for (int v = 0; v < V; v++)
adj[v] = new Bag<DirectedEdge>();
}
/**
* Initializes a random edge-weighted digraph with
<tt>V</tt> vertices and <em>E</em> edges.
* param V the number of vertices
* param E the number of edges
* @throws java.lang.IllegalArgumentException if
<tt>V</tt> < 0
* @throws java.lang.IllegalArgumentException if
<tt>E</tt> < 0
*/
public EdgeWeightedDigraph(int V, int E) {

this(V);
if (E < 0) throw new
IllegalArgumentException("Number of edges in a Digraph must
be nonnegative");
for (int i = 0; i < E; i++) {
int v = StdRandom.uniform(V);
int w = StdRandom.uniform(V);
double weight = .01 * StdRandom.uniform(100);
DirectedEdge e = new DirectedEdge(v, w, weight);
addEdge(e);
}
}
/**
* Initializes an edge-weighted digraph from an input
stream.
* The format is the number of vertices <em>V</em>,
* followed by the number of edges <em>E</em>,
* followed by <em>E</em> pairs of vertices and edge
weights,
* with each entry separated by whitespace.
* @param in the input stream
* @throws java.lang.IndexOutOfBoundsException if the
endpoints of any edge are not in prescribed range
* @throws java.lang.IllegalArgumentException if the
number of vertices or edges is negative
*/
public EdgeWeightedDigraph(In in) {
this(in.readInt());
int E = in.readInt();
if (E < 0) throw new
IllegalArgumentException("Number of edges must be
nonnegative");
for (int i = 0; i < E; i++) {
int v = in.readInt();
int w = in.readInt();
if (v < 0 || v >= V) throw new
IndexOutOfBoundsException("vertex " + v + " is not between 0
and " + (V-1));
if (w < 0 || w >= V) throw new
IndexOutOfBoundsException("vertex " + w + " is not between 0
and " + (V-1));
double weight = in.readDouble();
addEdge(new DirectedEdge(v, w, weight));
}
}

/**
* Initializes a new edge-weighted digraph that is a
deep copy of <tt>G</tt>.
* @param G the edge-weighted graph to copy
*/
public EdgeWeightedDigraph(EdgeWeightedDigraph G) {
this(G.V());
this.E = G.E();
for (int v = 0; v < G.V(); v++) {
// reverse so that adjacency list is in same
order as original
Stack<DirectedEdge> reverse = new
Stack<DirectedEdge>();
for (DirectedEdge e : G.adj[v]) {
reverse.push(e);
}
for (DirectedEdge e : reverse) {
adj[v].add(e);
}
}
}
/**
* Returns
digraph.
* @return
digraph
*/
public int
return
}
/**
* Returns
digraph.
* @return
digraph
*/
public int
return
}

the number of vertices in the edge-weighted


the number of vertices in the edge-weighted
V() {
V;

the number of edges in the edge-weighted


the number of edges in the edge-weighted
E() {
E;

// throw an IndexOutOfBoundsException unless 0 <= v < V


private void validateVertex(int v) {
if (v < 0 || v >= V)
throw new IndexOutOfBoundsException("vertex " +
v + " is not between 0 and " + (V-1));

}
/**
* Adds the directed edge <tt>e</tt> to the edgeweighted digraph.
* @param e the edge
* @throws java.lang.IndexOutOfBoundsException unless
endpoints of edge are between 0 and V-1
*/
public void addEdge(DirectedEdge e) {
int v = e.from();
int w = e.to();
validateVertex(v);
validateVertex(w);
adj[v].add(e);
E++;
}
/**
* Returns the directed edges incident from vertex
<tt>v</tt>.
* @param v the vertex
* @return the directed edges incident from vertex
<tt>v</tt> as an Iterable
* @throws java.lang.IndexOutOfBoundsException unless 0
<= v < V
*/
public Iterable<DirectedEdge> adj(int v) {
validateVertex(v);
return adj[v];
}
/**
* Returns the number of directed edges incident from
vertex <tt>v</tt>.
* This is known as the <em>outdegree</em> of vertex
<tt>v</tt>.
* @param v the vertex
* @return the outdegree of vertex <tt>v</tt>
* @throws java.lang.IndexOutOfBoundsException unless 0
<= v < V
*/
public int outdegree(int v) {
validateVertex(v);
return adj[v].size();
}

/**
* Returns all directed edges in the edge-weighted
digraph.
* To iterate over the edges in the edge-weighted
graph, use foreach notation:
* <tt>for (DirectedEdge e : G.edges())</tt>.
* @return all edges in the edge-weighted graph as an
Iterable.
*/
public Iterable<DirectedEdge> edges() {
Bag<DirectedEdge> list = new Bag<DirectedEdge>();
for (int v = 0; v < V; v++) {
for (DirectedEdge e : adj(v)) {
list.add(e);
}
}
return list;
}
/**
* Returns a string representation of the edge-weighted
digraph.
* This method takes time proportional to <em>E</em> +
<em>V</em>.
* @return the number of vertices <em>V</em>, followed
by the number of edges <em>E</em>,
*
followed by the <em>V</em> adjacency lists of
edges
*/
public String toString() {
StringBuilder s = new StringBuilder();
s.append(V + " " + E + NEWLINE);
for (int v = 0; v < V; v++) {
s.append(v + ": ");
for (DirectedEdge e : adj[v]) {
s.append(e + " ");
}
s.append(NEWLINE);
}
return s.toString();
}
/**
* Unit tests the <tt>EdgeWeightedDigraph</tt> data
type.
*/

public static void main(String[] args) {


In in = new In(args[0]);
EdgeWeightedDigraph G = new EdgeWeightedDigraph(in);
StdOut.println(G);
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Sun Jul 26 11:21:27 EDT 2015.
DirectedEdge.java
Below is the syntax highlighted version
of DirectedEdge.java from Algorithms.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac DirectedEdge.java
* Execution:
java DirectedEdge
* Dependencies: StdOut.java
*
* Immutable weighted directed edge.
*
***********************************************************
**************/
/**
* The <tt>DirectedEdge</tt> class represents a weighted
edge in an
* {@link EdgeWeightedDigraph}. 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
directed edge and
* the weight.
* <p>
* For additional documentation, see <a
href="http://algs4.cs.princeton.edu/44sp">Section 4.4</a>
of

* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and


Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class DirectedEdge {
private final int v;
private final int w;
private final double weight;
/**
* Initializes a directed edge from vertex <tt>v</tt>
to vertex <tt>w</tt> with
* the given <tt>weight</tt>.
* @param v the tail vertex
* @param w the head vertex
* @param weight the weight of the directed edge
* @throws java.lang.IndexOutOfBoundsException if
either <tt>v</tt> or <tt>w</tt>
*
is a negative integer
* @throws IllegalArgumentException if <tt>weight</tt>
is <tt>NaN</tt>
*/
public DirectedEdge(int v, int w, double weight) {
if (v < 0) throw new
IndexOutOfBoundsException("Vertex names must be nonnegative
integers");
if (w < 0) throw new
IndexOutOfBoundsException("Vertex names must be nonnegative
integers");
if (Double.isNaN(weight)) throw new
IllegalArgumentException("Weight is NaN");
this.v = v;
this.w = w;
this.weight = weight;
}
/**
* Returns
* @return
*/
public int
return
}

the tail vertex of the directed edge.


the tail vertex of the directed edge
from() {
v;

/**
* Returns
* @return
*/
public int
return
}

the head vertex of the directed edge.


the head vertex of the directed edge
to() {
w;

/**
* Returns the weight of the directed edge.
* @return the weight of the directed edge
*/
public double weight() {
return weight;
}
/**
* Returns a string representation of the directed
edge.
* @return a string representation of the directed edge
*/
public String toString() {
return v + "->" + w + " " + String.format("%5.2f",
weight);
}
/**
* Unit tests the <tt>DirectedEdge</tt> data type.
*/
public static void main(String[] args) {
DirectedEdge e = new DirectedEdge(12, 34, 5.67);
StdOut.println(e);
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Thu Jul 23 17:05:46 EDT 2015.
DijkstraSP.java
Below is the syntax highlighted version
of DijkstraSP.java from 4.4 Shortest Paths.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac DijkstraSP.java
* Execution:
java DijkstraSP input.txt s
* Dependencies: EdgeWeightedDigraph.java IndexMinPQ.java
Stack.java DirectedEdge.java
* Data files:
http://algs4.cs.princeton.edu/44sp/tinyEWD.txt
*
http://algs4.cs.princeton.edu/44sp/mediumEWD.txt
*
http://algs4.cs.princeton.edu/44sp/largeEWD.txt
*
* Dijkstra's algorithm. Computes the shortest path tree.
* Assumes all weights are nonnegative.
*
* % java DijkstraSP tinyEWD.txt 0
* 0 to 0 (0.00)
* 0 to 1 (1.05) 0->4 0.38
4->5 0.35
5->1 0.32
* 0 to 2 (0.26) 0->2 0.26
* 0 to 3 (0.99) 0->2 0.26
2->7 0.34
7->3 0.39
* 0 to 4 (0.38) 0->4 0.38
* 0 to 5 (0.73) 0->4 0.38
4->5 0.35
* 0 to 6 (1.51) 0->2 0.26
2->7 0.34
7->3 0.39
3->6 0.52
* 0 to 7 (0.60) 0->2 0.26
2->7 0.34
*
* % java DijkstraSP mediumEWD.txt 0
* 0 to 0 (0.00)
* 0 to 1 (0.71) 0->44 0.06
44->93 0.07
... 107->1
0.07
* 0 to 2 (0.65) 0->44 0.06
44->231 0.10 ... 42->2
0.11
* 0 to 3 (0.46) 0->97 0.08
97->248 0.09 ... 45->3
0.12
* 0 to 4 (0.42) 0->44 0.06
44->93 0.07
... 77->4
0.11
* ...
*
***********************************************************
**************/
/**

* The <tt>DijkstraSP</tt> class represents a data type


for solving the
* single-source shortest paths problem in edge-weighted
digraphs
* where the edge weights are nonnegative.
* <p>
* This implementation uses Dijkstra's algorithm with a
binary heap.
* The constructor takes time proportional to <em>E</em>
log <em>V</em>,
* where <em>V</em> is the number of vertices and
<em>E</em> is the number of edges.
* Afterwards, the <tt>distTo()</tt> and
<tt>hasPathTo()</tt> methods take
* constant time and the <tt>pathTo()</tt> method takes
time proportional to the
* number of edges in the shortest path returned.
* <p>
* For additional documentation, see <a
href="/algs4/44sp">Section 4.4</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class DijkstraSP {
private double[] distTo;
// distTo[v] =
distance of shortest s->v path
private DirectedEdge[] edgeTo;
// edgeTo[v] = last
edge on shortest s->v path
private IndexMinPQ<Double> pq;
// priority queue of
vertices
/**
* Computes a shortest paths tree from <tt>s</tt> to
every other vertex in
* the edge-weighted digraph <tt>G</tt>.
* @param G the edge-weighted digraph
* @param s the source vertex
* @throws IllegalArgumentException if an edge weight
is negative
* @throws IllegalArgumentException unless 0 &le;
<tt>s</tt> &le; <tt>V</tt> - 1
*/
public DijkstraSP(EdgeWeightedDigraph G, int s) {
for (DirectedEdge e : G.edges()) {

if (e.weight() < 0)
throw new IllegalArgumentException("edge " +
e + " has negative weight");
}
distTo = new double[G.V()];
edgeTo = new DirectedEdge[G.V()];
for (int v = 0; v < G.V(); v++)
distTo[v] = Double.POSITIVE_INFINITY;
distTo[s] = 0.0;
// relax vertices in order of distance from s
pq = new IndexMinPQ<Double>(G.V());
pq.insert(s, distTo[s]);
while (!pq.isEmpty()) {
int v = pq.delMin();
for (DirectedEdge e : G.adj(v))
relax(e);
}
// check optimality conditions
assert check(G, s);
}
// relax edge e and update pq if changed
private void relax(DirectedEdge e) {
int v = e.from(), w = e.to();
if (distTo[w] > distTo[v] + e.weight()) {
distTo[w] = distTo[v] + e.weight();
edgeTo[w] = e;
if (pq.contains(w)) pq.decreaseKey(w,
distTo[w]);
else
pq.insert(w, distTo[w]);
}
}
/**
* Returns the length of a shortest path from the
source vertex <tt>s</tt> to vertex <tt>v</tt>.
* @param v the destination vertex
* @return the length of a shortest path from the
source vertex <tt>s</tt> to vertex <tt>v</tt>;
*
<tt>Double.POSITIVE_INFINITY</tt> if no such path
*/
public double distTo(int v) {
return distTo[v];
}

/**
* Is there a path from the source vertex <tt>s</tt> to
vertex <tt>v</tt>?
* @param v the destination vertex
* @return <tt>true</tt> if there is a path from the
source vertex
*
<tt>s</tt> to vertex <tt>v</tt>, and
<tt>false</tt> otherwise
*/
public boolean hasPathTo(int v) {
return distTo[v] < Double.POSITIVE_INFINITY;
}
/**
* Returns a shortest path from the source vertex
<tt>s</tt> to vertex <tt>v</tt>.
* @param v the destination vertex
* @return a shortest path from the source vertex
<tt>s</tt> to vertex <tt>v</tt>
*
as an iterable of edges, and <tt>null</tt> if no
such path
*/
public Iterable<DirectedEdge> pathTo(int v) {
if (!hasPathTo(v)) return null;
Stack<DirectedEdge> path = new
Stack<DirectedEdge>();
for (DirectedEdge e = edgeTo[v]; e != null; e =
edgeTo[e.from()]) {
path.push(e);
}
return path;
}
// check optimality conditions:
// (i) for all edges e:
distTo[e.to()] <=
distTo[e.from()] + e.weight()
// (ii) for all edge e on the SPT: distTo[e.to()] ==
distTo[e.from()] + e.weight()
private boolean check(EdgeWeightedDigraph G, int s) {
// check that edge weights are nonnegative
for (DirectedEdge e : G.edges()) {
if (e.weight() < 0) {
System.err.println("negative edge weight
detected");

return false;
}
}
// check that distTo[v] and edgeTo[v] are
consistent
if (distTo[s] != 0.0 || edgeTo[s] != null) {
System.err.println("distTo[s] and edgeTo[s]
inconsistent");
return false;
}
for (int v = 0; v < G.V(); v++) {
if (v == s) continue;
if (edgeTo[v] == null && distTo[v] !=
Double.POSITIVE_INFINITY) {
System.err.println("distTo[] and edgeTo[]
inconsistent");
return false;
}
}
// check that all edges e = v->w satisfy distTo[w]
<= distTo[v] + e.weight()
for (int v = 0; v < G.V(); v++) {
for (DirectedEdge e : G.adj(v)) {
int w = e.to();
if (distTo[v] + e.weight() < distTo[w]) {
System.err.println("edge " + e + " not
relaxed");
return false;
}
}
}
// check that all edges e = v->w on SPT satisfy
distTo[w] == distTo[v] + e.weight()
for (int w = 0; w < G.V(); w++) {
if (edgeTo[w] == null) continue;
DirectedEdge e = edgeTo[w];
int v = e.from();
if (w != e.to()) return false;
if (distTo[v] + e.weight() != distTo[w]) {
System.err.println("edge " + e + " on
shortest path not tight");
return false;
}
}

return true;
}
/**
* Unit tests the <tt>DijkstraSP</tt> data type.
*/
public static void main(String[] args) {
In in = new In(args[0]);
EdgeWeightedDigraph G = new EdgeWeightedDigraph(in);
int s = Integer.parseInt(args[1]);
// compute shortest paths
DijkstraSP sp = new DijkstraSP(G, s);
// print shortest path
for (int t = 0; t < G.V(); t++) {
if (sp.hasPathTo(t)) {
StdOut.printf("%d to %d (%.2f) ", s, t,
sp.distTo(t));
for (DirectedEdge e : sp.pathTo(t)) {
StdOut.print(e + "
");
}
StdOut.println();
}
else {
StdOut.printf("%d to %d
no path\n",
s, t);
}
}
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Mon Jul 20 14:48:23 EDT 2015.
DijkstraAllPairsSP.java
Below is the syntax highlighted version
of DijkstraAllPairsSP.java from 4.4 Shortest Paths.
is the Javadoc.

Here

/
***********************************************************
**************
* Compilation: javac DijkstraAllPairsSP.java
* Execution:
none
* Dependencies: EdgeWeightedDigraph.java Dijkstra.java
*
* Dijkstra's algorithm run from each vertex.
* Takes time proportional to E V log V and space
proportional to EV.
*
***********************************************************
**************/
/**
* The <tt>DijkstraAllPairsSP</tt> class represents a data
type for solving the
* all-pairs shortest paths problem in edge-weighted
digraphs
* where the edge weights are nonnegative.
* <p>
* This implementation runs Dijkstra's algorithm from each
vertex.
* The constructor takes time proportional to <em>V</em>
(<em>E</em> log <em>V</em>)
* and uses space proprtional to <em>V</em><sup>2</sup>,
* where <em>V</em> is the number of vertices and
<em>E</em> is the number of edges.
* Afterwards, the <tt>dist()</tt> and <tt>hasPath()</tt>
methods take
* constant time and the <tt>path()</tt> method takes time
proportional to the
* number of edges in the shortest path returned.
* <p>
* For additional documentation, see <a
href="/algs4/44sp">Section 4.4</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class DijkstraAllPairsSP {
private DijkstraSP[] all;
/**

* Computes a shortest paths tree from each vertex to


to every other vertex in
* the edge-weighted digraph <tt>G</tt>.
* @param G the edge-weighted digraph
* @throws IllegalArgumentException if an edge weight
is negative
* @throws IllegalArgumentException unless 0 &le;
<tt>s</tt> &le; <tt>V</tt> - 1
*/
public DijkstraAllPairsSP(EdgeWeightedDigraph G) {
all = new DijkstraSP[G.V()];
for (int v = 0; v < G.V(); v++)
all[v] = new DijkstraSP(G, v);
}
/**
* Returns a shortest path from vertex <tt>s</tt> to
vertex <tt>t</tt>.
* @param s the source vertex
* @param t the destination vertex
* @return a shortest path from vertex <tt>s</tt> to
vertex <tt>t</tt>
*
as an iterable of edges, and <tt>null</tt> if no
such path
*/
public Iterable<DirectedEdge> path(int s, int t) {
return all[s].pathTo(t);
}
/**
* Is there a path from the vertex <tt>s</tt> to vertex
<tt>t</tt>?
* @param s the source vertex
* @param t the destination vertex
* @return <tt>true</tt> if there is a path from vertex
<tt>s</tt>
*
to vertex <tt>t</tt>, and <tt>false</tt>
otherwise
*/
public boolean hasPath(int s, int t) {
return dist(s, t) < Double.POSITIVE_INFINITY;
}
/**
* Returns the length of a shortest path from vertex
<tt>s</tt> to vertex <tt>t</tt>.
* @param s the source vertex

* @param t the destination vertex


* @return the length of a shortest path from vertex
<tt>s</tt> to vertex <tt>t</tt>;
*
<tt>Double.POSITIVE_INFINITY</tt> if no such path
*/
public double dist(int s, int t) {
return all[s].distTo(t);
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Thu Jul 23 17:05:46 EDT 2015.
AcyclicSP.java
Below is the syntax highlighted version
of AcyclicSP.java from 4.4 Shortest Paths.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac AcyclicSP.java
* Execution:
java AcyclicSP V E
* Dependencies: EdgeWeightedDigraph.java
DirectedEdge.java Topological.java
* Data files:
http://algs4.cs.princeton.edu/44sp/tinyEWDAG.txt
*
* 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
*
***********************************************************
**************/

/**
* The <tt>AcyclicSP</tt> class represents a data type for
solving the
* single-source shortest paths problem in edge-weighted
directed acyclic
* graphs (DAGs). The edge weights can be positive,
negative, or zero.
* <p>
* This implementation uses a topological-sort based
algorithm.
* The constructor takes time proportional to <em>V</em> +
<em>E</em>,
* where <em>V</em> is the number of vertices and
<em>E</em> is the number of edges.
* Afterwards, the <tt>distTo()</tt> and
<tt>hasPathTo()</tt> methods take
* constant time and the <tt>pathTo()</tt> method takes
time proportional to the
* number of edges in the shortest path returned.
* <p>
* For additional documentation, see <a
href="/algs4/44sp">Section 4.4</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class AcyclicSP {
private double[] distTo;
// distTo[v] =
distance of shortest s->v path
private DirectedEdge[] edgeTo;
// edgeTo[v] = last
edge on shortest s->v path
/**
* Computes a shortest paths tree from <tt>s</tt> to
every other vertex in
* the directed acyclic graph <tt>G</tt>.
* @param G the acyclic digraph
* @param s the source vertex
* @throws IllegalArgumentException if the digraph is
not acyclic
* @throws IllegalArgumentException unless 0 &le;
<tt>s</tt> &le; <tt>V</tt> - 1
*/

public AcyclicSP(EdgeWeightedDigraph G, int s) {


distTo = new double[G.V()];
edgeTo = new DirectedEdge[G.V()];
for (int v = 0; v < G.V(); v++)
distTo[v] = Double.POSITIVE_INFINITY;
distTo[s] = 0.0;
// visit vertices in toplogical order
Topological topological = new Topological(G);
if (!topological.hasOrder())
throw new IllegalArgumentException("Digraph is
not acyclic.");
for (int v : topological.order()) {
for (DirectedEdge e : G.adj(v))
relax(e);
}
}
// relax edge e
private void relax(DirectedEdge e) {
int v = e.from(), w = e.to();
if (distTo[w] > distTo[v] + e.weight()) {
distTo[w] = distTo[v] + e.weight();
edgeTo[w] = e;
}
}
/**
* Returns the length of a shortest path from the
source vertex <tt>s</tt> to vertex <tt>v</tt>.
* @param v the destination vertex
* @return the length of a shortest path from the
source vertex <tt>s</tt> to vertex <tt>v</tt>;
*
<tt>Double.POSITIVE_INFINITY</tt> if no such path
*/
public double distTo(int v) {
return distTo[v];
}
/**
* Is there a path from the source vertex <tt>s</tt> to
vertex <tt>v</tt>?
* @param v the destination vertex
* @return <tt>true</tt> if there is a path from the
source vertex
*
<tt>s</tt> to vertex <tt>v</tt>, and
<tt>false</tt> otherwise

*/
public boolean hasPathTo(int v) {
return distTo[v] < Double.POSITIVE_INFINITY;
}
/**
* Returns a shortest path from the source vertex
<tt>s</tt> to vertex <tt>v</tt>.
* @param v the destination vertex
* @return a shortest path from the source vertex
<tt>s</tt> to vertex <tt>v</tt>
*
as an iterable of edges, and <tt>null</tt> if no
such path
*/
public Iterable<DirectedEdge> pathTo(int v) {
if (!hasPathTo(v)) return null;
Stack<DirectedEdge> path = new
Stack<DirectedEdge>();
for (DirectedEdge e = edgeTo[v]; e != null; e =
edgeTo[e.from()]) {
path.push(e);
}
return path;
}
/**
* Unit tests the <tt>AcyclicSP</tt> data type.
*/
public static void main(String[] args) {
In in = new In(args[0]);
int s = Integer.parseInt(args[1]);
EdgeWeightedDigraph G = new EdgeWeightedDigraph(in);
// find shortest path from s to each other vertex
in DAG
AcyclicSP sp = new AcyclicSP(G, s);
for (int v = 0; v < G.V(); v++) {
if (sp.hasPathTo(v)) {
StdOut.printf("%d to %d (%.2f) ", s, v,
sp.distTo(v));
for (DirectedEdge e : sp.pathTo(v)) {
StdOut.print(e + "
");
}
StdOut.println();
}
else {

StdOut.printf("%d to %d

no path\n",

s, v);
}
}
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Sun Nov 10 05:53:55 EST 2013.
AcyclicLP.java
Below is the syntax highlighted version
of AcyclicLP.java from 4.4 Shortest Paths.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac AcyclicLP.java
* Execution:
java AcyclicP V E
* Dependencies: EdgeWeightedDigraph.java
DirectedEdge.java Topological.java
* Data files:
http://algs4.cs.princeton.edu/44sp/tinyEWDAG.txt
*
* Computes longeset 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)
6->4 0.93
4->7
*

5->1
0.37

0.32

1->3

0.29

3->6

0.52

***********************************************************
**************/
/**
* The <tt>AcyclicLP</tt> class represents a data type for
solving the
* single-source longest paths problem in edge-weighted
directed
* acyclic graphs (DAGs). The edge weights can be
positive, negative, or zero.
* <p>
* This implementation uses a topological-sort based
algorithm.
* The constructor takes time proportional to <em>V</em> +
<em>E</em>,
* where <em>V</em> is the number of vertices and
<em>E</em> is the number of edges.
* Afterwards, the <tt>distTo()</tt> and
<tt>hasPathTo()</tt> methods take
* constant time and the <tt>pathTo()</tt> method takes
time proportional to the
* number of edges in the longest path returned.
* <p>
* For additional documentation, see <a
href="/algs4/44sp">Section 4.4</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class AcyclicLP {
private double[] distTo;
// distTo[v] =
distance of longest s->v path
private DirectedEdge[] edgeTo;
// edgeTo[v] = last
edge on longest s->v path
/**
* Computes a longest paths tree from <tt>s</tt> to
every other vertex in
* the directed acyclic graph <tt>G</tt>.
* @param G the acyclic digraph
* @param s the source vertex

* @throws IllegalArgumentException if the digraph is


not acyclic
* @throws IllegalArgumentException unless 0 &le;
<tt>s</tt> &le; <tt>V</tt> - 1
*/
public AcyclicLP(EdgeWeightedDigraph G, int s) {
distTo = new double[G.V()];
edgeTo = new DirectedEdge[G.V()];
for (int v = 0; v < G.V(); v++)
distTo[v] = Double.NEGATIVE_INFINITY;
distTo[s] = 0.0;
// relax vertices in toplogical order
Topological topological = new Topological(G);
if (!topological.hasOrder())
throw new IllegalArgumentException("Digraph is
not acyclic.");
for (int v : topological.order()) {
for (DirectedEdge e : G.adj(v))
relax(e);
}
}
// relax edge e, but update if you find a *longer* path
private void relax(DirectedEdge e) {
int v = e.from(), w = e.to();
if (distTo[w] < distTo[v] + e.weight()) {
distTo[w] = distTo[v] + e.weight();
edgeTo[w] = e;
}
}
/**
* Returns the length of a longest path from the source
vertex <tt>s</tt> to vertex <tt>v</tt>.
* @param v the destination vertex
* @return the length of a longest path from the source
vertex <tt>s</tt> to vertex <tt>v</tt>;
*
<tt>Double.NEGATIVE_INFINITY</tt> if no such path
*/
public double distTo(int v) {
return distTo[v];
}
/**
* Is there a path from the source vertex <tt>s</tt> to
vertex <tt>v</tt>?

* @param v the destination vertex


* @return <tt>true</tt> if there is a path from the
source vertex
*
<tt>s</tt> to vertex <tt>v</tt>, and
<tt>false</tt> otherwise
*/
public boolean hasPathTo(int v) {
return distTo[v] > Double.NEGATIVE_INFINITY;
}
/**
* Returns a longest path from the source vertex
<tt>s</tt> to vertex <tt>v</tt>.
* @param v the destination vertex
* @return a longest path from the source vertex
<tt>s</tt> to vertex <tt>v</tt>
*
as an iterable of edges, and <tt>null</tt> if no
such path
*/
public Iterable<DirectedEdge> pathTo(int v) {
if (!hasPathTo(v)) return null;
Stack<DirectedEdge> path = new
Stack<DirectedEdge>();
for (DirectedEdge e = edgeTo[v]; e != null; e =
edgeTo[e.from()]) {
path.push(e);
}
return path;
}

/**
* Unit tests the <tt>AcyclicLP</tt> data type.
*/
public static void main(String[] args) {
In in = new In(args[0]);
int s = Integer.parseInt(args[1]);
EdgeWeightedDigraph G = new EdgeWeightedDigraph(in);
AcyclicLP lp = new AcyclicLP(G, s);
for (int v = 0; v < G.V(); v++) {
if (lp.hasPathTo(v)) {
StdOut.printf("%d to %d (%.2f) ", s, v,
lp.distTo(v));
for (DirectedEdge e : lp.pathTo(v)) {

StdOut.print(e + "
}
StdOut.println();
}
else {
StdOut.printf("%d to %d

");

no path\n",

s, v);
}
}
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Thu Jul 23 17:05:46 EDT 2015.
CPM.java
Below is the syntax highlighted version
of CPM.java from 4.4 Shortest Paths.
Here is the Javadoc.

/
***********************************************************
**************
* Compilation: javac CPM.java
* Execution:
java CPM < input.txt
* Dependencies: EdgeWeightedDigraph.java
AcyclicDigraphLP.java StdOut.java
* Data files:
http://algs4.cs.princeton.edu/44sp/jobsPC.txt
*
* Critical path method.
*
* % java CPM < jobsPC.txt
*
job
start finish
* -------------------*
0
0.0
41.0
*
1
41.0
92.0
*
2
123.0
173.0
*
3
91.0
127.0
*
4
70.0
108.0
*
5
0.0
45.0
*
6
70.0
91.0
*
7
41.0
73.0
*
8
91.0
123.0

*
*
*

9
41.0
Finish time:

70.0
173.0

***********************************************************
**************/
/**
* The <tt>CPM</tt> class provides a client that solves
the
* parallel precedence-constrained job scheduling problem
* via the <em>critical path method</em>. It reduces the
problem
* to the longest-paths problem in edge-weighted DAGs.
* It builds an edge-weighted digraph (which must be a
DAG)
* from the job-scheduling problem specification,
* finds the longest-paths tree, and computes the longestpaths
* lengths (which are precisely the start times for each
job).
* <p>
* This implementation uses {@link AcyclicLP} to find a
longest
* path in a DAG.
* The running time is proportional to <em>V</em> +
<em>E</em>,
* where <em>V</em> is the number of jobs and <em>E</em>
is the
* number of precedence constraints.
* <p>
* For additional documentation,
* see <a
href="http://algs4.cs.princeton.edu/44sp">Section 4.4</a>
of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class CPM {
// this class cannot be instantiated
private CPM() { }
/**

Reads the precedence constraints from standard

input
* and prints a feasible schedule to standard output.
*/
public static void main(String[] args) {
// number of jobs
int N = StdIn.readInt();
// source and sink
int source = 2*N;
int sink
= 2*N + 1;
// build network
EdgeWeightedDigraph G = new EdgeWeightedDigraph(2*N
+ 2);
for (int i = 0; i < N; i++) {
double duration = StdIn.readDouble();
G.addEdge(new DirectedEdge(source, i, 0.0));
G.addEdge(new DirectedEdge(i+N, sink, 0.0));
G.addEdge(new DirectedEdge(i, i+N,
duration));
// precedence constraints
int M = StdIn.readInt();
for (int j = 0; j < M; j++) {
int precedent = StdIn.readInt();
G.addEdge(new DirectedEdge(N+i, precedent,
0.0));
}
}
// compute longest path
AcyclicLP lp = new AcyclicLP(G, source);
// print results
StdOut.println(" job
start finish");
StdOut.println("--------------------");
for (int i = 0; i < N; i++) {
StdOut.printf("%4d %7.1f %7.1f\n", i,
lp.distTo(i), lp.distTo(i+N));
}
StdOut.printf("Finish time: %7.1f\n",
lp.distTo(sink));
}
}

Copyright 20022010, Robert Sedgewick and Kevin Wayne.


Last updated: Tue Oct 22 10:41:44 EDT 2013.
BellmanFordSP.java
Below is the syntax highlighted version
of BellmanFordSP.java from 4.4 Shortest Paths.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac BellmanFordSP.java
* Execution:
java BellmanFordSP filename.txt s
* Dependencies: EdgeWeightedDigraph.java
DirectedEdge.java Queue.java
*
EdgeWeightedDirectedCycle.java
* Data files:
http://algs4.cs.princeton.edu/44sp/tinyEWDn.txt
*
http://algs4.cs.princeton.edu/44sp/mediumEWDnc.txt
*
* Bellman-Ford shortest path algorithm. Computes the
shortest path tree in
* edge-weighted digraph G from vertex s, or finds a
negative cost cycle
* reachable from s.
*
* % java BellmanFordSP tinyEWDn.txt 0
* 0 to 0 ( 0.00)
* 0 to 1 ( 0.93) 0->2 0.26
2->7 0.34
7->3 0.39
3->6 0.52
6->4 -1.25
4->5 0.35
5->1 0.32
* 0 to 2 ( 0.26) 0->2 0.26
* 0 to 3 ( 0.99) 0->2 0.26
2->7 0.34
7->3 0.39
* 0 to 4 ( 0.26) 0->2 0.26
2->7 0.34
7->3 0.39
3->6 0.52
6->4 -1.25
* 0 to 5 ( 0.61) 0->2 0.26
2->7 0.34
7->3 0.39
3->6 0.52
6->4 -1.25
4->5 0.35
* 0 to 6 ( 1.51) 0->2 0.26
2->7 0.34
7->3 0.39
3->6 0.52
* 0 to 7 ( 0.60) 0->2 0.26
2->7 0.34
*
* % java BellmanFordSP tinyEWDnc.txt 0

*
*
*
*

4->5 0.35
5->4 -0.66

***********************************************************
**************/
/**
* The <tt>BellmanFordSP</tt> class represents a data type
for solving the
* single-source shortest paths problem in edge-weighted
digraphs with
* no negative cycles.
* The edge weights can be positive, negative, or zero.
* This class finds either a shortest path from the source
vertex <em>s</em>
* to every other vertex or a negative cycle reachable
from the source vertex.
* <p>
* This implementation uses the Bellman-Ford-Moore
algorithm.
* The constructor takes time proportional to <em>V</em>
(<em>V</em> + <em>E</em>)
* in the worst case, where <em>V</em> is the number of
vertices and <em>E</em>
* is the number of edges.
* Afterwards, the <tt>distTo()</tt>,
<tt>hasPathTo()</tt>, and <tt>hasNegativeCycle()</tt>
* methods take constant time; the <tt>pathTo()</tt> and
<tt>negativeCycle()</tt>
* method takes time proportional to the number of edges
returned.
* <p>
* For additional documentation, see <a
href="/algs4/44sp">Section 4.4</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class BellmanFordSP {
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;


is v currently on the queue?
private Queue<Integer> queue;
vertices to relax
private int cost;
calls to relax()
private Iterable<DirectedEdge> cycle;
cycle (or null if no such cycle)

// onQueue[v] =
// queue of
// number of
// negative

/**
* Computes a shortest paths tree from <tt>s</tt> to
every other vertex in
* the edge-weighted digraph <tt>G</tt>.
* @param G the acyclic digraph
* @param s the source vertex
* @throws IllegalArgumentException unless 0 &le;
<tt>s</tt> &le; <tt>V</tt> - 1
*/
public BellmanFordSP(EdgeWeightedDigraph G, int s) {
distTo = new double[G.V()];
edgeTo = new DirectedEdge[G.V()];
onQueue = new boolean[G.V()];
for (int v = 0; v < G.V(); v++)
distTo[v] = Double.POSITIVE_INFINITY;
distTo[s] = 0.0;
// Bellman-Ford algorithm
queue = new Queue<Integer>();
queue.enqueue(s);
onQueue[s] = true;
while (!queue.isEmpty() && !hasNegativeCycle()) {
int v = queue.dequeue();
onQueue[v] = false;
relax(G, v);
}
assert check(G, s);
}
// relax vertex v and put other endpoints on queue if
changed
private void relax(EdgeWeightedDigraph G, int v) {
for (DirectedEdge e : G.adj(v)) {
int w = e.to();
if (distTo[w] > distTo[v] + e.weight()) {
distTo[w] = distTo[v] + e.weight();
edgeTo[w] = e;

if (!onQueue[w]) {
queue.enqueue(w);
onQueue[w] = true;
}
}
if (cost++ % G.V() == 0) {
findNegativeCycle();
if (hasNegativeCycle()) return;
negative cycle
}
}
}

// found a

/**
* Is there a negative cycle reachable from the source
vertex <tt>s</tt>?
* @return <tt>true</tt> if there is a negative cycle
reachable from the
*
source vertex <tt>s</tt>, and <tt>false</tt>
otherwise
*/
public boolean hasNegativeCycle() {
return cycle != null;
}
/**
* Returns a negative cycle reachable from the source
vertex <tt>s</tt>, or <tt>null</tt>
* if there is no such cycle.
* @return a negative cycle reachable from the soruce
vertex <tt>s</tt>
*
as an iterable of edges, and <tt>null</tt> if
there is no such cycle
*/
public Iterable<DirectedEdge> negativeCycle() {
return cycle;
}
// by finding a cycle in predecessor graph
private void findNegativeCycle() {
int V = edgeTo.length;
EdgeWeightedDigraph spt = new
EdgeWeightedDigraph(V);
for (int v = 0; v < V; v++)
if (edgeTo[v] != null)
spt.addEdge(edgeTo[v]);

EdgeWeightedDirectedCycle finder = new


EdgeWeightedDirectedCycle(spt);
cycle = finder.cycle();
}
/**
* Returns the length of a shortest path from the
source vertex <tt>s</tt> to vertex <tt>v</tt>.
* @param v the destination vertex
* @return the length of a shortest path from the
source vertex <tt>s</tt> to vertex <tt>v</tt>;
*
<tt>Double.POSITIVE_INFINITY</tt> if no such path
* @throws UnsupportedOperationException if there is a
negative cost cycle reachable
*
from the source vertex <tt>s</tt>
*/
public double distTo(int v) {
if (hasNegativeCycle())
throw new
UnsupportedOperationException("Negative cost cycle exists");
return distTo[v];
}
/**
* Is there a path from the source <tt>s</tt> to vertex
<tt>v</tt>?
* @param v the destination vertex
* @return <tt>true</tt> if there is a path from the
source vertex
*
<tt>s</tt> to vertex <tt>v</tt>, and
<tt>false</tt> otherwise
*/
public boolean hasPathTo(int v) {
return distTo[v] < Double.POSITIVE_INFINITY;
}
/**
* Returns a shortest path from the source <tt>s</tt>
to vertex <tt>v</tt>.
* @param v the destination vertex
* @return a shortest path from the source <tt>s</tt>
to vertex <tt>v</tt>
*
as an iterable of edges, and <tt>null</tt> if no
such path
* @throws UnsupportedOperationException if there is a
negative cost cycle reachable
*
from the source vertex <tt>s</tt>

*/
public Iterable<DirectedEdge> pathTo(int v) {
if (hasNegativeCycle())
throw new
UnsupportedOperationException("Negative cost cycle exists");
if (!hasPathTo(v)) return null;
Stack<DirectedEdge> path = new
Stack<DirectedEdge>();
for (DirectedEdge e = edgeTo[v]; e != null; e =
edgeTo[e.from()]) {
path.push(e);
}
return path;
}
// check optimality conditions: either
// (i) there exists a negative cycle reacheable from s
//
or
// (ii) for all edges e = v->w:
distTo[w]
<= distTo[v] + e.weight()
// (ii') for all edges e = v->w on the SPT: distTo[w]
== distTo[v] + e.weight()
private boolean check(EdgeWeightedDigraph G, int s) {
// has a negative cycle
if (hasNegativeCycle()) {
double weight = 0.0;
for (DirectedEdge e : negativeCycle()) {
weight += e.weight();
}
if (weight >= 0.0) {
System.err.println("error: weight of
negative cycle = " + weight);
return false;
}
}
// no negative cycle reachable from source
else {
// check that distTo[v] and edgeTo[v] are
consistent
if (distTo[s] != 0.0 || edgeTo[s] != null) {
System.err.println("distanceTo[s] and
edgeTo[s] inconsistent");
return false;
}

for (int v = 0; v < G.V(); v++) {


if (v == s) continue;
if (edgeTo[v] == null && distTo[v] !=
Double.POSITIVE_INFINITY) {
System.err.println("distTo[] and
edgeTo[] inconsistent");
return false;
}
}
// check that all edges e = v->w satisfy
distTo[w] <= distTo[v] + e.weight()
for (int v = 0; v < G.V(); v++) {
for (DirectedEdge e : G.adj(v)) {
int w = e.to();
if (distTo[v] + e.weight() < distTo[w])
{
System.err.println("edge " + e + "
not relaxed");
return false;
}
}
}
// check that all edges e = v->w on SPT satisfy
distTo[w] == distTo[v] + e.weight()
for (int w = 0; w < G.V(); w++) {
if (edgeTo[w] == null) continue;
DirectedEdge e = edgeTo[w];
int v = e.from();
if (w != e.to()) return false;
if (distTo[v] + e.weight() != distTo[w]) {
System.err.println("edge " + e + " on
shortest path not tight");
return false;
}
}
}
StdOut.println("Satisfies optimality conditions");
StdOut.println();
return true;
}
/**
* Unit tests the <tt>BellmanFordSP</tt> data type.
*/

public static void main(String[] args) {


In in = new In(args[0]);
int s = Integer.parseInt(args[1]);
EdgeWeightedDigraph G = new EdgeWeightedDigraph(in);
BellmanFordSP sp = new BellmanFordSP(G, s);
// print negative cycle
if (sp.hasNegativeCycle()) {
for (DirectedEdge e : sp.negativeCycle())
StdOut.println(e);
}
// print shortest paths
else {
for (int v = 0; v < G.V(); v++) {
if (sp.hasPathTo(v)) {
StdOut.printf("%d to %d (%5.2f) ", s,
v, sp.distTo(v));
for (DirectedEdge e : sp.pathTo(v)) {
StdOut.print(e + "
");
}
StdOut.println();
}
else {
StdOut.printf("%d to %d
no
path\n", s, v);
}
}
}
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Fri May 1 10:43:06 EDT 2015.
EdgeWeightedDirectedCycle.java
Below is the syntax highlighted version
of EdgeWeightedDirectedCycle.java from 4.4 Shortest Paths.
Here is the Javadoc.

/
***********************************************************
**************
* Compilation: javac EdgeWeightedDirectedCycle.java
* Execution:
java EdgeWeightedDirectedCycle V E F
* Dependencies: EdgeWeightedDigraph.java DirectedEdge
Stack.java
*
* Finds a directed cycle in an edge-weighted digraph.
* Runs in O(E + V) time.
*
*
***********************************************************
**************/
/**
* The <tt>EdgeWeightedDirectedCycle</tt> class represents
a data type for
* determining whether an edge-weighted digraph has a
directed cycle.
* The <em>hasCycle</em> operation determines whether the
edge-weighted
* digraph has a directed cycle and, if so, the
<em>cycle</em> operation
* returns one.
* <p>
* This implementation uses depth-first search.
* The constructor takes time proportional to <em>V</em> +
<em>E</em>
* (in the worst case),
* where <em>V</em> is the number of vertices and
<em>E</em> is the number of edges.
* Afterwards, the <em>hasCycle</em> operation takes
constant time;
* the <em>cycle</em> operation takes time proportional
* to the length of the cycle.
* <p>
* See {@link Topological} to compute a topological order
if the edge-weighted
* digraph is acyclic.
* <p>
* For additional documentation, see <a
href="/algs4/44sp">Section 4.4</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*

* @author Robert Sedgewick


* @author Kevin Wayne
*/
public class EdgeWeightedDirectedCycle {
private boolean[] marked;
has vertex v been marked?
private DirectedEdge[] edgeTo;
previous edge on path to v
private boolean[] onStack;
is vertex on the stack?
private Stack<DirectedEdge> cycle;
(or null if no such cycle)

// marked[v] =
// edgeTo[v] =
// onStack[v] =
// directed cycle

/**
* Determines whether the edge-weighted digraph
<tt>G</tt> has a directed cycle and,
* if so, finds such a cycle.
* @param G the edge-weighted digraph
*/
public EdgeWeightedDirectedCycle(EdgeWeightedDigraph G)
{
marked = new boolean[G.V()];
onStack = new boolean[G.V()];
edgeTo = new DirectedEdge[G.V()];
for (int v = 0; v < G.V(); v++)
if (!marked[v]) dfs(G, v);
// check that digraph has a cycle
assert check(G);
}
// check that algorithm computes either the topological
order or finds a directed cycle
private void dfs(EdgeWeightedDigraph G, int v) {
onStack[v] = true;
marked[v] = true;
for (DirectedEdge e : G.adj(v)) {
int w = e.to();
// short circuit if directed cycle found
if (cycle != null) return;
//found new vertex, so recur
else if (!marked[w]) {
edgeTo[w] = e;
dfs(G, w);
}

// trace back directed cycle


else if (onStack[w]) {
cycle = new Stack<DirectedEdge>();
while (e.from() != w) {
cycle.push(e);
e = edgeTo[e.from()];
}
cycle.push(e);
return;
}
}
onStack[v] = false;
}
/**
* Does the edge-weighted digraph have a directed
cycle?
* @return <tt>true</tt> if the edge-weighted digraph
has a directed cycle,
* <tt>false</tt> otherwise
*/
public boolean hasCycle() {
return cycle != null;
}
/**
* Returns a directed cycle if the edge-weighted
digraph has a directed cycle,
* and <tt>null</tt> otherwise.
* @return a directed cycle (as an iterable) if the
edge-weighted digraph
*
has a directed cycle, and <tt>null</tt> otherwise
*/
public Iterable<DirectedEdge> cycle() {
return cycle;
}
// certify that digraph is either acyclic or has a
directed cycle
private boolean check(EdgeWeightedDigraph G) {
// edge-weighted digraph is cyclic
if (hasCycle()) {
// verify cycle

DirectedEdge first = null, last = null;


for (DirectedEdge e : cycle()) {
if (first == null) first = e;
if (last != null) {
if (last.to() != e.from()) {
System.err.printf("cycle edges %s
and %s not incident\n", last, e);
return false;
}
}
last = e;
}
if (last.to() != first.from()) {
System.err.printf("cycle edges %s and %s not
incident\n", last, first);
return false;
}
}
return true;
}
/**
* Unit tests the <tt>EdgeWeightedDirectedCycle</tt>
data type.
*/
public static void main(String[] args) {
// create random DAG with V vertices and E edges;
then add F random edges
int V = Integer.parseInt(args[0]);
int E = Integer.parseInt(args[1]);
int F = Integer.parseInt(args[2]);
EdgeWeightedDigraph G = new EdgeWeightedDigraph(V);
int[] vertices = new int[V];
for (int i = 0; i < V; i++)
vertices[i] = i;
StdRandom.shuffle(vertices);
for (int i = 0; i < E; i++) {
int v, w;
do {
v = StdRandom.uniform(V);
w = StdRandom.uniform(V);
} while (v >= w);
double weight = StdRandom.uniform();

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);
G.addEdge(new DirectedEdge(v, w, weight));
}
StdOut.println(G);
// find a directed cycle
EdgeWeightedDirectedCycle finder = new
EdgeWeightedDirectedCycle(G);
if (finder.hasCycle()) {
StdOut.print("Cycle: ");
for (DirectedEdge e : finder.cycle()) {
StdOut.print(e + " ");
}
StdOut.println();
}
// or give topologial sort
else {
StdOut.println("No directed cycle");
}
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Tue Jul 28 14:26:38 EDT 2015.
Arbitrage.java
Below is the syntax highlighted version
of Arbitrage.java from 4.4 Shortest Paths.
the Javadoc.

Here is

/
***********************************************************
**************

* Compilation: javac Arbitrage.java


* Execution:
java Arbitrage < input.txt
* Dependencies: EdgeWeightedDigraph.java
DirectedEdge.java
*
BellmanFordSP.java
* Data file:
http://algs4.cs.princeton.edu/44sp/rates.txt
*
* Arbitrage detection.
*
* % more rates.txt
* 5
* USD 1
0.741 0.657 1.061 1.005
* EUR 1.349 1
0.888 1.433 1.366
* GBP 1.521 1.126 1
1.614 1.538
* CHF 0.942 0.698 0.619 1
0.953
* CAD 0.995 0.732 0.650 1.049 1
*
* % java Arbitrage < rates.txt
* 1000.00000 USD = 741.00000 EUR
*
741.00000 EUR = 1012.20600 CAD
* 1012.20600 CAD = 1007.14497 USD
*
***********************************************************
**************/
/**
* The <tt>Arbitrage</tt> class provides a client that
finds an arbitrage
* opportunity in a currency exchange table by
constructing a
* complete-digraph representation of the exchange table
and then finding
* a negative cycle in the digraph.
* <p>
* This implementation uses the Bellman-Ford algorithm to
find a
* negative cycle in the complete digraph.
* The running time is proportional to
<em>V</em><sup>3</sup> in the
* worst case, where <em>V</em> is the number of
currencies.
* <p>
* For additional documentation,

* see <a
href="http://algs4.cs.princeton.edu/44sp">Section 4.4</a>
of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class Arbitrage {
// this class cannot be instantiated
private Arbitrage() { }
/**
* Reads the currency exchange table from standard
input and
* prints an arbitrage opportunity to standard output
(if one exists).
*/
public static void main(String[] args) {
// V currencies
int V = StdIn.readInt();
String[] name = new String[V];
// create complete network
EdgeWeightedDigraph G = new EdgeWeightedDigraph(V);
for (int v = 0; v < V; v++) {
name[v] = StdIn.readString();
for (int w = 0; w < V; w++) {
double rate = StdIn.readDouble();
DirectedEdge e = new DirectedEdge(v, w,
-Math.log(rate));
G.addEdge(e);
}
}
// find negative cycle
BellmanFordSP spt = new BellmanFordSP(G, 0);
if (spt.hasNegativeCycle()) {
double stake = 1000.0;
for (DirectedEdge e : spt.negativeCycle()) {
StdOut.printf("%10.5f %s ", stake,
name[e.from()]);
stake *= Math.exp(-e.weight());

StdOut.printf("= %10.5f %s\n", stake,


name[e.to()]);
}
}
else {
StdOut.println("No arbitrage opportunity");
}
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Tue Oct 22 10:24:29 EDT 2013.
FloydWarshall.java
Below is the syntax highlighted version
of FloydWarshall.java from 4.4 Shortest Paths.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac FloydWarshall.java
* Execution: java FloydWarshall V E
* Dependencies: AdjMatrixEdgeWeightedDigraph.java
*
* Floyd-Warshall all-pairs shortest path algorithm.
*
* % java FloydWarshall 100 500
*
* Should check for negative cycles during triple loop;
otherwise
* intermediate numbers can get exponentially large.
* Reference: "The Floyd-Warshall algorithm on graphs with
negative cycles"
* by Stefan Hougardy
*
***********************************************************
**************/

/**
* The <tt>FloydWarshall</tt> class represents a data type
for solving the
* all-pairs shortest paths problem in edge-weighted
digraphs with
* no negative cycles.
* The edge weights can be positive, negative, or zero.
* This class finds either a shortest path between every
pair of vertices
* or a negative cycle.
* <p>
* This implementation uses the Floyd-Warshall algorithm.
* The constructor takes time proportional to
<em>V</em><sup>3</sup> in the
* worst case, where <em>V</em> is the number of vertices.
* Afterwards, the <tt>dist()</tt>, <tt>hasPath()</tt>, and
<tt>hasNegativeCycle()</tt>
* methods take constant time; the <tt>path()</tt> and
<tt>negativeCycle()</tt>
* method takes time proportional to the number of edges
returned.
* <p>
* For additional documentation, see <a
href="/algs4/44sp">Section 4.4</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/ public class FloydWarshall {
private boolean hasNegativeCycle; // is there a
negative cycle?
private double[][] distTo; // distTo[v][w] = length of
shortest v->w path
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
* the edge-weighted digraph <tt>G</tt>. If no such
shortest path exists for
* some pair of vertices, it computes a negative cycle.
* @param G the edge-weighted digraph
*/
public FloydWarshall(AdjMatrixEdgeWeightedDigraph G) {
int V = G.V();

distTo = new double[V][V];


edgeTo = new DirectedEdge[V][V];
// initialize distances to infinity
for (int v = 0; v < V; v++) {
for (int w = 0; w < V; w++) {
distTo[v][w] = Double.POSITIVE_INFINITY;
}
}
// initialize distances using edge-weighted
digraph's
for (int v = 0; v < G.V(); v++) {
for (DirectedEdge e : G.adj(v)) {
distTo[e.from()][e.to()] = e.weight();
edgeTo[e.from()][e.to()] = e;
}
// in case of self-loops
if (distTo[v][v] >= 0.0) {
distTo[v][v] = 0.0;
edgeTo[v][v] = null;
}
}
// Floyd-Warshall updates
for (int i = 0; i < V; i++) {
// compute shortest paths using only 0, 1, ...,
i as intermediate vertices
for (int v = 0; v < V; v++) {
if (edgeTo[v][i] == null) continue; //
optimization
for (int w = 0; w < V; w++) {
if (distTo[v][w] > distTo[v][i] +
distTo[i][w]) {
distTo[v][w] = distTo[v][i] +
distTo[i][w];
edgeTo[v][w] = edgeTo[i][w];
}
}
// check for negative cycle
if (distTo[v][v] < 0.0) {
hasNegativeCycle = true;
return;
}
}
}
}

/**
* Is there a negative cycle?
* @return <tt>true</tt> if there is a negative cycle,
and <tt>false</tt> otherwise
*/
public boolean hasNegativeCycle() {
return hasNegativeCycle;
}
/**
* Returns a negative cycle, or <tt>null</tt> if there
is no such cycle.
* @return a negative cycle as an iterable of edges,
* or <tt>null</tt> if there is no such cycle
*/
public Iterable<DirectedEdge> negativeCycle() {
for (int v = 0; v < distTo.length; v++) {
// negative cycle in v's predecessor graph
if (distTo[v][v] < 0.0) {
int V = edgeTo.length;
EdgeWeightedDigraph spt = new
EdgeWeightedDigraph(V);
for (int w = 0; w < V; w++)
if (edgeTo[v][w] != null)
spt.addEdge(edgeTo[v][w]);
EdgeWeightedDirectedCycle finder = new
EdgeWeightedDirectedCycle(spt);
assert finder.hasCycle();
return finder.cycle();
}
}
return null;
}
/**
* Is there a path from the vertex <tt>s</tt> to vertex
<tt>t</tt>?
* @param s the source vertex
* @param t the destination vertex
* @return <tt>true</tt> if there is a path from vertex
<tt>s</tt>
* to vertex <tt>t</tt>, and <tt>false</tt> otherwise
*/
public boolean hasPath(int s, int t) {
return distTo[s][t] < Double.POSITIVE_INFINITY;
}

/**
* Returns the length of a shortest path from vertex
<tt>s</tt> to vertex <tt>t</tt>.
* @param s the source vertex
* @param t the destination vertex
* @return the length of a shortest path from vertex
<tt>s</tt> to vertex <tt>t</tt>;
* <tt>Double.POSITIVE_INFINITY</tt> if no such path
* @throws UnsupportedOperationException if there is a
negative cost cycle
*/
public double dist(int s, int t) {
if (hasNegativeCycle())
throw new
UnsupportedOperationException("Negative cost cycle exists");
return distTo[s][t];
}
/**
* Returns a shortest path from vertex <tt>s</tt> to
vertex <tt>t</tt>.
* @param s the source vertex
* @param t the destination vertex
* @return a shortest path from vertex <tt>s</tt> to
vertex <tt>t</tt>
* as an iterable of edges, and <tt>null</tt> if no
such path
* @throws UnsupportedOperationException if there is a
negative cost cycle
*/
public Iterable<DirectedEdge> path(int s, int t) {
if (hasNegativeCycle())
throw new
UnsupportedOperationException("Negative cost cycle exists");
if (!hasPath(s, t)) return null;
Stack<DirectedEdge> path = new
Stack<DirectedEdge>();
for (DirectedEdge e = edgeTo[s][t]; e != null; e =
edgeTo[s][e.from()]) {
path.push(e);
}
return path;
}
// check optimality conditions
private boolean check(EdgeWeightedDigraph G, int s) {

// no negative cycle
if (!hasNegativeCycle()) {
for (int v = 0; v < G.V(); v++) {
for (DirectedEdge e : G.adj(v)) {
int w = e.to();
for (int i = 0; i < G.V(); i++) {
if (distTo[i][w] > distTo[i][v] +
e.weight()) {
System.err.println("edge " + e +
" is eligible");
return false;
}
}
}
}
}
return true;
}
/**
* Unit tests the <tt>FloydWarshall</tt> data type.
*/
public static void main(String[] args) {
// random graph with V vertices and E edges,
parallel edges allowed
int V = Integer.parseInt(args[0]);
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;
if (v == w) G.addEdge(new DirectedEdge(v, w,
Math.abs(weight)));
else G.addEdge(new DirectedEdge(v, w, weight));
}
StdOut.println(G);
// run Floyd-Warshall algorithm
FloydWarshall spt = new FloydWarshall(G);

// print all-pairs shortest path distances


StdOut.printf(" ");
for (int v = 0; v < G.V(); v++) {
StdOut.printf("%6d ", v);
}
StdOut.println();
for (int v = 0; v < G.V(); v++) {
StdOut.printf("%3d: ", v);
for (int w = 0; w < G.V(); w++) {
if (spt.hasPath(v, w)) StdOut.printf("%6.2f
", spt.dist(v, w));
else StdOut.printf(" Inf ");
}
StdOut.println();
}
// print negative cycle
if (spt.hasNegativeCycle()) {
StdOut.println("Negative cost cycle:");
for (DirectedEdge e : spt.negativeCycle())
StdOut.println(e);
StdOut.println();
}
// print all-pairs shortest paths
else {
for (int v = 0; v < G.V(); v++) {
for (int w = 0; w < G.V(); w++) {
if (spt.hasPath(v, w)) {
StdOut.printf("%d to %d (%5.2f) ",
v, w, spt.dist(v, w));
for (DirectedEdge e : spt.path(v,
w))
StdOut.print(e + " ");
StdOut.println();
}
else {
StdOut.printf("%d to %d no path\n",
v, w);
}
}
}
}
}
}

Copyright 20022010, Robert Sedgewick and Kevin Wayne.


Last updated: Wed Jul 22 17:41:34 EDT 2015.

AdjMatrixEdgeWeightedDigraph.java
Below is the syntax highlighted version
of AdjMatrixEdgeWeightedDigraph.java from 4.4 Shortest
Paths.
Here is the Javadoc.

/
***********************************************************
**************
* Compilation: javac AdjMatrixEdgeWeightedDigraph.java
* Execution:
java AdjMatrixEdgeWeightedDigraph V E
* Dependencies: StdOut.java
*
* An edge-weighted digraph, implemented using an
adjacency matrix.
* Parallel edges are disallowed; self-loops are allowed.
*
***********************************************************
**************/
import java.util.Iterator;
import java.util.NoSuchElementException;
/**
* The <tt>AdjMatrixEdgeWeightedDigraph</tt> class
represents a edge-weighted
* digraph of vertices named 0 through <em>V</em> - 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
* to the digraph and iterate over all of edges incident
from a given vertex.
* It also provides
* methods for returning the number of vertices <em>V</em>
and the number
* of edges <em>E</em>. Parallel edges are disallowed;
self-loops are permitted.
* <p>
* This implementation uses an adjacency-matrix
representation.
* All operations take constant time (in the worst case)
except
* iterating over the edges incident from a given vertex,
which takes
* time proportional to <em>V</em>.
* <p>
* For additional documentation,
* see <a
href="http://algs4.cs.princeton.edu/44sp">Section 4.4</a>
of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class AdjMatrixEdgeWeightedDigraph {
private static final String NEWLINE =
System.getProperty("line.separator");
private int V;
private int E;
private DirectedEdge[][] adj;
/**
* Initializes an empty edge-weighted digraph with
<tt>V</tt> vertices and 0 edges.
* param V the number of vertices
* @throws java.lang.IllegalArgumentException if
<tt>V</tt> < 0
*/
public AdjMatrixEdgeWeightedDigraph(int V) {
if (V < 0) throw new RuntimeException("Number of
vertices must be nonnegative");
this.V = V;

this.E = 0;
this.adj = new DirectedEdge[V][V];
}
/**
* Initializes a random edge-weighted digraph with
<tt>V</tt> vertices and <em>E</em> edges.
* param V the number of vertices
* param E the number of edges
* @throws java.lang.IllegalArgumentException if
<tt>V</tt> < 0
* @throws java.lang.IllegalArgumentException if
<tt>E</tt> < 0
*/
public AdjMatrixEdgeWeightedDigraph(int V, int E) {
this(V);
if (E < 0) throw new RuntimeException("Number of
edges must be nonnegative");
if (E > V*V) throw new RuntimeException("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;
addEdge(new DirectedEdge(v, w, weight));
}
}
/**
* Returns
digraph.
* @return
digraph
*/
public int
return
}

the number of vertices in the edge-weighted


the number of vertices in the edge-weighted
V() {
V;

/**
* Returns the number of edges in the edge-weighted
digraph.
* @return the number of edges in the edge-weighted
digraph
*/

public int E() {


return E;
}
/**
* Adds the directed edge <tt>e</tt> to the edgeweighted digraph (if there
* is not already an edge with the same endpoints).
* @param e the edge
*/
public void addEdge(DirectedEdge e) {
int v = e.from();
int w = e.to();
if (adj[v][w] == null) {
E++;
adj[v][w] = e;
}
}
/**
* Returns the directed edges incident from vertex
<tt>v</tt>.
* @param v the vertex
* @return the directed edges incident from vertex
<tt>v</tt> as an Iterable
* @throws java.lang.IndexOutOfBoundsException unless 0
<= v < V
*/
public Iterable<DirectedEdge> adj(int v) {
return new AdjIterator(v);
}
// support iteration over graph vertices
private class AdjIterator implements
Iterator<DirectedEdge>, Iterable<DirectedEdge> {
private int v;
private int w = 0;
public AdjIterator(int v) {
this.v = v;
}
public Iterator<DirectedEdge> iterator() {
return this;
}
public boolean hasNext() {

while (w < V) {
if (adj[v][w] != null) return true;
w++;
}
return false;
}
public DirectedEdge next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
return adj[v][w++];
}
public void remove() {
throw new UnsupportedOperationException();
}
}
/**
* Returns a string representation of the edge-weighted
digraph. This method takes
* time proportional to <em>V</em><sup>2</sup>.
* @return the number of vertices <em>V</em>, followed
by the number of edges <em>E</em>,
*
followed by the <em>V</em> adjacency lists of
edges
*/
public String toString() {
StringBuilder s = new StringBuilder();
s.append(V + " " + E + NEWLINE);
for (int v = 0; v < V; v++) {
s.append(v + ": ");
for (DirectedEdge e : adj(v)) {
s.append(e + " ");
}
s.append(NEWLINE);
}
return s.toString();
}
/**
* Unit tests the <tt>AdjMatrixEdgeWeightedDigraph</tt>
data type.
*/
public static void main(String[] args) {
int V = Integer.parseInt(args[0]);

int E = Integer.parseInt(args[1]);
AdjMatrixEdgeWeightedDigraph G = new
AdjMatrixEdgeWeightedDigraph(V, E);
StdOut.println(G);
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Tue Jul 28 06:21:05 EDT 2015.
/
************************************************************
*************
* Compilation: javac Alphabet.java
* Execution:
java Alphabet
* Dependencies: StdOut.java
*
* A data type for alphabets, for use with stringprocessing code
* that must convert between an alphabet of size R and the
integers
* 0 through R-1.
*
* Warning: supports only the basic multilingual plane
(BMP), i.e,
*
Unicode characters between U+0000 and U+FFFF.
*
************************************************************
*************/
public class Alphabet {
public static final Alphabet BINARY
Alphabet("01");
public static final Alphabet OCTAL
Alphabet("01234567");
public static final Alphabet DECIMAL
Alphabet("0123456789");
public static final Alphabet HEXADECIMAL
Alphabet("0123456789ABCDEF");
public static final Alphabet DNA
Alphabet("ACTG");
public static final Alphabet LOWERCASE
Alphabet("abcdefghijklmnopqrstuvwxyz");

= new
= new
= new
= new
= new
= new

public static final Alphabet UPPERCASE


= new
Alphabet("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
public static final Alphabet PROTEIN
= new
Alphabet("ACDEFGHIKLMNPQRSTVWY");
public static final Alphabet BASE64
= new
Alphabet("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwx
yz0123456789+/");
public static final Alphabet ASCII
= new
Alphabet(128);
public static final Alphabet EXTENDED_ASCII = new
Alphabet(256);
public static final Alphabet UNICODE16
= new
Alphabet(65536);
private char[] alphabet;
alphabet
private int[] inverse;
private int R;
alphabet

// the characters in the


// indices
// the radix of the

// Create a new Alphabet from sequence of characters in


string.
public Alphabet(String alpha) {
// check that alphabet contains no duplicate chars
boolean[] unicode = new
boolean[Character.MAX_VALUE];
for (int i = 0; i < alpha.length(); i++) {
char c = alpha.charAt(i);
if (unicode[c])
throw new IllegalArgumentException("Illegal
alphabet: repeated character = '" + c + "'");
unicode[c] = true;
}
alphabet = alpha.toCharArray();
R = alpha.length();
inverse = new int[Character.MAX_VALUE];
for (int i = 0; i < inverse.length; i++)
inverse[i] = -1;
// can't use char since R can be as big as 65,536
for (int c = 0; c < R; c++)
inverse[alphabet[c]] = c;
}
// Create a new Alphabet of Unicode chars 0 to R-1

private Alphabet(int R) {
alphabet = new char[R];
inverse = new int[R];
this.R = R;
// can't use char since R can be as big as 65,536
for (int i = 0; i < R; i++)
alphabet[i] = (char) i;
for (int i = 0; i < R; i++)
inverse[i] = i;
}
// Create a new Alphabet of Unicode chars 0 to 255
(extended ASCII)
public Alphabet() {
this(256);
}
// is character c in the alphabet?
public boolean contains(char c) {
return inverse[c] != -1;
}
// return radix R
public int R() {
return R;
}
// return number of bits to represent an index
public int lgR() {
int lgR = 0;
for (int t = R-1; t >= 1; t /= 2)
lgR++;
return lgR;
}
// convert c to index between 0 and R-1.
public int toIndex(char c) {
if (c >= inverse.length || inverse[c] == -1) {
throw new IllegalArgumentException("Character "
+ c + " not in alphabet");
}
return inverse[c];
}
// convert String s over this alphabet into a base-R
integer

public int[] toIndices(String s) {


char[] source = s.toCharArray();
int[] target = new int[s.length()];
for (int i = 0; i < source.length; i++)
target[i] = toIndex(source[i]);
return target;
}
// convert an index between 0 and R-1 into a char over
this alphabet
public char toChar(int index) {
if (index < 0 || index >= R) {
throw new IndexOutOfBoundsException("Alphabet
index out of bounds");
}
return alphabet[index];
}
// Convert base-R integer into a String over this
alphabet
public String toChars(int[] indices) {
StringBuilder s = new StringBuilder(indices.length);
for (int i = 0; i < indices.length; i++)
s.append(toChar(indices[i]));
return s.toString();
}
public static void main(String[] args) {
int[] encoded1 =
Alphabet.BASE64.toIndices("NowIsTheTimeForAllGoodMen");
String decoded1 = Alphabet.BASE64.toChars(encoded1);
StdOut.println(decoded1);
int[] encoded2 =
Alphabet.DNA.toIndices("AACGAACGGTTTACCCCG");
String decoded2 = Alphabet.DNA.toChars(encoded2);
StdOut.println(decoded2);
int[] encoded3 =
Alphabet.DECIMAL.toIndices("01234567890123456789");
String decoded3 =
Alphabet.DECIMAL.toChars(encoded3);
StdOut.println(decoded3);
}
}

Count.java
Below is the syntax highlighted version
of Count.java from 5 Strings.
Here is the Javadoc.

/
***********************************************************
**************
* Compilation: javac Count.java
* Execution:
java Count alpha < input.txt
* Dependencies: Alphabet.java StdOut.java
*
* 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
* A 5
* B 2
* C 1
* D 1
* R 2
*
* % java Count 0123456789 < pi.txt
* 0 99959
* 1 99757

*
*
*
*
*
*
*
*
*

2
3
4
5
6
7
8
9

100026
100230
100230
100359
99548
99800
99985
100106

***********************************************************
**************/

public class Count {


public static void main(String[] args) {
Alphabet alpha = new Alphabet(args[0]);
int R = alpha.R();
int[] count = new int[R];
String a = StdIn.readAll();
int N = a.length();
for (int i = 0; i < N; i++)
if (alpha.contains(a.charAt(i)))
count[alpha.toIndex(a.charAt(i))]++;
for (int c = 0; c < R; c++)
StdOut.println(alpha.toChar(c) + " " +
count[c]);
}
}

Copyright 20022010, Robert Sedgewick and Kevin Wayne.


Last updated: Tue Jul 28 14:31:09 EDT 2015.
LSD.java
Below is the syntax highlighted version
of LSD.java from 5.1 String Sorts.
Here is the Javadoc.

/
***********************************************************
************************
* Compilation: javac LSD.java

* Execution:
java LSD < input.txt
* Dependencies: StdIn.java StdOut.java
*
* LSD radix sort
*
*
- Sort a String[] array of N extended ASCII strings
(R = 256), each of length W.
*
*
- Sort an int[] array of N 32-bit integers, treating
each integer as
*
a sequence of W = 4 bytes (R = 256).
*
* Uses extra space proportional to N + R.
*
*
* % java LSD < words3.txt
* all
* bad
* bed
* bug
* dad
* ...
* yes
* yet
* zoo
*
***********************************************************
************************/
public class LSD {
private static final int BITS_PER_BYTE = 8;
// LSD radix sort
public static void sort(String[] a, int W) {
int N = a.length;
int R = 256;
// extend ASCII alphabet size
String[] aux = new String[N];
for (int d = W-1; d >= 0; d--) {
// sort by key-indexed counting on dth
character
// compute frequency counts
int[] count = new int[R+1];
for (int i = 0; i < N; i++)

count[a[i].charAt(d) + 1]++;
// compute cumulates
for (int r = 0; r < R; r++)
count[r+1] += count[r];
// move data
for (int i = 0; i < N; i++)
aux[count[a[i].charAt(d)]++] = a[i];
// copy back
for (int i = 0; i < N; i++)
a[i] = aux[i];
}
}
// LSD sort an array of integers, treating
4 bytes
// assumes integers are nonnegative
// [ 2-3x faster than Arrays.sort() ]
public static void sort(int[] a) {
int BITS = 32;
// each
bits
int W = BITS / BITS_PER_BYTE; // each
bytes
int R = 1 << BITS_PER_BYTE;
// each
between 0 and 255
int MASK = R - 1;
// 0xFF

each int as

int is 32
int is 4
bytes is

int N = a.length;
int[] aux = new int[N];
for (int d = 0; d < W; d++) {
// compute frequency counts
int[] count = new int[R+1];
for (int i = 0; i < N; i++) {
int c = (a[i] >> BITS_PER_BYTE*d) & MASK;
count[c + 1]++;
}
// compute cumulates
for (int r = 0; r < R; r++)
count[r+1] += count[r];
// for most significant byte, 0x80-0xFF comes
before 0x00-0x7F

if (d == W-1) {
int shift1 =
int shift2 =
for (int r =
count[r]
for (int r =
count[r]
}

count[R] - count[R/2];
count[R/2];
0; r < R/2; r++)
+= shift1;
R/2; r < R; r++)
-= shift2;

// move data
for (int i = 0; i < N; i++) {
int c = (a[i] >> BITS_PER_BYTE*d) & MASK;
aux[count[c]++] = a[i];
}
// copy back
for (int i = 0; i < N; i++)
a[i] = aux[i];
}
}
public static void main(String[] args) {
String[] a = StdIn.readAllStrings();
int N = a.length;
// check that strings have fixed length
int W = a[0].length();
for (int i = 0; i < N; i++)
assert a[i].length() == W : "Strings must have
fixed length";
// sort the strings
sort(a, W);
// print results
for (int i = 0; i < N; i++)
StdOut.println(a[i]);
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Tue Jul 28 09:05:33 EDT 2015.
MSD.java

Below is the syntax highlighted version


of MSD.java from 5.1 String Sorts.
Here is the Javadoc.

/
***********************************************************
************************
* Compilation: javac MSD.java
* Execution:
java MSD < input.txt
* Dependencies: StdIn.java StdOut.java
*
*
- Sort a String[] array of N extended ASCII strings
(R = 256), each of length W.
*
*
- Sort an int[] array of N 32-bit integers, treating
each integer as
*
a sequence of W = 4 bytes (R = 256).
*
*
* % java MSD < shells.txt
* are
* by
* sea
* seashells
* seashells
* sells
* sells
* she
* she
* shells
* shore
* surely
* the
* the
*
***********************************************************
************************/
public class MSD {
private static final int BITS_PER_BYTE =
8;
private static final int BITS_PER_INT = 32;
Java int is 32 bits
private static final int R
= 256;
extended ASCII alphabet size

// each
//

private static final int CUTOFF


cutoff to insertion sort

15;

//

// sort array of strings


public static void sort(String[] a) {
int N = a.length;
String[] aux = new String[N];
sort(a, 0, N-1, 0, aux);
}
// return dth character of s, -1 if d = length of
string
private static int charAt(String s, int d) {
assert d >= 0 && d <= s.length();
if (d == s.length()) return -1;
return s.charAt(d);
}
// sort from a[lo] to a[hi], starting at the dth
character
private static void sort(String[] a, int lo, int hi, int
d, String[] aux) {
// cutoff to insertion sort for small subarrays
if (hi <= lo + CUTOFF) {
insertion(a, lo, hi, d);
return;
}
// compute frequency counts
int[] count = new int[R+2];
for (int i = lo; i <= hi; i++) {
int c = charAt(a[i], d);
count[c+2]++;
}
// transform counts to indicies
for (int r = 0; r < R+1; r++)
count[r+1] += count[r];
// distribute
for (int i = lo; i <= hi; i++) {
int c = charAt(a[i], d);
aux[count[c+1]++] = a[i];
}
// copy back

for (int i = lo; i <= hi; i++)


a[i] = aux[i - lo];
// recursively sort for each character (excludes
sentinel -1)
for (int r = 0; r < R; r++)
sort(a, lo + count[r], lo + count[r+1] - 1, d+1,
aux);
}
// 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++)
for (int j = i; j > lo && less(a[j], a[j-1], d);
j--)
exch(a, j, j-1);
}
// exchange a[i] and a[j]
private static void exch(String[] a, int i, int j) {
String temp = a[i];
a[i] = a[j];
a[j] = temp;
}
// is v less than w, starting at character d
private static boolean less(String v, String w, int d) {
// assert v.substring(0, d).equals(w.substring(0,
d));
for (int i = d; i <
w.length()); i++) {
if (v.charAt(i)
if (v.charAt(i)
}
return v.length() <
}

Math.min(v.length(),
< w.charAt(i)) return true;
> w.charAt(i)) return false;
w.length();

// MSD sort array of integers


public static void sort(int[] a) {
int N = a.length;
int[] aux = new int[N];
sort(a, 0, N-1, 0, aux);
}

// MSD sort from a[lo] to a[hi], starting at the dth


byte
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);
return;
}
// compute frequency counts (need R = 256)
int[] count = new int[R+1];
int mask = R - 1;
// 0xFF;
int shift = BITS_PER_INT - BITS_PER_BYTE*d BITS_PER_BYTE;
for (int i = lo; i <= hi; i++) {
int c = (a[i] >> shift) & mask;
count[c + 1]++;
}
// transform counts to indicies
for (int r = 0; r < R; r++)
count[r+1] += count[r];
/*************BUGGGY
// 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];
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;
aux[count[c]++] = a[i];
}
// copy back
for (int i = lo; i <= hi; i++)
a[i] = aux[i - lo];

// no more bits
if (d == 4) return;
// recursively sort for each character
if (count[0] > 0)
sort(a, lo, lo + count[0] - 1, d+1, aux);
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);
}
// insertion sort a[lo..hi], starting at dth character
private static void insertion(int[] a, int lo, int hi,
int d) {
for (int i = lo; i <= hi; i++)
for (int j = i; j > lo && a[j] < a[j-1]; j--)
exch(a, j, j-1);
}
// exchange a[i] and a[j]
private static void exch(int[] a, int i, int j) {
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
public static void main(String[] args) {
String[] a = StdIn.readAllStrings();
int N = a.length;
sort(a);
for (int i = 0; i < N; i++)
StdOut.println(a[i]);
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Tue Jul 28 09:05:33 EDT 2015.
Quick3string.java
Below is the syntax highlighted version
of Quick3string.java from 5.1 String Sorts.
the Javadoc.

Here is

/
***********************************************************
************************
* Compilation: javac Quick3string.java
* Execution:
java Quick3string < input.txt
* Dependencies: StdIn.java StdOut.java
*
* Reads string from standard input and 3-way string
quicksort them.
*
* % java Quick3string < shell.txt
* are
* by
* sea
* seashells
* seashells
* sells
* sells
* she
* she
* shells
* shore
* surely
* the
* the
*
*
***********************************************************
************************/
public class Quick3string {
private static final int CUTOFF =
insertion sort

15;

// cutoff to

// sort the array a[] of strings


public static void sort(String[] a) {
StdRandom.shuffle(a);
sort(a, 0, a.length-1, 0);
assert isSorted(a);
}
// return the dth character of s, -1 if d = length of s
private static int charAt(String s, int d) {
assert d >= 0 && d <= s.length();

if (d == s.length()) return -1;


return s.charAt(d);
}
// 3-way string quicksort a[lo..hi] starting at dth
character
private static void sort(String[] a, int lo, int hi, int
d) {
// cutoff to insertion sort for small subarrays
if (hi <= lo + CUTOFF) {
insertion(a, lo, hi, d);
return;
}
int lt = lo, gt = hi;
int v = charAt(a[lo], d);
int i = lo + 1;
while (i <= gt) {
int t = charAt(a[i], d);
if
(t < v) exch(a, lt++, i++);
else if (t > v) exch(a, i, gt--);
else
i++;
}
// 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);
}
// sort from a[lo] to a[hi], starting at the dth
character
private static void insertion(String[] a, int lo, int
hi, int d) {
for (int i = lo; i <= hi; i++)
for (int j = i; j > lo && less(a[j], a[j-1], d);
j--)
exch(a, j, j-1);
}
// exchange a[i] and a[j]
private static void exch(String[] a, int i, int j) {
String temp = a[i];
a[i] = a[j];
a[j] = temp;

}
//
//
JAVA 7
//
d) {
//
d));
//
0;
//

is v less than w, starting at character d


DEPRECATED BECAUSE OF SLOW SUBSTRING EXTRACTION IN
private static boolean less(String v, String w, int
assert v.substring(0, d).equals(w.substring(0,
return v.substring(d).compareTo(w.substring(d)) <
}

// is v less than w, starting at character d


private static boolean less(String v, String w, int d) {
assert v.substring(0, d).equals(w.substring(0, d));
for (int i = d; i < Math.min(v.length(),
w.length()); i++) {
if (v.charAt(i) < w.charAt(i)) return true;
if (v.charAt(i) > w.charAt(i)) return false;
}
return v.length() < w.length();
}
// is the array sorted
private static boolean isSorted(String[] a) {
for (int i = 1; i < a.length; i++)
if (a[i].compareTo(a[i-1]) < 0) return false;
return true;
}
public static void main(String[] args) {
// read in the strings from standard input
String[] a = StdIn.readAllStrings();
int N = a.length;
// sort the strings
sort(a);
// print the results
for (int i = 0; i < N; i++)
StdOut.println(a[i]);
}
}

Copyright 20022010, Robert Sedgewick and Kevin Wayne.


Last updated: Tue Jul 28 09:05:33 EDT 2015.
TrieST.java
Below is the syntax highlighted version
of TrieST.java from 5.2 Tries.
Here is the Javadoc.

/
***********************************************************
**************
* Compilation: javac TrieST.java
* Execution:
java TrieST < words.txt
* Dependencies: StdIn.java
*
* A string symbol table for extended ASCII strings,
implemented
* using a 256-way trie.
*
* % java TrieST < shellsST.txt
* by 4
* sea 6
* sells 1
* she 0
* shells 3
* shore 7
* the 5
*
***********************************************************
**************/
/**
* The <tt>TrieST</tt> class represents an symbol table of
key-value
* pairs, with string keys and generic values.
* It supports the usual <em>put</em>, <em>get</em>,
<em>contains</em>,
* <em>delete</em>, <em>size</em>, and <em>is-empty</em>
methods.
* It also provides character-based methods for finding
the string
* in the symbol table that is the <em>longest prefix</em>
of a given prefix,

* finding all strings in the symbol table that <em>start


with</em> a given prefix,
* and finding all strings in the symbol table that
<em>match</em> a given pattern.
* A symbol table implements the <em>associative array</em>
abstraction:
* when associating a value with a key that is already in
the symbol table,
* the convention is to replace the old value with the new
value.
* Unlike {@link java.util.Map}, this class uses the
convention that
* values cannot be <tt>null</tt>&mdash;setting the
* value associated with a key to <tt>null</tt> is
equivalent to deleting the key
* from the symbol table.
* <p>
* This implementation uses a 256-way trie.
* The <em>put</em>, <em>contains</em>, <em>delete</em>,
and
* <em>longest prefix</em> operations take time
proportional to the length
* of the key (in the worst case). Construction takes
constant time.
* The <em>size</em>, and <em>is-empty</em> operations
take constant time.
* Construction takes constant time.
* <p>
* For additional documentation, see <a
href="http://algs4.cs.princeton.edu/52trie">Section 5.2</a>
of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*/
public class TrieST<Value> {
private static final int R = 256;
// extended
ASCII
private Node root;
private int N;

// root of trie
// number of keys in trie

// R-way trie node


private static class Node {
private Object val;
private Node[] next = new Node[R];
}

/**
* Initializes an empty string symbol table.
*/
public TrieST() {
}
/**
* Returns the value associated
* @param key the key
* @return the value associated
the key is in the symbol table
*
and <tt>null</tt> if the
symbol table
* @throws NullPointerException
<tt>null</tt>
*/
public Value get(String key) {
Node x = get(root, key, 0);
if (x == null) return null;
return (Value) x.val;
}

with the given key.


with the given key if
key is not in the
if <tt>key</tt> is

/**
* Does this symbol table contain the given key?
* @param key the key
* @return <tt>true</tt> if this symbol table contains
<tt>key</tt> and
*
<tt>false</tt> otherwise
* @throws NullPointerException if <tt>key</tt> is
<tt>null</tt>
*/
public boolean contains(String key) {
return get(key) != null;
}
private Node get(Node x, String key, int d) {
if (x == null) return null;
if (d == key.length()) return x;
char c = key.charAt(d);
return get(x.next[c], key, d+1);
}
/**
* Inserts the key-value pair into the symbol table,
overwriting the old value

* with the new value if the key is already in the


symbol table.
* If the value is <tt>null</tt>, this effectively
deletes the key from the symbol table.
* @param key the key
* @param val the value
* @throws NullPointerException if <tt>key</tt> is
<tt>null</tt>
*/
public void put(String key, Value val) {
if (val == null) delete(key);
else root = put(root, key, val, 0);
}
private Node put(Node x, String key, Value val, int d) {
if (x == null) x = new Node();
if (d == key.length()) {
if (x.val == null) N++;
x.val = val;
return x;
}
char c = key.charAt(d);
x.next[c] = put(x.next[c], key, val, d+1);
return x;
}
/**
* Returns
table.
* @return
table
*/
public int
return
}

the number of key-value pairs in this symbol


the number of key-value pairs in this symbol
size() {
N;

/**
* Is this symbol table empty?
* @return <tt>true</tt> if this symbol table is empty
and <tt>false</tt> otherwise
*/
public boolean isEmpty() {
return size() == 0;
}
/**

* Returns all keys in the symbol table as an


<tt>Iterable</tt>.
* To iterate over all of the keys in the symbol table
named <tt>st</tt>,
* use the foreach notation: <tt>for (Key key :
st.keys())</tt>.
* @return all keys in the sybol table as an
<tt>Iterable</tt>
*/
public Iterable<String> keys() {
return keysWithPrefix("");
}
/**
* Returns all of the keys in the set that start with
<tt>prefix</tt>.
* @param prefix the prefix
* @return all of the keys in the set that start with
<tt>prefix</tt>,
*
as an iterable
*/
public Iterable<String> keysWithPrefix(String prefix) {
Queue<String> results = new Queue<String>();
Node x = get(root, prefix, 0);
collect(x, new StringBuilder(prefix), results);
return results;
}
private void collect(Node x, StringBuilder prefix,
Queue<String> results) {
if (x == null) return;
if (x.val != null)
results.enqueue(prefix.toString());
for (char c = 0; c < R; c++) {
prefix.append(c);
collect(x.next[c], prefix, results);
prefix.deleteCharAt(prefix.length() - 1);
}
}
/**
* Returns all of the keys in the symbol table that
match <tt>pattern</tt>,
* where . symbol is treated as a wildcard character.
* @param pattern the pattern
* @return all of the keys in the symbol table that
match <tt>pattern</tt>,

*
as an iterable, where . is treated as a wildcard
character.
*/
public Iterable<String> keysThatMatch(String pattern) {
Queue<String> results = new Queue<String>();
collect(root, new StringBuilder(), pattern,
results);
return results;
}
private void collect(Node x, StringBuilder prefix,
String pattern, Queue<String> results) {
if (x == null) return;
int d = prefix.length();
if (d == pattern.length() && x.val != null)
results.enqueue(prefix.toString());
if (d == pattern.length())
return;
char c = pattern.charAt(d);
if (c == '.') {
for (char ch = 0; ch < R; ch++) {
prefix.append(ch);
collect(x.next[ch], prefix, pattern,
results);
prefix.deleteCharAt(prefix.length() - 1);
}
}
else {
prefix.append(c);
collect(x.next[c], prefix, pattern, results);
prefix.deleteCharAt(prefix.length() - 1);
}
}
/**
* Returns the string in the symbol table that is the
longest prefix of <tt>query</tt>,
* or <tt>null</tt>, if no such string.
* @param query the query string
* @return the string in the symbol table that is the
longest prefix of <tt>query</tt>,
*
or <tt>null</tt> if no such string
* @throws NullPointerException if <tt>query</tt> is
<tt>null</tt>
*/
public String longestPrefixOf(String query) {
int length = longestPrefixOf(root, query, 0, -1);

if (length == -1) return null;


else return query.substring(0, length);
}
// returns the length of the longest string key in the
subtrie
// rooted at x that is a prefix of the query string,
// assuming the first d character match and we have
already
// found a prefix match of given length (-1 if no such
match)
private int longestPrefixOf(Node x, String query, int d,
int length) {
if (x == null) return length;
if (x.val != null) length = d;
if (d == query.length()) return length;
char c = query.charAt(d);
return longestPrefixOf(x.next[c], query, d+1,
length);
}
/**
* Removes the key from the set if the key is present.
* @param key the key
* @throws NullPointerException if <tt>key</tt> is
<tt>null</tt>
*/
public void delete(String key) {
root = delete(root, key, 0);
}
private Node delete(Node x, String key, int d) {
if (x == null) return null;
if (d == key.length()) {
if (x.val != null) N--;
x.val = null;
}
else {
char c = key.charAt(d);
x.next[c] = delete(x.next[c], key, d+1);
}
// remove subtrie rooted at x if it is completely
empty
if (x.val != null) return x;
for (int c = 0; c < R; c++)
if (x.next[c] != null)

return x;
return null;
}
/**
* Unit tests the <tt>TrieST</tt> data type.
*/
public static void main(String[] args) {
// build symbol table from standard input
TrieST<Integer> st = new TrieST<Integer>();
for (int i = 0; !StdIn.isEmpty(); i++) {
String key = StdIn.readString();
st.put(key, i);
}
// print results
if (st.size() < 100) {
StdOut.println("keys(\"\"):");
for (String key : st.keys()) {
StdOut.println(key + " " + st.get(key));
}
StdOut.println();
}
StdOut.println("longestPrefixOf(\"shellsort\"):");
StdOut.println(st.longestPrefixOf("shellsort"));
StdOut.println();
StdOut.println("longestPrefixOf(\"quicksort\"):");
StdOut.println(st.longestPrefixOf("quicksort"));
StdOut.println();
StdOut.println("keysWithPrefix(\"shor\"):");
for (String s : st.keysWithPrefix("shor"))
StdOut.println(s);
StdOut.println();
StdOut.println("keysThatMatch(\".he.l.\"):");
for (String s : st.keysThatMatch(".he.l."))
StdOut.println(s);
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Tue Jul 28 09:33:03 EDT 2015.

TrieSET.java
Below is the syntax highlighted version
of TrieSET.java from 5.2 Tries.
Here is the Javadoc.

/
***********************************************************
**************
* Compilation: javac TrieSET.java
* Execution:
java TrieSET < words.txt
* Dependencies: StdIn.java
*
* An set for extended ASCII strings, implemented using a
256-way trie.
*
* Sample client reads in a list of words from standard
input and
* prints out each word, removing any duplicates.
*
***********************************************************
**************/
import java.util.Iterator;
/**
* The <tt>TrieSET</tt> class represents an ordered set of
strings over
* the extended ASCII alphabet.
* It supports the usual <em>add</em>, <em>contains</em>,
and <em>delete</em>
* methods. It also provides character-based methods for
finding the string
* in the set that is the <em>longest prefix</em> of a
given prefix,
* finding all strings in the set that <em>start with</em>
a given prefix,
* and finding all strings in the set that <em>match</em>
a given pattern.
* <p>
* This implementation uses a 256-way trie.
* The <em>add</em>, <em>contains</em>, <em>delete</em>,
and

* <em>longest prefix</em> methods take time proportional


to the length
* of the key (in the worst case). Construction takes
constant time.
* <p>
* For additional documentation, see
* <a href="http://algs4.cs.princeton.edu/52trie">Section
5.2</a> of
* <i>Algorithms in Java, 4th Edition</i> by Robert
Sedgewick and Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class TrieSET implements Iterable<String> {
private static final int R = 256;
// extended
ASCII
private Node root;
private int N;

// root of trie
// number of keys in trie

// R-way trie node


private static class Node {
private Node[] next = new Node[R];
private boolean isString;
}
/**
* Initializes an empty set of strings.
*/
public TrieSET() {
}
/**
* Does the set contain the given key?
* @param key the key
* @return <tt>true</tt> if the set contains
<tt>key</tt> and
*
<tt>false</tt> otherwise
* @throws NullPointerException if <tt>key</tt> is
<tt>null</tt>
*/
public boolean contains(String key) {
Node x = get(root, key, 0);
if (x == null) return false;
return x.isString;
}

private Node get(Node x, String key, int d) {


if (x == null) return null;
if (d == key.length()) return x;
char c = key.charAt(d);
return get(x.next[c], key, d+1);
}
/**
* Adds the key to the set if it is not already
present.
* @param key the key to add
* @throws NullPointerException if <tt>key</tt> is
<tt>null</tt>
*/
public void add(String key) {
root = add(root, key, 0);
}
private Node add(Node x, String key, int d) {
if (x == null) x = new Node();
if (d == key.length()) {
if (!x.isString) N++;
x.isString = true;
}
else {
char c = key.charAt(d);
x.next[c] = add(x.next[c], key, d+1);
}
return x;
}
/**
* Returns
* @return
*/
public int
return
}

the number of strings in the set.


the number of strings in the set
size() {
N;

/**
* Is the set empty?
* @return <tt>true</tt> if the set is empty, and
<tt>false</tt> otherwise
*/
public boolean isEmpty() {
return size() == 0;

}
/**
* Returns all of the keys in the set, as an iterator.
* To iterate over all of the keys in a set named
<tt>set</tt>, use the
* foreach notation: <tt>for (Key key : set)</tt>.
* @return an iterator to all of the keys in the set
*/
public Iterator<String> iterator() {
return keysWithPrefix("").iterator();
}
/**
* Returns all of the keys in the set that start with
<tt>prefix</tt>.
* @param prefix the prefix
* @return all of the keys in the set that start with
<tt>prefix</tt>,
*
as an iterable
*/
public Iterable<String> keysWithPrefix(String prefix) {
Queue<String> results = new Queue<String>();
Node x = get(root, prefix, 0);
collect(x, new StringBuilder(prefix), results);
return results;
}
private void collect(Node x, StringBuilder prefix,
Queue<String> results) {
if (x == null) return;
if (x.isString) results.enqueue(prefix.toString());
for (char c = 0; c < R; c++) {
prefix.append(c);
collect(x.next[c], prefix, results);
prefix.deleteCharAt(prefix.length() - 1);
}
}
/**
* Returns all of
<tt>pattern</tt>,
* where . symbol
* @param pattern
* @return all of
<tt>pattern</tt>,

the keys in the set that match


is treated as a wildcard character.
the pattern
the keys in the set that match

*
as an iterable, where . is treated as a wildcard
character.
*/
public Iterable<String> keysThatMatch(String pattern) {
Queue<String> results = new Queue<String>();
StringBuilder prefix = new StringBuilder();
collect(root, prefix, pattern, results);
return results;
}
private void collect(Node x, StringBuilder prefix,
String pattern, Queue<String> results) {
if (x == null) return;
int d = prefix.length();
if (d == pattern.length() && x.isString)
results.enqueue(prefix.toString());
if (d == pattern.length())
return;
char c = pattern.charAt(d);
if (c == '.') {
for (char ch = 0; ch < R; ch++) {
prefix.append(ch);
collect(x.next[ch], prefix, pattern,
results);
prefix.deleteCharAt(prefix.length() - 1);
}
}
else {
prefix.append(c);
collect(x.next[c], prefix, pattern, results);
prefix.deleteCharAt(prefix.length() - 1);
}
}
/**
* Returns the string in the set that is the longest
prefix of <tt>query</tt>,
* or <tt>null</tt>, if no such string.
* @param query the query string
* @return the string in the set that is the longest
prefix of <tt>query</tt>,
*
or <tt>null</tt> if no such string
* @throws NullPointerException if <tt>query</tt> is
<tt>null</tt>
*/
public String longestPrefixOf(String query) {
int length = longestPrefixOf(root, query, 0, -1);

if (length == -1) return null;


return query.substring(0, length);
}
// returns the length of the longest string key in the
subtrie
// rooted at x that is a prefix of the query string,
// assuming the first d character match and we have
already
// found a prefix match of length length
private int longestPrefixOf(Node x, String query, int d,
int length) {
if (x == null) return length;
if (x.isString) length = d;
if (d == query.length()) return length;
char c = query.charAt(d);
return longestPrefixOf(x.next[c], query, d+1,
length);
}
/**
* Removes the key from the set if the key is present.
* @param key the key
* @throws NullPointerException if <tt>key</tt> is
<tt>null</tt>
*/
public void delete(String key) {
root = delete(root, key, 0);
}
private Node delete(Node x, String key, int d) {
if (x == null) return null;
if (d == key.length()) {
if (x.isString) N--;
x.isString = false;
}
else {
char c = key.charAt(d);
x.next[c] = delete(x.next[c], key, d+1);
}
// remove subtrie rooted at x if it is completely
empty
if (x.isString) return x;
for (int c = 0; c < R; c++)
if (x.next[c] != null)
return x;

return null;
}
/**
* Unit tests the <tt>TrieSET</tt> data type.
*/
public static void main(String[] args) {
TrieSET set = new TrieSET();
while (!StdIn.isEmpty()) {
String key = StdIn.readString();
set.add(key);
}
// print results
if (set.size() < 100) {
StdOut.println("keys(\"\"):");
for (String key : set) {
StdOut.println(key);
}
StdOut.println();
}
StdOut.println("longestPrefixOf(\"shellsort\"):");
StdOut.println(set.longestPrefixOf("shellsort"));
StdOut.println();
StdOut.println("longestPrefixOf(\"xshellsort\"):");
StdOut.println(set.longestPrefixOf("xshellsort"));
StdOut.println();
StdOut.println("keysWithPrefix(\"shor\"):");
for (String s : set.keysWithPrefix("shor"))
StdOut.println(s);
StdOut.println();
StdOut.println("keysWithPrefix(\"shortening\"):");
for (String s : set.keysWithPrefix("shortening"))
StdOut.println(s);
StdOut.println();
StdOut.println("keysThatMatch(\".he.l.\"):");
for (String s : set.keysThatMatch(".he.l."))
StdOut.println(s);
}
}

Copyright 20022010, Robert Sedgewick and Kevin Wayne.


Last updated: Tue Jul 28 09:33:03 EDT 2015.
TST.java
Below is the syntax highlighted version
of TST.java from 5.2 Tries.
Here is the Javadoc.

/
***********************************************************
**************
* Compilation: javac TST.java
* Execution:
java TST < words.txt
* Dependencies: StdIn.java
*
* Symbol table with string keys, implemented using a
ternary search
* trie (TST).
*
*
* % java TST < shellsST.txt
* keys(""):
* by 4
* sea 6
* sells 1
* she 0
* shells 3
* shore 7
* the 5
*
* longestPrefixOf("shellsort"):
* shells
*
* keysWithPrefix("shor"):
* shore
*
* keysThatMatch(".he.l."):
* shells
*
* % java TST
* theory the now is the time for all good men
*
*
*

Remarks
-------- can't use a key that is the empty string ""

*
***********************************************************
**************/
/**
* The <tt>TST</tt> class represents an symbol table of
key-value
* pairs, with string keys and generic values.
* It supports the usual <em>put</em>, <em>get</em>,
<em>contains</em>,
* <em>delete</em>, <em>size</em>, and <em>is-empty</em>
methods.
* It also provides character-based methods for finding
the string
* in the symbol table that is the <em>longest prefix</em>
of a given prefix,
* finding all strings in the symbol table that <em>start
with</em> a given prefix,
* and finding all strings in the symbol table that
<em>match</em> a given pattern.
* A symbol table implements the <em>associative array</em>
abstraction:
* when associating a value with a key that is already in
the symbol table,
* the convention is to replace the old value with the new
value.
* Unlike {@link java.util.Map}, this class uses the
convention that
* values cannot be <tt>null</tt>&mdash;setting the
* value associated with a key to <tt>null</tt> is
equivalent to deleting the key
* from the symbol table.
* <p>
* This implementation uses a ternary search trie.
* <p>
* For additional documentation, see <a
href="http://algs4.cs.princeton.edu/52trie">Section 5.2</a>
of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*/
public class TST<Value> {
private int N;
// size
private Node<Value> root;
// root of TST
private static class Node<Value> {

private char c;
private Node<Value> left, mid, right;
middle, and right subtries
private Value val;
associated with string
}

// character
// left,
// value

/**
* Initializes an empty string symbol table.
*/
public TST() {
}
/**
* Returns
table.
* @return
table
*/
public int
return
}

the number of key-value pairs in this symbol


the number of key-value pairs in this symbol
size() {
N;

/**
* Does this symbol table contain the given key?
* @param key the key
* @return <tt>true</tt> if this symbol table contains
<tt>key</tt> and
*
<tt>false</tt> otherwise
* @throws NullPointerException if <tt>key</tt> is
<tt>null</tt>
*/
public boolean contains(String key) {
return get(key) != null;
}
/**
* Returns the value associated
* @param key the key
* @return the value associated
the key is in the symbol table
*
and <tt>null</tt> if the
symbol table
* @throws NullPointerException
<tt>null</tt>
*/
public Value get(String key) {

with the given key.


with the given key if
key is not in the
if <tt>key</tt> is

if (key == null) throw new NullPointerException();


if (key.length() == 0) throw new
IllegalArgumentException("key must have length >= 1");
Node<Value> x = get(root, key, 0);
if (x == null) return null;
return x.val;
}
// return subtrie corresponding to given key
private Node<Value> get(Node<Value> x, String key, int
d) {
if (key == null) throw new NullPointerException();
if (key.length() == 0) throw new
IllegalArgumentException("key must have length >= 1");
if (x == null) return null;
char c = key.charAt(d);
if
(c < x.c)
return get(x.left,
key, d);
else if (c > x.c)
return get(x.right,
key, d);
else if (d < key.length() - 1) return get(x.mid,
key, d+1);
else
return x;
}
/**
* Inserts the key-value pair into the symbol table,
overwriting the old value
* with the new value if the key is already in the
symbol table.
* If the value is <tt>null</tt>, this effectively
deletes the key from the symbol table.
* @param key the key
* @param val the value
* @throws NullPointerException if <tt>key</tt> is
<tt>null</tt>
*/
public void put(String key, Value val) {
if (!contains(key)) N++;
root = put(root, key, val, 0);
}
private Node<Value> put(Node<Value> x, String key, Value
val, int d) {
char c = key.charAt(d);
if (x == null) {
x = new Node<Value>();

x.c = c;
}
if
(c < x.c)
put(x.left, key, val, d);
else if (c > x.c)
put(x.right, key, val, d);
else if (d < key.length() - 1)
key, val, d+1);
else
return x;
}

x.left

x.right =
x.mid

= put(x.mid,

x.val

= val;

/**
* Returns the string in the symbol table that is the
longest prefix of <tt>query</tt>,
* or <tt>null</tt>, if no such string.
* @param query the query string
* @return the string in the symbol table that is the
longest prefix of <tt>query</tt>,
*
or <tt>null</tt> if no such string
* @throws NullPointerException if <tt>query</tt> is
<tt>null</tt>
*/
public String longestPrefixOf(String query) {
if (query == null || query.length() == 0) return
null;
int length = 0;
Node<Value> x = root;
int i = 0;
while (x != null && i < query.length()) {
char c = query.charAt(i);
if
(c < x.c) x = x.left;
else if (c > x.c) x = x.right;
else {
i++;
if (x.val != null) length = i;
x = x.mid;
}
}
return query.substring(0, length);
}
/**
* Returns all keys in the symbol table as an
<tt>Iterable</tt>.
* To iterate over all of the keys in the symbol table
named <tt>st</tt>,

* use the foreach notation: <tt>for (Key key :


st.keys())</tt>.
* @return all keys in the sybol table as an
<tt>Iterable</tt>
*/
public Iterable<String> keys() {
Queue<String> queue = new Queue<String>();
collect(root, new StringBuilder(), queue);
return queue;
}
/**
* Returns all of the keys in the set that start with
<tt>prefix</tt>.
* @param prefix the prefix
* @return all of the keys in the set that start with
<tt>prefix</tt>,
*
as an iterable
*/
public Iterable<String> keysWithPrefix(String prefix) {
Queue<String> queue = new Queue<String>();
Node<Value> x = get(root, prefix, 0);
if (x == null) return queue;
if (x.val != null) queue.enqueue(prefix);
collect(x.mid, new StringBuilder(prefix), queue);
return queue;
}
// all keys in subtrie rooted at x with given prefix
private void collect(Node<Value> x, StringBuilder
prefix, Queue<String> queue) {
if (x == null) return;
collect(x.left, prefix, queue);
if (x.val != null) queue.enqueue(prefix.toString() +
x.c);
collect(x.mid,
prefix.append(x.c), queue);
prefix.deleteCharAt(prefix.length() - 1);
collect(x.right, prefix, queue);
}
/**
* Returns all of the keys in the symbol table that
match <tt>pattern</tt>,
* where . symbol is treated as a wildcard character.
* @param pattern the pattern

* @return all of the keys in the symbol table that


match <tt>pattern</tt>,
*
as an iterable, where . is treated as a wildcard
character.
*/
public Iterable<String> keysThatMatch(String pattern) {
Queue<String> queue = new Queue<String>();
collect(root, new StringBuilder(), 0, pattern,
queue);
return queue;
}
private void collect(Node<Value> x, StringBuilder
prefix, int i, String pattern, Queue<String> queue) {
if (x == null) return;
char c = pattern.charAt(i);
if (c == '.' || c < x.c) collect(x.left, prefix, i,
pattern, queue);
if (c == '.' || c == x.c) {
if (i == pattern.length() - 1 && x.val != null)
queue.enqueue(prefix.toString() + x.c);
if (i < pattern.length() - 1) {
collect(x.mid, prefix.append(x.c), i+1,
pattern, queue);
prefix.deleteCharAt(prefix.length() - 1);
}
}
if (c == '.' || c > x.c) collect(x.right, prefix, i,
pattern, queue);
}
/**
* Unit tests the <tt>TST</tt> data type.
*/
public static void main(String[] args) {
// build symbol table from standard input
TST<Integer> st = new TST<Integer>();
for (int i = 0; !StdIn.isEmpty(); i++) {
String key = StdIn.readString();
st.put(key, i);
}
// print results
if (st.size() < 100) {
StdOut.println("keys(\"\"):");

for (String key : st.keys()) {


StdOut.println(key + " " + st.get(key));
}
StdOut.println();
}
StdOut.println("longestPrefixOf(\"shellsort\"):");
StdOut.println(st.longestPrefixOf("shellsort"));
StdOut.println();
StdOut.println("keysWithPrefix(\"shor\"):");
for (String s : st.keysWithPrefix("shor"))
StdOut.println(s);
StdOut.println();
StdOut.println("keysThatMatch(\".he.l.\"):");
for (String s : st.keysThatMatch(".he.l."))
StdOut.println(s);
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Tue Jul 28 09:33:03 EDT 2015.
KMP.java
Below is the syntax highlighted version
of KMP.java from 5.3 Substring Search.
the Javadoc.

Here is

/
***********************************************************
****
* Compilation: javac KMP.java
* Execution:
java KMP pattern text
* Dependencies: StdOut.java
*
* Reads in two strings, the pattern and the input text,
and
* searches for the pattern in the input text using the
* KMP algorithm.
*
* % java KMP abracadabra
abacadabrabracabracadabrabrabracad

* text:
abacadabrabracabracadabrabrabracad
* pattern:
abracadabra
*
* % java KMP rab abacadabrabracabracadabrabrabracad
* text:
abacadabrabracabracadabrabrabracad
* pattern:
rab
*
* % java KMP bcara abacadabrabracabracadabrabrabracad
* text:
abacadabrabracabracadabrabrabracad
* pattern:
bcara
*
* % java KMP rabrabracad
abacadabrabracabracadabrabrabracad
* text:
abacadabrabracabracadabrabrabracad
* pattern:
rabrabracad
*
* % java KMP abacad abacadabrabracabracadabrabrabracad
* text:
abacadabrabracabracadabrabrabracad
* pattern: abacad
*
***********************************************************
****/
public class KMP {
private final int R;
private int[][] dfa;
private char[] pattern;
array for the pattern
private String pat;

// the radix
// the KMP automoton
// either the character
// or the pattern string

// create the DFA from a String


public KMP(String pat) {
this.R = 256;
this.pat = pat;
// build DFA from pattern
int M = pat.length();
dfa = new int[R][M];
dfa[pat.charAt(0)][0] = 1;
for (int X = 0, j = 1; j < M; j++) {
for (int c = 0; c < R; c++)
dfa[c][j] = dfa[c][X];
// Copy mismatch
cases.
dfa[pat.charAt(j)][j] = j+1;
case.

// Set match

X = dfa[pat.charAt(j)][X];
restart state.
}
}

// Update

// create the DFA from a character array over Rcharacter alphabet


public KMP(char[] pattern, int R) {
this.R = R;
this.pattern = new char[pattern.length];
for (int j = 0; j < pattern.length; j++)
this.pattern[j] = pattern[j];
// build DFA from pattern
int M = pattern.length;
dfa = new int[R][M];
dfa[pattern[0]][0] = 1;
for (int X = 0, j = 1; j < M; j++) {
for (int c = 0; c < R; c++)
dfa[c][j] = dfa[c][X];
// Copy mismatch
cases.
dfa[pattern[j]][j] = j+1;

// Set match

case.
X = dfa[pattern[j]][X];
restart state.
}
}

// Update

// return offset of first match; N if no match


public int search(String txt) {
// simulate operation of DFA on
int M = pat.length();
int N = txt.length();
int i, j;
for (i = 0, j = 0; i < N && j <
j = dfa[txt.charAt(i)][j];
}
if (j == M) return i - M;
//
return N;
//

text

M; i++) {
found
not found

}
// return offset of first match; N if no match
public int search(char[] text) {
// simulate operation of DFA on text

int
int
int
for

M = pattern.length;
N = text.length;
i, j;
(i = 0, j = 0; i < N && j < M; i++) {
j = dfa[text[i]][j];

}
if (j == M) return i - M;
return N;

// found
// not found

}
// test client
public static void main(String[] args) {
String pat = args[0];
String txt = args[1];
char[] pattern = pat.toCharArray();
char[] text
= txt.toCharArray();
KMP kmp1 = new KMP(pat);
int offset1 = kmp1.search(txt);
KMP kmp2 = new KMP(pattern, 256);
int offset2 = kmp2.search(text);
// print results
StdOut.println("text:

" + txt);

StdOut.print("pattern: ");
for (int i = 0; i < offset1; i++)
StdOut.print(" ");
StdOut.println(pat);
StdOut.print("pattern: ");
for (int i = 0; i < offset2; i++)
StdOut.print(" ");
StdOut.println(pat);
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Tue Jul 28 09:33:03 EDT 2015.
BoyerMoore.java
Below is the syntax highlighted version

of BoyerMoore.java from 5.3 Substring Search.


the Javadoc.

Here is

/
***********************************************************
****
* Compilation: javac BoyerMoore.java
* Execution:
java BoyerMoore pattern text
* Dependencies: StdOut.java
*
* Reads in two strings, the pattern and the input text,
and
* searches for the pattern in the input text using the
* bad-character rule part of the Boyer-Moore algorithm.
* (does not implement the strong good suffix rule)
*
* % java BoyerMoore abracadabra
abacadabrabracabracadabrabrabracad
* text:
abacadabrabracabracadabrabrabracad
* pattern:
abracadabra
*
* % java BoyerMoore rab
abacadabrabracabracadabrabrabracad
* text:
abacadabrabracabracadabrabrabracad
* pattern:
rab
*
* % java BoyerMoore bcara
abacadabrabracabracadabrabrabracad
* text:
abacadabrabracabracadabrabrabracad
* pattern:
bcara
*
* % java BoyerMoore rabrabracad
abacadabrabracabracadabrabrabracad
* text:
abacadabrabracabracadabrabrabracad
* pattern:
rabrabracad
*
* % java BoyerMoore abacad
abacadabrabracabracadabrabrabracad
* text:
abacadabrabracabracadabrabrabracad
* pattern: abacad
*
***********************************************************
****/

public class BoyerMoore {


private final int R;
private int[] right;
array
private char[] pattern;
character array
private String pat;

// the radix
// the bad-character skip
// store the pattern as a
// or as a string

// pattern provided as a string


public BoyerMoore(String pat) {
this.R = 256;
this.pat = pat;
// position of rightmost occurrence of c in the
pattern
right = new int[R];
for (int c = 0; c < R; c++)
right[c] = -1;
for (int j = 0; j < pat.length(); j++)
right[pat.charAt(j)] = j;
}
// pattern provided as a character array
public BoyerMoore(char[] pattern, int R) {
this.R = R;
this.pattern = new char[pattern.length];
for (int j = 0; j < pattern.length; j++)
this.pattern[j] = pattern[j];
// position of rightmost occurrence of c in the
pattern
right = new int[R];
for (int c = 0; c < R; c++)
right[c] = -1;
for (int j = 0; j < pattern.length; j++)
right[pattern[j]] = j;
}
// return offset of first match; N if no match
public int search(String txt) {
int M = pat.length();
int N = txt.length();
int skip;
for (int i = 0; i <= N - M; i += skip) {
skip = 0;
for (int j = M-1; j >= 0; j--) {

if (pat.charAt(j) != txt.charAt(i+j)) {
skip = Math.max(1, j right[txt.charAt(i+j)]);
break;
}
}
if (skip == 0) return i;
// found
}
return N;
// not found
}
// return offset of first match; N if no match
public int search(char[] text) {
int M = pattern.length;
int N = text.length;
int skip;
for (int i = 0; i <= N - M; i += skip) {
skip = 0;
for (int j = M-1; j >= 0; j--) {
if (pattern[j] != text[i+j]) {
skip = Math.max(1, j right[text[i+j]]);
break;
}
}
if (skip == 0) return i;
// found
}
return N;
// not found
}

// test client
public static void main(String[] args) {
String pat = args[0];
String txt = args[1];
char[] pattern = pat.toCharArray();
char[] text
= txt.toCharArray();
BoyerMoore boyermoore1 = new BoyerMoore(pat);
BoyerMoore boyermoore2 = new BoyerMoore(pattern,
256);
int offset1 = boyermoore1.search(txt);
int offset2 = boyermoore2.search(text);
// print results

StdOut.println("text:

" + txt);

StdOut.print("pattern: ");
for (int i = 0; i < offset1; i++)
StdOut.print(" ");
StdOut.println(pat);
StdOut.print("pattern: ");
for (int i = 0; i < offset2; i++)
StdOut.print(" ");
StdOut.println(pat);
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Tue Jul 28 09:33:03 EDT 2015.
RabinKarp.java
Below is the syntax highlighted version
of RabinKarp.java from 5.3 Substring Search.
the Javadoc.

Here is

/
***********************************************************
****
* Compilation: javac RabinKarp.java
* Execution:
java RabinKarp pat txt
* Dependencies: StdOut.java
*
* Reads in two strings, the pattern and the input text,
and
* searches for the pattern in the input text using the
* Las Vegas version of the Rabin-Karp algorithm.
*
* % java RabinKarp abracadabra
abacadabrabracabracadabrabrabracad
* pattern: abracadabra
* text:
abacadabrabracabracadabrabrabracad
* match:
abracadabra
*
* % java RabinKarp rab abacadabrabracabracadabrabrabracad
* pattern: rab
* text:
abacadabrabracabracadabrabrabracad

* match:
rab
*
* % java RabinKarp bcara
abacadabrabracabracadabrabrabracad
* pattern: bcara
* text:
abacadabrabracabracadabrabrabracad
*
* % java RabinKarp rabrabracad
abacadabrabracabracadabrabrabracad
* text:
abacadabrabracabracadabrabrabracad
* pattern:
rabrabracad
*
* % java RabinKarp abacad
abacadabrabracabracadabrabrabracad
* text:
abacadabrabracabracadabrabrabracad
* pattern: abacad
*
***********************************************************
****/
import java.math.BigInteger;
import java.util.Random;
public class RabinKarp {
private String pat;
for Las Vegas
private long patHash;
private int M;
private long Q;
to avoid long overflow
private int R;
private long RM;

// the pattern

// needed only

// pattern hash value


// pattern length
// a large prime, small enough
// radix
// R^(M-1) % Q

public RabinKarp(int R, char[] pattern) {


throw new UnsupportedOperationException("Operation
not supported yet");
}
public RabinKarp(String pat) {
this.pat = pat;
// save pattern (needed only
for Las Vegas)
R = 256;
M = pat.length();
Q = longRandomPrime();

// precompute R^(M-1) % Q for use in removing


leading digit
RM = 1;
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++)
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;
return true;
}
// Monte Carlo version: always return true
private boolean check(int i) {
return true;
}
// check for exact match
public int search(String txt) {
int N = txt.length();
if (N < M) return N;
long txtHash = hash(txt, M);
// check for match at offset 0
if ((patHash == txtHash) && check(txt, 0))
return 0;
// 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;

// match
int offset = i - M + 1;
if ((patHash == txtHash) && check(txt, offset))
return offset;
}
// no match
return N;
}
// a random 31-bit prime
private static long longRandomPrime() {
BigInteger prime = BigInteger.probablePrime(31, new
Random());
return prime.longValue();
}
// test client
public static void main(String[] args) {
String pat = args[0];
String txt = args[1];
RabinKarp searcher = new RabinKarp(pat);
int offset = searcher.search(txt);
// print results
StdOut.println("text:

" + txt);

// from brute force search method 1


StdOut.print("pattern: ");
for (int i = 0; i < offset; i++)
StdOut.print(" ");
StdOut.println(pat);
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Tue Jul 28 09:33:03 EDT 2015.
NFA.java
Below is the syntax highlighted version
of NFA.java from 5.4 Regular Expressions.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac NFA.java
* Execution:
java NFA regexp text
* Dependencies: Stack.java Bag.java Digraph.java
DirectedDFS.java
*
* % java NFA "(A*B|AC)D" AAAABD
* true
*
* % java NFA "(A*B|AC)D" AAAAC
* false
*
* % java NFA "(a|(bc)*d)*" abcbcd
* true
*
* % java NFA "(a|(bc)*d)*" abcbcbcdaaaabcbcdaaaddd
* true
*
* Remarks
* ----------*
- This version does not suport the + operator or
multiway-or.
*
*
- This version does not handle character classes,
*
metacharacters (either in the text or pattern),
capturing
*
capabilities, greedy vs. relucantant modifier, and
*
other features in industrial-strength
implementations such
*
as java.util.regexp.
*
***********************************************************
**************/
public class NFA {
private Digraph G;
transitions
private String regexp;
private int M;
regular expression

// digraph of epsilon
// regular expression
// number of characters in

// Create the NFA for the given RE


public NFA(String regexp) {
this.regexp = regexp;
M = regexp.length();
Stack<Integer> ops = new Stack<Integer>();
G = new Digraph(M+1);
for (int i = 0; i < M; i++) {
int lp = i;
if (regexp.charAt(i) == '(' || regexp.charAt(i)
== '|')
ops.push(i);
else if (regexp.charAt(i) == ')') {
int or = ops.pop();
// 2-way or operator
if (regexp.charAt(or) == '|') {
lp = ops.pop();
G.addEdge(lp, or+1);
G.addEdge(or, i);
}
else if (regexp.charAt(or) == '(')
lp = or;
else assert false;
}
// closure operator (uses 1-character
lookahead)
if (i < M-1 && regexp.charAt(i+1) == '*') {
G.addEdge(lp, i+1);
G.addEdge(i+1, lp);
}
if (regexp.charAt(i) == '(' || regexp.charAt(i)
== '*' || regexp.charAt(i) == ')')
G.addEdge(i, i+1);
}
}
// Does the NFA recognize txt?
public boolean recognizes(String txt) {
DirectedDFS dfs = new DirectedDFS(G, 0);
Bag<Integer> pc = new Bag<Integer>();
for (int v = 0; v < G.V(); v++)
if (dfs.marked(v)) pc.add(v);
// Compute possible NFA states for txt[i+1]
for (int i = 0; i < txt.length(); i++) {
Bag<Integer> match = new Bag<Integer>();

for (int v : pc) {


if (v == M) continue;
if ((regexp.charAt(v) == txt.charAt(i)) ||
regexp.charAt(v) == '.')
match.add(v+1);
}
dfs = new DirectedDFS(G, match);
pc = new Bag<Integer>();
for (int v = 0; v < G.V(); v++)
if (dfs.marked(v)) pc.add(v);
// optimization if no states reachable
if (pc.size() == 0) return false;
}
// check for accept state
for (int v : pc)
if (v == M) return true;
return false;
}
public static void main(String[] args) {
String regexp = "(" + args[0] + ")";
String txt = args[1];
if (txt.indexOf('|') >= 0) {
throw new IllegalArgumentException("| character
in text is not supported");
}
NFA nfa = new NFA(regexp);
StdOut.println(nfa.recognizes(txt));
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Sun Dec 15 03:24:34 EST 2013.
GREP.java
Below is the syntax highlighted version
of GREP.java from 5.4 Regular Expressions.

/
***********************************************************
**************
* Compilation: javac GREP.java
* Execution:
java GREP regexp < input.txt
* Dependencies: NFA.java
* Data files:
http://algs4.cs.princeton.edu/54regexp/tinyL.txt
*
* 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.
*
* % more tinyL.txt
* AC
* AD
* AAA
* ABD
* ADD
* BCD
* ABCCBD
* BABAAA
* BABBAAA
*
* % java GREP "(A*B|AC)D" < tinyL.txt
* ABD
* ABCCBD
*
***********************************************************
**************/
public class GREP {
public static void main(String[] args) {
String regexp = "(.*" + args[0] + ".*)";
NFA nfa = new NFA(regexp);
while (StdIn.hasNextLine()) {
String txt = StdIn.readLine();
if (nfa.recognizes(txt)) {
StdOut.println(txt);
}
}
}
}

Copyright 20022010, Robert Sedgewick and Kevin Wayne.


Last updated: Wed Sep 14 12:38:07 EDT 2011.
BinaryDump.java
Below is the syntax highlighted version
of BinaryDump.java from 5.5 Data Compression.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac BinaryDump.java
* Execution:
java BinaryDump N < file
* Dependencies: BinaryStdIn.java
* Data file:
http://introcs.cs.princeton.edu/stdlib/abra.txt
*
* Reads in a binary file and writes out the bits, N per
line.
*
* % more abra.txt
* ABRACADABRA!
*
* % java BinaryDump 16 < abra.txt
* 0100000101000010
* 0101001001000001
* 0100001101000001
* 0100010001000001
* 0100001001010010
* 0100000100100001
* 96 bits
*
***********************************************************
**************/
public class BinaryDump {
public static void main(String[] args) {
int bitsPerLine = 16;
if (args.length == 1) {
bitsPerLine = Integer.parseInt(args[0]);
}

int count;
for (count = 0; !BinaryStdIn.isEmpty(); count++) {
if (bitsPerLine == 0) {
BinaryStdIn.readBoolean();
continue;
}
else if (count != 0 && count % bitsPerLine == 0)
StdOut.println();
if (BinaryStdIn.readBoolean()) StdOut.print(1);
else
StdOut.print(0);
}
if (bitsPerLine != 0) StdOut.println();
StdOut.println(count + " bits");
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Sun Jul 26 11:14:34 EDT 2015.
HexDump.java
Below is the syntax highlighted version
of HexDump.java from 5.5 Data Compression.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac HexDump.java
* Execution:
java HexDump < file
* Dependencies: BinaryStdIn.java StdOut.java
* Data file:
http://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
* ABRACADABRA!
*
* % java HexDump 16 < abra.txt
* 41 42 52 41 43 41 44 41 42 52 41 21
* 96 bits
*

*
* Remark
* -------------------------*
- Similar to the Unix utilities od (octal dump) or
hexdump (hexadecimal dump).
*
* % od -t x1 < abra.txt
* 0000000 41 42 52 41 43 41 44 41 42 52 41 21
* 0000014
*
***********************************************************
**************/
public class HexDump {
public static void main(String[] args) {
int bytesPerLine = 16;
if (args.length == 1) {
bytesPerLine = Integer.parseInt(args[0]);
}
int i;
for (i = 0; !BinaryStdIn.isEmpty(); i++) {
if (bytesPerLine == 0) {
BinaryStdIn.readChar();
continue;
}
if (i == 0) StdOut.printf("");
else if (i % bytesPerLine == 0)
StdOut.printf("\n", i);
else StdOut.print(" ");
char c = BinaryStdIn.readChar();
StdOut.printf("%02x", c & 0xff);
}
if (bytesPerLine != 0) StdOut.println();
StdOut.println((i*8) + " bits");
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Sun Jul 26 11:14:34 EDT 2015.
PictureDump.java
Below is the syntax highlighted version

of PictureDump.java from 5.5 Data Compression.


the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac PictureDump.java
* 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-byh picture,
* with the 1 bits in black and the 0 bits in white.
*
* % more abra.txt
* ABRACADABRA!
*
* % java PictureDump 16 6 < abra.txt
*
***********************************************************
**************/
import java.awt.Color;
public class PictureDump {
public static void main(String[] args) {
int width = Integer.parseInt(args[0]);
int height = Integer.parseInt(args[1]);
Picture pic = new Picture(width, height);
int count = 0;
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
pic.set(j, i, Color.RED);
if (!BinaryStdIn.isEmpty()) {
count++;
boolean bit = BinaryStdIn.readBoolean();
if (bit) pic.set(j, i, Color.BLACK);
else
pic.set(j, i, Color.WHITE);
}
}
}
pic.show();

StdOut.println(count + " bits");


}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Thu Oct 10 16:09:52 EDT 2013.
Genome.java
Below is the syntax highlighted version
of Genome.java from 5.5 Data Compression.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac Genome.java
* Execution:
java Genome - < input.txt
(compress)
* Execution:
java Genome + < input.txt
(expand)
* Dependencies: BinaryIn.java BinaryOut.java
*
* Compress or expand a genomic sequence using a 2-bit
code.
*
* % more genomeTiny.txt
* ATAGATGCATAGCGCATAGCTAGATGTGCTAGC
*
* % java Genome - < genomeTiny.txt | java Genome +
* ATAGATGCATAGCGCATAGCTAGATGTGCTAGC
*
***********************************************************
**************/
public class Genome {
private static final Alphabet DNA = new
Alphabet("ACGT");
public static void compress() {
String s = BinaryStdIn.readString();
int N = s.length();
BinaryStdOut.write(N);
// 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();
}
public static void expand() {
int N = BinaryStdIn.readInt();
// Read two bits; write char.
for (int i = 0; i < N; i++) {
char c = BinaryStdIn.readChar(2);
BinaryStdOut.write(DNA.toChar(c), 8);
}
BinaryStdOut.close();
}
public static void main(String[] args) {
if
(args[0].equals("-")) compress();
else if (args[0].equals("+")) expand();
else throw new IllegalArgumentException("Illegal
command line argument");
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Sun Jul 26 11:15:17 EDT 2015.
RunLength.java
Below is the syntax highlighted version
of RunLength.java from 5.5 Data Compression.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac RunLength.java
* Execution:
java RunLength - < input.txt
(compress)
* Execution:
java RunLength + < input.txt
(expand)
* Dependencies: BinaryIn.java BinaryOut.java
*

* Compress or expand binary input from standard input


using
* run-length encoding.
*
* % java BinaryDump 40 < 4runs.bin
* 0000000000000001111111000000011111111111
* 40 bits
*
* This has runs of 15 0s, 7 1s, 7 0s, and 11 1s.
*
* % java RunLength - < 4runs.bin | java HexDump
* 0f 07 07 0b
* 4 bytes
*
***********************************************************
**************/
public class RunLength {
private static final int R
= 256;
private static final int LG_R = 8;
public static void expand() {
boolean b = false;
while (!BinaryStdIn.isEmpty()) {
int run = BinaryStdIn.readInt(LG_R);
for (int i = 0; i < run; i++)
BinaryStdOut.write(b);
b = !b;
}
BinaryStdOut.close();
}
public static void compress() {
char run = 0;
boolean old = false;
while (!BinaryStdIn.isEmpty()) {
boolean b = BinaryStdIn.readBoolean();
if (b != old) {
BinaryStdOut.write(run, LG_R);
run = 1;
old = !old;
}
else {
if (run == R-1) {
BinaryStdOut.write(run, LG_R);
run = 0;

BinaryStdOut.write(run, LG_R);
}
run++;
}
}
BinaryStdOut.write(run, LG_R);
BinaryStdOut.close();
}
public static void main(String[] args) {
if
(args[0].equals("-")) compress();
else if (args[0].equals("+")) expand();
else throw new IllegalArgumentException("Illegal
command line argument");
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Tue Jul 28 09:42:58 EDT 2015.
Huffman.java
Below is the syntax highlighted version
of Huffman.java from 5.5 Data Compression.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac Huffman.java
* Execution:
java Huffman - < input.txt
(compress)
* Execution:
java Huffman + < input.txt
(expand)
* Dependencies: BinaryIn.java BinaryOut.java
* Data files:
http://algs4.cs.princeton.edu/55compression/abra.txt
*
http://algs4.cs.princeton.edu/55compression/tinytinyTale.txt
*
* Compress or expand a binary input stream using the
Huffman algorithm.
*
* % java Huffman - < abra.txt | java BinaryDump 60

*
01010000010010100010001001000011010000110101010010101000010
0
*
00000000000000000000000000011000111110010110100011111001010
0
* 120 bits
*
* % java Huffman - < abra.txt | java Huffman +
* ABRACADABRA!
*
***********************************************************
**************/
public class Huffman {
// alphabet size of extended ASCII
private static final int R = 256;
// Huffman trie node
private static class Node implements Comparable<Node> {
private final char ch;
private final int freq;
private final Node left, right;
Node(char ch, int freq, Node left, Node right) {
this.ch
= ch;
this.freq = freq;
this.left = left;
this.right = right;
}
// is the node a leaf node?
private boolean isLeaf() {
assert (left == null && right == null) || (left
!= null && right != null);
return (left == null && right == null);
}
// compare, based on frequency
public int compareTo(Node that) {
return this.freq - that.freq;
}
}

// compress bytes from standard input and write to


standard output
public static void compress() {
// read the input
String s = BinaryStdIn.readString();
char[] input = s.toCharArray();
// tabulate frequency counts
int[] freq = new int[R];
for (int i = 0; i < input.length; i++)
freq[input[i]]++;
// build Huffman trie
Node root = buildTrie(freq);
// build code table
String[] st = new String[R];
buildCode(st, root, "");
// print trie for decoder
writeTrie(root);
// print number of bytes in original uncompressed
message
BinaryStdOut.write(input.length);
// use Huffman code to encode input
for (int i = 0; i < input.length; i++) {
String code = st[input[i]];
for (int j = 0; j < code.length(); j++) {
if (code.charAt(j) == '0') {
BinaryStdOut.write(false);
}
else if (code.charAt(j) == '1') {
BinaryStdOut.write(true);
}
else throw new
IllegalStateException("Illegal state");
}
}
// close output stream
BinaryStdOut.close();
}
// build the Huffman trie given frequencies
private static Node buildTrie(int[] freq) {

// initialze priority queue with singleton trees


MinPQ<Node> pq = new MinPQ<Node>();
for (char i = 0; i < R; i++)
if (freq[i] > 0)
pq.insert(new Node(i, freq[i], null, null));
// special case in case there is only one character
with a nonzero frequency
if (pq.size() == 1) {
if (freq['\0'] == 0) pq.insert(new Node('\0', 0,
null, null));
else
pq.insert(new Node('\1', 0,
null, null));
}
// merge two smallest trees
while (pq.size() > 1) {
Node left = pq.delMin();
Node right = pq.delMin();
Node parent = new Node('\0', left.freq +
right.freq, left, right);
pq.insert(parent);
}
return pq.delMin();
}
// write bitstring-encoded trie to standard output
private static void writeTrie(Node x) {
if (x.isLeaf()) {
BinaryStdOut.write(true);
BinaryStdOut.write(x.ch, 8);
return;
}
BinaryStdOut.write(false);
writeTrie(x.left);
writeTrie(x.right);
}
// make a lookup table from symbols and their encodings
private static void buildCode(String[] st, Node x,
String s) {
if (!x.isLeaf()) {
buildCode(st, x.left, s + '0');
buildCode(st, x.right, s + '1');
}

else {
st[x.ch] = s;
}
}
// expand Huffman-encoded input from standard input and
write to standard output
public static void expand() {
// read in Huffman trie from input stream
Node root = readTrie();
// number of bytes to write
int length = BinaryStdIn.readInt();
// decode using the Huffman trie
for (int i = 0; i < length; i++) {
Node x = root;
while (!x.isLeaf()) {
boolean bit = BinaryStdIn.readBoolean();
if (bit) x = x.right;
else
x = x.left;
}
BinaryStdOut.write(x.ch, 8);
}
BinaryStdOut.close();
}
private static Node readTrie() {
boolean isLeaf = BinaryStdIn.readBoolean();
if (isLeaf) {
return new Node(BinaryStdIn.readChar(), -1,
null, null);
}
else {
return new Node('\0', -1, readTrie(),
readTrie());
}
}
public static void main(String[] args) {
if
(args[0].equals("-")) compress();
else if (args[0].equals("+")) expand();

else throw new IllegalArgumentException("Illegal


command line argument");
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Tue Jul 28 09:42:58 EDT 2015.
LZW.java
Below is the syntax highlighted version
of LZW.java from 5.5 Data Compression.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac LZW.java
* Execution:
java LZW - < input.txt
(compress)
* Execution:
java LZW + < input.txt
(expand)
* Dependencies: BinaryIn.java BinaryOut.java
*
* Compress or expand binary input from standard input
using LZW.
*
* WARNING: STARTING WITH ORACLE JAVA 6, UPDATE 7 the
SUBSTRING
* METHOD TAKES TIME AND SPACE LINEAR IN THE SIZE OF THE
EXTRACTED
* SUBSTRING (INSTEAD OF CONSTANT SPACE AND TIME AS IN
EARLIER
* IMPLEMENTATIONS).
*
* See <a href = "http://java-performance.info/changes-tostring-java-1-7-0_06/">this article</a>
* for more details.
*
***********************************************************
**************/
public class LZW {

private
input chars
private
codewords =
private
width

static final int R = 256;

// number of

static final int L = 4096;


2^W
static final int W = 12;

// number of
// codeword

public static void compress() {


String input = BinaryStdIn.readString();
TST<Integer> st = new TST<Integer>();
for (int i = 0; i < R; i++)
st.put("" + (char) i, i);
int code = R+1; // R is codeword for EOF
while (input.length() > 0) {
String s = st.longestPrefixOf(input); // Find
max prefix match s.
BinaryStdOut.write(st.get(s), W);
// Print
s's encoding.
int t = s.length();
if (t < input.length() && code < L)
// Add s
to symbol table.
st.put(input.substring(0, t + 1), code++);
input = input.substring(t);
// Scan
past s in input.
}
BinaryStdOut.write(R, W);
BinaryStdOut.close();
}
public static void expand() {
String[] st = new String[L];
int i; // next available codeword value
// initialize symbol table with all 1-character
strings
for (i = 0; i < R; i++)
st[i] = "" + (char) i;
st[i++] = "";
lookahead for EOF

// (unused)

int codeword = BinaryStdIn.readInt(W);


if (codeword == R) return;
// expanded
message is empty string
String val = st[codeword];

while (true) {
BinaryStdOut.write(val);
codeword = BinaryStdIn.readInt(W);
if (codeword == R) break;
String s = st[codeword];
if (i == codeword) s = val + val.charAt(0);
// special case hack
if (i < L) st[i++] = val + s.charAt(0);
val = s;
}
BinaryStdOut.close();
}

public static void main(String[] args) {


if
(args[0].equals("-")) compress();
else if (args[0].equals("+")) expand();
else throw new IllegalArgumentException("Illegal
command line argument");
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Sun Aug 10 09:06:11 EDT 2014.
CollisionSystem.java
Below is the syntax highlighted version
of CollisionSystem.java from 6.1 Event-Driven Simulation.
Here is the Javadoc.

/
***********************************************************
**************
* Compilation: javac CollisionSystem.java
* Execution:
java CollisionSystem N
(N
random particles)
*
java CollisionSystem < input.txt
(from a file)
* Dependencies: StdDraw.java Particle.java MinPQ.java
*
* Creates N random particles and simulates their motion
according

*
*

to the laws of elastic collisions.

***********************************************************
**************/
import java.awt.Color;
public class CollisionSystem {
private MinPQ<Event> pq;
private double t = 0.0;
time
private double hz = 0.5;
events per clock tick
private Particle[] particles;
particles

// the priority queue


// simulation clock
// number of redraw
// the array of

// create a new collision system with the given set of


particles
public CollisionSystem(Particle[] particles) {
this.particles = particles.clone();
// defensive
copy
}
// updates priority queue with all new events for
particle a
private void predict(Particle a, double limit) {
if (a == null) return;
// particle-particle collisions
for (int i = 0; i < particles.length; i++) {
double dt = a.timeToHit(particles[i]);
if (t + dt <= limit)
pq.insert(new Event(t + dt, a,
particles[i]));
}
// particle-wall collisions
double dtX = a.timeToHitVerticalWall();
double dtY = a.timeToHitHorizontalWall();
if (t + dtX <= limit) pq.insert(new Event(t + dtX,
a, null));
if (t + dtY <= limit) pq.insert(new Event(t + dtY,
null, a));
}
// redraw all particles

private void redraw(double limit) {


StdDraw.clear();
for (int i = 0; i < particles.length; i++) {
particles[i].draw();
}
StdDraw.show(20);
if (t < limit) {
pq.insert(new Event(t + 1.0 / hz, null, null));
}
}

/**********************************************************
**********************
* Event based simulation for limit seconds.
***********************************************************
*********************/
public void simulate(double limit) {
// initialize PQ with collision events and redraw
event
pq = new MinPQ<Event>();
for (int i = 0; i < particles.length; i++) {
predict(particles[i], limit);
}
pq.insert(new Event(0, null, null));
//
redraw event
// the main event-driven simulation loop
while (!pq.isEmpty()) {
// get impending event, discard if invalidated
Event e = pq.delMin();
if (!e.isValid()) continue;
Particle a = e.a;
Particle b = e.b;
// physical collision, so update positions, and
then simulation clock
for (int i = 0; i < particles.length; i++)
particles[i].move(e.time - t);
t = e.time;
// process event

if
(a != null && b != null) a.bounceOff(b);
// particle-particle collision
else if (a != null && b == null)
a.bounceOffVerticalWall();
// particle-wall collision
else if (a == null && b != null)
b.bounceOffHorizontalWall(); // particle-wall collision
else if (a == null && b == null) redraw(limit);
// redraw event
// update the priority queue with new
collisions involving a or b
predict(a, limit);
predict(b, limit);
}
}

/**********************************************************
***************
* An event during a particle collision simulation.
Each event contains
* the time at which it will occur (assuming no
supervening actions)
* and the particles a and b involved.
*
*
- a and b both null:
redraw event
*
- a null, b not null:
collision with vertical
wall
*
- a not null, b null:
collision with
horizontal wall
*
- a and b both not null: binary collision
between a and b
*
***********************************************************
**************/
private static class Event implements Comparable<Event>
{
private final double time;
// time that
event is scheduled to occur
private final Particle a, b;
// particles
involved in event, possibly null
private final int countA, countB; // collision
counts at event creation

// create a new event to occur at time t involving


a and b
public Event(double t, Particle a, Particle b) {
this.time = t;
this.a
= a;
this.b
= b;
if (a != null) countA = a.count();
else
countA = -1;
if (b != null) countB = b.count();
else
countB = -1;
}
// compare times when two events will occur
public int compareTo(Event that) {
if
(this.time < that.time) return -1;
else if (this.time > that.time) return +1;
else
return 0;
}
// has any collision occurred between when event
was created and now?
public boolean isValid() {
if (a != null && a.count() != countA) return
false;
if (b != null && b.count() != countB) return
false;
return true;
}
}

/**********************************************************
**********************
* Sample client.
***********************************************************
*********************/
public static void main(String[] args) {
StdDraw.setCanvasSize(800, 800);
// remove the border
// StdDraw.setXscale(1.0/22.0, 21.0/22.0);
// StdDraw.setYscale(1.0/22.0, 21.0/22.0);
// turn on animation mode

StdDraw.show(0);
// the array of particles
Particle[] particles;
// create N random particles
if (args.length == 1) {
int N = Integer.parseInt(args[0]);
particles = new Particle[N];
for (int i = 0; i < N; i++)
particles[i] = new Particle();
}
// or read from standard input
else {
int N = StdIn.readInt();
particles = new Particle[N];
for (int i = 0; i < N; i++) {
double rx
= StdIn.readDouble();
double ry
= StdIn.readDouble();
double vx
= StdIn.readDouble();
double vy
= StdIn.readDouble();
double radius = StdIn.readDouble();
double mass
= StdIn.readDouble();
int r
= StdIn.readInt();
int g
= StdIn.readInt();
int b
= StdIn.readInt();
Color color
= new Color(r, g, b);
particles[i] = new Particle(rx, ry, vx, vy,
radius, mass, color);
}
}
// create collision system and simulate
CollisionSystem system = new
CollisionSystem(particles);
system.simulate(10000);
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Tue Jul 28 11:23:22 EDT 2015.
Particle.java

Below is the syntax highlighted version


of Particle.java from 6.1 Event-Driven Simulation.
is the Javadoc.

Here

/**********************************************************
***************
* Compilation: javac Particle.java
* Execution:
none
* Dependencies: StdDraw.java
*
* A particle moving in the unit box with a given
position, velocity,
* radius, and mass.
*
***********************************************************
**************/
import java.awt.Color;
public class Particle {
private static final double INFINITY =
Double.POSITIVE_INFINITY;
private
private
private
private
private
private

double rx, ry;


double vx, vy;
double radius;
double mass;
Color color;
int count;

//
//
//
//
//
//

position
velocity
radius
mass
color
number of collisions so

far
// create a new particle with given parameters
public Particle(double rx, double ry, double vx, double
vy, double radius, double mass, Color color) {
this.vx = vx;
this.vy = vy;
this.rx = rx;
this.ry = ry;
this.radius = radius;
this.mass
= mass;
this.color = color;

}
// create a random particle in the unit box (overlaps
not checked)
public Particle() {
rx
= Math.random();
ry
= Math.random();
vx
= 0.01 * (Math.random() - 0.5);
vy
= 0.01 * (Math.random() - 0.5);
radius = 0.01;
mass
= 0.5;
color = Color.BLACK;
}
// updates position
public void move(double dt) {
rx += vx * dt;
ry += vy * dt;
}
// draw the particle
public void draw() {
StdDraw.setPenColor(color);
StdDraw.filledCircle(rx, ry, radius);
}
// return the number of collisions involving this
particle
public int count() {
return count;
}
// how long into future until collision between this
particle a and b?
public double timeToHit(Particle b) {
Particle a = this;
if (a == b) return INFINITY;
double dx = b.rx - a.rx;
double dy = b.ry - a.ry;
double dvx = b.vx - a.vx;
double dvy = b.vy - a.vy;
double dvdr = dx*dvx + dy*dvy;
if (dvdr > 0) return INFINITY;
double dvdv = dvx*dvx + dvy*dvy;
double drdr = dx*dx + dy*dy;
double sigma = a.radius + b.radius;

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;
}
// how long into future until this particle collides
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
return INFINITY;
}
// how long into future until this particle collides
with a horizontal wall?
public double timeToHitHorizontalWall() {
if
(vy > 0) return (1.0 - ry - radius) / vy;
else if (vy < 0) return (radius - ry) / vy;
else
return INFINITY;
}
// update velocities upon collision between this
particle and that particle
public void bounceOff(Particle that) {
double dx = that.rx - this.rx;
double dy = that.ry - this.ry;
double dvx = that.vx - this.vx;
double dvy = that.vy - this.vy;
double dvdr = dx*dvx + dy*dvy;
// dv
dot dr
double dist = this.radius + that.radius;
//
distance between particle centers at collison
// normal force F, and in x and y directions
double F = 2 * this.mass * that.mass * dvdr /
((this.mass + that.mass) * dist);
double fx = F * dx / dist;
double fy = F * dy / dist;
// update velocities according to normal force
this.vx += fx / this.mass;
this.vy += fy / this.mass;
that.vx -= fx / that.mass;
that.vy -= fy / that.mass;

// update collision counts


this.count++;
that.count++;
}
// update velocity of this particle upon collision with
a vertical wall
public void bounceOffVerticalWall() {
vx = -vx;
count++;
}
// update velocity of this particle upon collision with
a horizontal wall
public void bounceOffHorizontalWall() {
vy = -vy;
count++;
}
// return kinetic energy associated with this particle
public double kineticEnergy() {
return 0.5 * mass * (vx*vx + vy*vy);
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Tue Jul 28 11:23:22 EDT 2015.
BTree.java
Below is the syntax highlighted version
of BTree.java from 6.2 B-trees.
Here is the Javadoc.

/
***********************************************************
**************
* Compilation: javac BTree.java
* Execution:
java BTree
* Dependencies: StdOut.java
*
* B-tree.
*
* Limitations

* ----------*
- Assumes M is even and M >= 4
*
- should b be an array of children or list (it would
help with
*
casting to make it a list)
*
***********************************************************
**************/
public class BTree<Key extends Comparable<Key>, Value> {
private static final int M = 4;
// max children per
B-tree node = M-1
private Node root;
private int HT;
private int N;
pairs in the B-tree

// root of the B-tree


// height of the B-tree
// number of key-value

// helper B-tree node data type


private static final class Node {
private int m;
number of children
private Entry[] children = new Entry[M];
array of children

//
// the

// create a node with k children


private Node(int k) {
m = k;
}
}
// internal nodes: only use key and next
// external nodes: only use key and value
private static class Entry {
private Comparable key;
private Object value;
private Node next;
// helper field to iterate
over array entries
public Entry(Comparable key, Object value, Node
next) {
this.key
= key;
this.value = value;
this.next = next;
}
}

// constructor
public BTree() {
root = new Node(0);
}
// return number of key-value pairs in the B-tree
public int size() { return N; }
// return height of B-tree
public int height() { return HT; }
// search for given key, return associated value;
return null if no such key
public Value get(Key key) { return search(root, key,
HT); }
private Value search(Node x, Key key, int ht) {
Entry[] children = x.children;
// external node
if (ht == 0) {
for (int j = 0; j < x.m; j++) {
if (eq(key, children[j].key)) return (Value)
children[j].value;
}
}
// internal node
else {
for (int j = 0; j < x.m; j++) {
if (j+1 == x.m || less(key,
children[j+1].key))
return search(children[j].next, key, ht1);
}
}
return null;
}
// insert key-value pair
// add code to check for duplicate keys
public void put(Key key, Value value) {
Node u = insert(root, key, value, HT);
N++;
if (u == null) return;

// need to split root


Node t = new Node(2);
t.children[0] = new Entry(root.children[0].key,
null, root);
t.children[1] = new Entry(u.children[0].key, null,
u);
root = t;
HT++;
}
private Node insert(Node h, Key key, Value value, int
ht) {
int j;
Entry t = new Entry(key, value, null);
// external node
if (ht == 0) {
for (j = 0; j < h.m; j++) {
if (less(key, h.children[j].key)) break;
}
}
// internal node
else {
for (j = 0; j < h.m; j++) {
if ((j+1 == h.m) || less(key,
h.children[j+1].key)) {
Node u = insert(h.children[j++].next,
key, value, ht-1);
if (u == null) return null;
t.key = u.children[0].key;
t.next = u;
break;
}
}
}
for (int i = h.m; i
h.children[i] =
h.children[j] = t;
h.m++;
if (h.m < M) return
else
return
}

> j; i--)
h.children[i-1];
null;
split(h);

// split node in half


private Node split(Node h) {
Node t = new Node(M/2);
h.m = M/2;
for (int j = 0; j < M/2; j++)
t.children[j] = h.children[M/2+j];
return t;
}
// for debugging
public String toString() {
return toString(root, HT, "") + "\n";
}
private String toString(Node h, int ht, String indent) {
StringBuilder s = new StringBuilder();
Entry[] children = h.children;
if (ht == 0) {
for (int j = 0; j < h.m; j++) {
s.append(indent + children[j].key + " " +
children[j].value + "\n");
}
}
else {
for (int j = 0; j < h.m; j++) {
if (j > 0) s.append(indent + "(" +
children[j].key + ")\n");
s.append(toString(children[j].next, ht-1,
indent + "
"));
}
}
return s.toString();
}
// comparison functions - make Comparable instead of
Key to avoid casts
private boolean less(Comparable k1, Comparable k2) {
return k1.compareTo(k2) < 0;
}
private boolean eq(Comparable k1, Comparable k2) {
return k1.compareTo(k2) == 0;
}

/**********************************************************
***************
* Test client.
***********************************************************
**************/
public static void main(String[] args) {
BTree<String, String> st = new BTree<String,
String>();
//

st.put("www.cs.princeton.edu",
st.put("www.cs.princeton.edu",
st.put("www.princeton.edu",
st.put("www.yale.edu",
st.put("www.simpsons.com",
st.put("www.apple.com",
st.put("www.amazon.com",
st.put("www.ebay.com",
st.put("www.cnn.com",
st.put("www.google.com",
st.put("www.nytimes.com",
st.put("www.microsoft.com",
st.put("www.dell.com",
st.put("www.slashdot.org",
st.put("www.espn.com",
st.put("www.weather.com",
st.put("www.yahoo.com",

"128.112.136.12");
"128.112.136.11");
"128.112.128.15");
"130.132.143.21");
"209.052.165.60");
"17.112.152.32");
"207.171.182.16");
"66.135.192.87");
"64.236.16.20");
"216.239.41.99");
"199.239.136.200");
"207.126.99.140");
"143.166.224.230");
"66.35.250.151");
"199.181.135.201");
"63.111.66.11");
"216.109.118.65");

StdOut.println("cs.princeton.edu:
st.get("www.cs.princeton.edu"));
StdOut.println("hardvardsucks.com:
st.get("www.harvardsucks.com"));
StdOut.println("simpsons.com:
st.get("www.simpsons.com"));
StdOut.println("apple.com:
st.get("www.apple.com"));
StdOut.println("ebay.com:
st.get("www.ebay.com"));
StdOut.println("dell.com:
st.get("www.dell.com"));
StdOut.println();
StdOut.println("size:
StdOut.println("height:
StdOut.println(st);

" +
" +
" +
" +
" +
" +

" + st.size());
" + st.height());

StdOut.println();
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Tue Jul 28 11:31:29 EDT 2015.
SuffixArray.java
Below is the syntax highlighted version
of SuffixArray.java from 6.3 Suffix Arrays.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac SuffixArray.java
* Execution:
java SuffixArray < input.txt
* Dependencies: StdIn.java StdOut.java
*
* A data type that computes the suffix array of a string.
*
*
% java SuffixArray < abra.txt
*
i ind lcp rnk select
*
--------------------------*
0 11
0 "!"
*
1 10
0
1 "A!"
*
2
7
1
2 "ABRA!"
*
3
0
4
3 "ABRACADABRA!"
*
4
3
1
4 "ACADABRA!"
*
5
5
1
5 "ADABRA!"
*
6
8
0
6 "BRA!"
*
7
1
3
7 "BRACADABRA!"
*
8
4
0
8 "CADABRA!"
*
9
6
0
9 "DABRA!"
*
10
9
0 10 "RA!"
*
11
2
2 11 "RACADABRA!"
*
* See SuffixArrayX.java for an optimized version that
uses 3-way
* radix quicksort and does not use the nested class
Suffix.
*

***********************************************************
**************/
import java.util.Arrays;
/**
* The <tt>SuffixArray</tt> class represents a suffix
array of a string of
* length <em>N</em>.
* It supports the <em>selecting</em> the <em>i</em>th
smallest suffix,
* getting the <em>index</em> of the <em>i</em>th smallest
suffix,
* computing the length of the <em>longest common
prefix</em> between the
* <em>i</em>th smallest suffix and the <em>i</em>-1st
smallest suffix,
* and determining the <em>rank</em> of a query string
(which is the number
* of suffixes strictly less than the query string).
* <p>
* This implementation uses a nested class <tt>Suffix</tt>
to represent
* a suffix of a string (using constant time and space)
and
* <tt>Arrays.sort()</tt> to sort the array of suffixes.
* For alternate implementations of the same API, see
* {@link SuffixArrayX}, which is faster in practice (uses
3-way radix quicksort)
* and uses less memory (does not create <tt>Suffix</tt>
objects).
* The <em>index</em> and <em>length</em> operations takes
constant time
* in the worst case. The <em>lcp</em> operation takes
time proportional to the
* length of the longest common prefix.
* The <em>select</em> operation takes time proportional
* to the length of the suffix and should be used
primarily for debugging.
* <p>
* For additional documentation, see <a
href="http://algs4.cs.princeton.edu/63suffix">Section
6.3</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*/

public class SuffixArray {


private Suffix[] suffixes;
/**
* Initializes a suffix array for the given
<tt>text</tt> string.
* @param text the input string
*/
public SuffixArray(String text) {
int N = text.length();
this.suffixes = new Suffix[N];
for (int i = 0; i < N; i++)
suffixes[i] = new Suffix(text, i);
Arrays.sort(suffixes);
}
private static class Suffix implements
Comparable<Suffix> {
private final String text;
private final int index;
private Suffix(String text, int index) {
this.text = text;
this.index = index;
}
private int length() {
return text.length() - index;
}
private char charAt(int i) {
return text.charAt(index + i);
}
public int compareTo(Suffix that) {
if (this == that) return 0; // optimization
int N = Math.min(this.length(), that.length());
for (int i = 0; i < N; i++) {
if (this.charAt(i) < that.charAt(i)) return
-1;
if (this.charAt(i) > that.charAt(i)) return
+1;
}
return this.length() - that.length();
}
public String toString() {
return text.substring(index);
}

}
/**
* Returns
* @return
*/
public int
return
}

the length of the input string.


the length of the input string
length() {
suffixes.length;

/**
* Returns the index into the original string of the
<em>i</em>th smallest suffix.
* That is, <tt>text.substring(sa.index(i))</tt> is the
<em>i</em>th smallest suffix.
* @param i an integer between 0 and <em>N</em>-1
* @return the index into the original string of the
<em>i</em>th smallest suffix
* @throws java.lang.IndexOutOfBoundsException unless 0
&le; <em>i</em> &lt; <Em>N</em>
*/
public int index(int i) {
if (i < 0 || i >= suffixes.length) throw new
IndexOutOfBoundsException();
return suffixes[i].index;
}
/**
* Returns the length of the longest common prefix of
the <em>i</em>th
* smallest suffix and the <em>i</em>-1st smallest
suffix.
* @param i an integer between 1 and <em>N</em>-1
* @return the length of the longest common prefix of
the <em>i</em>th
* smallest suffix and the <em>i</em>-1st smallest
suffix.
* @throws java.lang.IndexOutOfBoundsException unless 1
&le; <em>i</em> &lt; <em>N</em>
*/
public int lcp(int i) {
if (i < 1 || i >= suffixes.length) throw new
IndexOutOfBoundsException();
return lcp(suffixes[i], suffixes[i-1]);
}

// longest common prefix of s and t


private static int lcp(Suffix s, Suffix t) {
int N = Math.min(s.length(), t.length());
for (int i = 0; i < N; i++) {
if (s.charAt(i) != t.charAt(i)) return i;
}
return N;
}
/**
* Returns the <em>i</em>th smallest suffix as a
string.
* @param i the index
* @return the <em>i</em> smallest suffix as a string
* @throws java.lang.IndexOutOfBoundsException unless 0
&le; <em>i</em> &lt; <Em>N</em>
*/
public String select(int i) {
if (i < 0 || i >= suffixes.length) throw new
IndexOutOfBoundsException();
return suffixes[i].toString();
}
/**
* Returns the number of suffixes strictly less than
the <tt>query</tt> string.
* We note that <tt>rank(select(i))</tt> equals
<tt>i</tt> for each <tt>i</tt>
* between 0 and <em>N</em>-1.
* @param query the query string
* @return the number of suffixes strictly less than
<tt>query</tt>
*/
public int rank(String query) {
int lo = 0, hi = suffixes.length - 1;
while (lo <= hi) {
int mid = lo + (hi - lo) / 2;
int cmp = compare(query, suffixes[mid]);
if (cmp < 0) hi = mid - 1;
else if (cmp > 0) lo = mid + 1;
else return mid;
}
return lo;
}
// compare query string to suffix

private static int compare(String query, Suffix suffix)


{
int N = Math.min(query.length(), suffix.length());
for (int i = 0; i < N; i++) {
if (query.charAt(i) < suffix.charAt(i)) return
-1;
if (query.charAt(i) > suffix.charAt(i)) return
+1;
}
return query.length() - suffix.length();
}
/**
* Unit tests the <tt>SuffixArray</tt> data type.
*/
public static void main(String[] args) {
String s = StdIn.readAll().replaceAll("\\s+", "
").trim();
SuffixArray suffix = new SuffixArray(s);
// StdOut.println("rank(" + args[0] + ") = " +
suffix.rank(args[0]));
StdOut.println(" i ind lcp rnk select");
StdOut.println("---------------------------");
for (int i = 0; i < s.length(); i++) {
int index = suffix.index(i);
String ith = "\"" + s.substring(index,
Math.min(index + 50, s.length())) + "\"";
assert
s.substring(index).equals(suffix.select(i));
int rank = suffix.rank(s.substring(index));
if (i == 0) {
StdOut.printf("%3d %3d %3s %3d %s\n", i,
index, "-", rank, ith);
}
else {
int lcp = suffix.lcp(i);
StdOut.printf("%3d %3d %3d %3d %s\n", i,
index, lcp, rank, ith);
}
}
}
}

Copyright 20022010, Robert Sedgewick and Kevin Wayne.


Last updated: Tue Jul 28 11:38:17 EDT 2015.
SuffixArrayX.java
Below is the syntax highlighted version
of SuffixArrayX.java from 6.3 Suffix Arrays.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac SuffixArrayX.java
* Execution:
java SuffixArrayX < input.txt
* Dependencies: StdIn.java StdOut.java
*
* A data type that computes the suffix array of a string
using 3-way
* radix quicksort.
*
* % java SuffixArrayX < abra.txt
*
i ind lcp rnk select
* --------------------------*
0 11
0 !
*
1 10
0
1 A!
*
2
7
1
2 ABRA!
*
3
0
4
3 ABRACADABRA!
*
4
3
1
4 ACADABRA!
*
5
5
1
5 ADABRA!
*
6
8
0
6 BRA!
*
7
1
3
7 BRACADABRA!
*
8
4
0
8 CADABRA!
*
9
6
0
9 DABRA!
*
10
9
0 10 RA!
*
11
2
2 11 RACADABRA!
*
*
***********************************************************
**************/
/**
* The <tt>SuffixArrayX</tt> class represents a suffix
array of a string of
* length <em>N</em>.

* It supports the <em>selecting</em> the <em>i</em>th


smallest suffix,
* getting the <em>index</em> of the <em>i</em>th smallest
suffix,
* computing the length of the <em>longest common
prefix</em> between the
* <em>i</em>th smallest suffix and the <em>i</em>-1st
smallest suffix,
* and determining the <em>rank</em> of a query string
(which is the number
* of suffixes strictly less than the query string).
* <p>
* This implementation uses 3-way radix quicksort to sort
the array of suffixes.
* For a simpler (but less efficient) implementations of
the same API, see
* {@link SuffixArray}.
* The <em>index</em> and <em>length</em> operations takes
constant time
* in the worst case. The <em>lcp</em> operation takes
time proportional to the
* length of the longest common prefix.
* The <em>select</em> operation takes time proportional
* to the length of the suffix and should be used
primarily for debugging.
* <p>
* This implementation uses '\0' as a sentinel and assumes
that the charater
* '\0' does not appear in the text.
* <p>
* In practice, this algorithm runs very fast. However, in
the worst-case
* it can be very poor (e.g., a string consisting of N
copies of the same
* character. We do not shuffle the array of suffixes
before sorting because
* shuffling is relatively expensive and a pathologial
input for which
* the suffixes start out in a bad order (e.g., sorted) is
likely to be
* a bad input for this algorithm with or without the
shuffle.
* <p>
* For additional documentation, see <a
href="http://algs4.cs.princeton.edu/63suffix">Section
6.3</a> of

* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and


Kevin Wayne.
*/
public class SuffixArrayX {
private static final int CUTOFF = 5;
// cutoff to
insertion sort (any value between 0 and 12)
private final
private final
text.substring(j)
private final
text

char[] text;
int[] index;
// index[i] = j means
is ith largest suffix
int N;
// number of characters in

/**
* Initializes a suffix array for the given
<tt>text</tt> string.
* @param text the input string
*/
public SuffixArrayX(String text) {
N = text.length();
text = text + '\0';
this.text = text.toCharArray();
this.index = new int[N];
for (int i = 0; i < N; i++)
index[i] = i;
sort(0, N-1, 0);
}
// 3-way string quicksort lo..hi starting at dth
character
private void sort(int lo, int hi, int d) {
// cutoff to insertion sort for small subarrays
if (hi <= lo + CUTOFF) {
insertion(lo, hi, d);
return;
}
int lt = lo, gt = hi;
char v = text[index[lo] + d];
int i = lo + 1;
while (i <= gt) {
char t = text[index[i] + d];
if
(t < v) exch(lt++, i++);
else if (t > v) exch(i, gt--);
else
i++;

}
// a[lo..lt-1] < v = a[lt..gt] < a[gt+1..hi].
sort(lo, lt-1, d);
if (v > 0) sort(lt, gt, d+1);
sort(gt+1, hi, d);
}
// sort from a[lo] to a[hi], starting at the dth
character
private void insertion(int lo, int hi, int d) {
for (int i = lo; i <= hi; i++)
for (int j = i; j > lo && less(index[j],
index[j-1], d); j--)
exch(j, j-1);
}
// is text[i+d..N) < text[j+d..N) ?
private boolean less(int i, int j, int d) {
if (i == j) return false;
i = i + d;
j = j + d;
while (i < N && j < N) {
if (text[i] < text[j]) return true;
if (text[i] > text[j]) return false;
i++;
j++;
}
return i > j;
}
// exchange index[i] and index[j]
private void exch(int i, int j) {
int swap = index[i];
index[i] = index[j];
index[j] = swap;
}
/**
* Returns
* @return
*/
public int
return
}

the length of the input string.


the length of the input string
length() {
N;

/**
* Returns the index into the original string of the
<em>i</em>th smallest suffix.
* That is, <tt>text.substring(sa.index(i))</tt> is the
<em>i</em> smallest suffix.
* @param i an integer between 0 and <em>N</em>-1
* @return the index into the original string of the
<em>i</em>th smallest suffix
* @throws java.lang.IndexOutOfBoundsException unless 0
&le; <em>i</em> &lt; <Em>N</em>
*/
public int index(int i) {
if (i < 0 || i >= N) throw new
IndexOutOfBoundsException();
return index[i];
}
/**
* Returns the length of the longest common prefix of
the <em>i</em>th
* smallest suffix and the <em>i</em>-1st smallest
suffix.
* @param i an integer between 1 and <em>N</em>-1
* @return the length of the longest common prefix of
the <em>i</em>th
* smallest suffix and the <em>i</em>-1st smallest
suffix.
* @throws java.lang.IndexOutOfBoundsException unless 1
&le; <em>i</em> &lt; <em>N</em>
*/
public int lcp(int i) {
if (i < 1 || i >= N) throw new
IndexOutOfBoundsException();
return lcp(index[i], index[i-1]);
}
// longest common prefix of text[i..N) and text[j..N)
private int lcp(int i, int j) {
int length = 0;
while (i < N && j < N) {
if (text[i] != text[j]) return length;
i++;
j++;
length++;
}
return length;
}

/**
* Returns the <em>i</em>th smallest suffix as a
string.
* @param i the index
* @return the <em>i</em> smallest suffix as a string
* @throws java.lang.IndexOutOfBoundsException unless 0
&le; <em>i</em> &lt; <Em>N</em>
*/
public String select(int i) {
if (i < 0 || i >= N) throw new
IndexOutOfBoundsException();
return new String(text, index[i], N - index[i]);
}
/**
* Returns the number of suffixes strictly less than
the <tt>query</tt> string.
* We note that <tt>rank(select(i))</tt> equals
<tt>i</tt> for each <tt>i</tt>
* between 0 and <em>N</em>-1.
* @param query the query string
* @return the number of suffixes strictly less than
<tt>query</tt>
*/
public int rank(String query) {
int lo = 0, hi = N - 1;
while (lo <= hi) {
int mid = lo + (hi - lo) / 2;
int cmp = compare(query, index[mid]);
if
(cmp < 0) hi = mid - 1;
else if (cmp > 0) lo = mid + 1;
else return mid;
}
return lo;
}
// is query < text[i..N) ?
private int compare(String query, int i) {
int M = query.length();
int j = 0;
while (i < N && j < M) {
if (query.charAt(j) != text[i]) return
query.charAt(j) - text[i];
i++;
j++;

}
if (i < N) return -1;
if (j < M) return +1;
return 0;
}
/**
* Unit tests the <tt>SuffixArrayx</tt> data type.
*/
public static void main(String[] args) {
String s = StdIn.readAll().replaceAll("\n", "
").trim();
SuffixArrayX suffix1 = new SuffixArrayX(s);
SuffixArray suffix2 = new SuffixArray(s);
boolean check = true;
for (int i = 0; check && i < s.length(); i++) {
if (suffix1.index(i) != suffix2.index(i)) {
StdOut.println("suffix1(" + i + ") = " +
suffix1.index(i));
StdOut.println("suffix2(" + i + ") = " +
suffix2.index(i));
String ith = "\"" +
s.substring(suffix1.index(i), Math.min(suffix1.index(i) +
50, s.length())) + "\"";
String jth = "\"" +
s.substring(suffix2.index(i), Math.min(suffix2.index(i) +
50, s.length())) + "\"";
StdOut.println(ith);
StdOut.println(jth);
check = false;
}
}
StdOut.println(" i ind lcp rnk select");
StdOut.println("---------------------------");
for (int i = 0; i < s.length(); i++) {
int index = suffix2.index(i);
String ith = "\"" + s.substring(index,
Math.min(index + 50, s.length())) + "\"";
int rank = suffix2.rank(s.substring(index));
assert
s.substring(index).equals(suffix2.select(i));
if (i == 0) {
StdOut.printf("%3d %3d %3s %3d %s\n", i,
index, "-", rank, ith);

}
else {
// int lcp = suffix.lcp(suffix2.index(i),
suffix2.index(i-1));
int lcp = suffix2.lcp(i);
StdOut.printf("%3d %3d %3d %3d %s\n", i,
index, lcp, rank, ith);
}
}
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Tue Jul 28 11:31:29 EDT 2015.
LRS.java
Below is the syntax highlighted version
of LRS.java from 6.3 Suffix Arrays.

/
***********************************************************
**************
* Compilation: javac LRS.java
* Execution:
java LRS < file.txt
* Dependencies: StdIn.java SuffixArray.java
* Data files:
http://algs4.cs.princeton.edu/63suffix/tinyTale.txt
*
http://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
* repeated substring in that text using a suffix array.
*
* % java LRS < tinyTale.txt
* 'st of times it was the '
*
* % java LRS < mobydick.txt
* ',- Such a funny, sporty, gamy, jesty, joky, hoky-poky
lad, is the Ocean, oh! Th'

*
*
*
*
*
*
*
*
*

% java LRS
aaaaaaaaa
'aaaaaaaa'
% java LRS
abcdefg
''

***********************************************************
**************/
public class LRS {
public static void main(String[] args) {
String text = StdIn.readAll().replaceAll("\\s+", "
");
SuffixArray sa = new SuffixArray(text);
int N = sa.length();
String lrs = "";
for (int i = 1; i < N; i++) {
int length = sa.lcp(i);
if (length > lrs.length()) {
// lrs = sa.select(i).substring(0, length);
lrs = text.substring(sa.index(i),
sa.index(i) + length);
}
}
StdOut.println("'" + lrs + "'");
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Mon Aug 26 18:33:55 EDT 2013.
KWIK.java
Below is the syntax highlighted version
of KWIK.java from 6.3 Suffix Arrays.
Here is the Javadoc.

/
***********************************************************
**************
* Compilation: javac KWIK.java
* Execution:
java KWIK file.txt
* Dependencies: StdIn.java StdOut.java In.java
SuffixArray.java
* Data files:
http://algs4.cs.princeton.edu/63suffix/tale.txt
*
* Keyword-in-context search.
*
* % java KWIK tale.txt 15
* majesty
*
most gracious majesty king george th
* rnkeys and the majesty of the law fir
* on against the majesty of the people
* se them to his majestys chief secreta
* h lists of his majestys forces and of
*
* the worst
* w the best and the worst are known to y
* f them give me the worst first there th
* for in case of the worst is a friend in
* e roomdoor and the worst is over then a
* pect mr darnay the worst its the wisest
* is his brother the worst of a bad race
* ss in them for the worst of health for
*
you have seen the worst of her agitati
* cumwented into the worst of luck buuust
* n your brother the worst of the bad rac
*
full share in the worst of the day pla
* mes to himself the worst of the strife
* f times it was the worst of times it wa
* ould hope that the worst was over well
* urage business the worst will be over i
* clesiastics of the worst world worldly
*
***********************************************************
**************/
public class KWIK {
public static void main(String[] args) {
In in = new In(args[0]);
int context = Integer.parseInt(args[1]);

// read in text
String text = in.readAll().replaceAll("\\s+", " ");
int N = text.length();
// build suffix array
SuffixArray sa = new SuffixArray(text);
// find all occurrences of queries and give context
while (StdIn.hasNextLine()) {
String query = StdIn.readLine();
for (int i = sa.rank(query); i < N; i++) {
int from1 = sa.index(i);
int to1
= Math.min(N, from1 +
query.length());
if (!query.equals(text.substring(from1,
to1))) break;
int from2 = Math.max(0, sa.index(i) context);
int to2
= Math.min(N, sa.index(i) +
context + query.length());
StdOut.println(text.substring(from2, to2));
}
StdOut.println();
}
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Tue Jul 28 11:31:29 EDT 2015.
LongestCommonSubstring.java
Below is the syntax highlighted version
of LongestCommonSubstring.java from 6.3 Suffix Arrays.
Here is the Javadoc.

/
***********************************************************
**************
* Compilation: javac LongestCommonSubstring.java
* Execution:
java LongestCommonSubstring file1.txt
file2.txt
* Dependencies: SuffixArray.java StdOut.java In.java

*
* Reads in two text strings, replaces all consecutive
blocks of
* whitespace with a single space, and then computes the
longest
* common substring.
*
* Assumes that the character '\1' does not appear in
either text.
* Perhaps, search for a character that does not appear in
either text
* (and make sure SuffixArray.java doesn't choose the same
one).
*
* % java LongestCommonSubstring tale.txt mobydick.txt
* ' seemed on the point of being '
*
***********************************************************
**************/
public class LongestCommonSubstring {
public static void main(String[] args) {
// read in two string from two files
In in1 = new In(args[0]);
In in2 = new In(args[1]);
String text1 =
in1.readAll().trim().replaceAll("\\s+", " ");
String text2 =
in2.readAll().trim().replaceAll("\\s+", " ");
int N1 = text1.length();
// int N2 = text2.length();
// concatenate two string with intervening '\1'
String text = text1 + '\1' + text2;
int N = text.length();
// compute suffix array of concatenated text
SuffixArray suffix = new SuffixArray(text);
// search for longest common substring
String lcs = "";
for (int i = 1; i < N; i++) {

// adjacent suffixes both from first text


string
if (suffix.index(i) < N1 && suffix.index(i-1) <
N1) continue;
// adjacent suffixes both from secondt text
string
if (suffix.index(i) > N1 && suffix.index(i-1) >
N1) continue;
// check if adjacent suffixes longer common
substring
int length = suffix.lcp(i);
if (length > lcs.length()) {
lcs = text.substring(suffix.index(i),
suffix.index(i) + length);
}
}
// print out longest common substring
StdOut.println(lcs.length());
StdOut.println("'" + lcs + "'");
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Sat Sep 6 14:57:55 EDT 2014.
FordFulkerson.java
Below is the syntax highlighted version
of FordFulkerson.java from 6.4 Maxflow.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac FordFulkerson.java
* Execution:
java FordFulkerson V E
* Dependencies: FlowNetwork.java FlowEdge.java Queue.java
*
* Ford-Fulkerson algorithm for computing a max flow and
* a min cut using shortest augmenting path rule.
*

***********************************************************
**********/
/**
* The <tt>FordFulkerson</tt> class represents a data type
for computing a
* <em>maximum st-flow</em> and <em>minimum st-cut</em> in
a flow
* network.
* <p>
* This implementation uses the <em>Ford-Fulkerson</em>
algorithm with
* the <em>shortest augmenting path</em> heuristic.
* The constructor takes time proportional to <em>E V</em>
(<em>E</em> + <em>V</em>)
* in the worst case and extra space (not including the
network)
* proportional to <em>V</em>, where <em>V</em> is the
number of vertices
* and <em>E</em> is the number of edges. In practice, the
algorithm will
* run much faster.
* Afterwards, the <tt>inCut()</tt> and <tt>value()</tt>
methods take
* constant time.
* <p>
* 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.
* <p>
* For additional documentation, see <a
href="http://algs4.cs.princeton.edu/64maxflow">Section
6.4</a>
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class FordFulkerson {
private static final double FLOATING_POINT_EPSILON = 1E11;

private boolean[] marked;


s->v path in residual graph
private FlowEdge[] edgeTo;
on shortest residual s->v path
private double value;
flow

// marked[v] = true iff


// edgeTo[v] = last edge
// current value of max

/**
* Compute a maximum flow and minimum cut in the
network <tt>G</tt>
* from vertex <tt>s</tt> to vertex <tt>t</tt>.
* @param G the flow network
* @param s the source vertex
* @param t the sink vertex
* @throws IndexOutOfBoundsException unless 0 <= s < V
* @throws IndexOutOfBoundsException unless 0 <= t < V
* @throws IllegalArgumentException if s = t
* @throws IllegalArgumentException if initial flow is
infeasible
*/
public FordFulkerson(FlowNetwork G, int s, int t) {
validate(s, G.V());
validate(t, G.V());
if (s == t)
throw new
IllegalArgumentException("Source equals sink");
if (!isFeasible(G, s, t)) throw new
IllegalArgumentException("Initial flow is infeasible");
// while there exists an augmenting path, use it
value = excess(G, t);
while (hasAugmentingPath(G, s, t)) {
// compute bottleneck capacity
double bottle = Double.POSITIVE_INFINITY;
for (int v = t; v != s; v = edgeTo[v].other(v))
{
bottle = Math.min(bottle,
edgeTo[v].residualCapacityTo(v));
}
// augment flow
for (int v = t; v != s; v = edgeTo[v].other(v))
{
edgeTo[v].addResidualFlowTo(v, bottle);
}

value += bottle;
}
// check optimality conditions
assert check(G, s, t);
}
/**
* Returns the value of the maximum flow.
* @return the value of the maximum flow
*/
public double value() {
return value;
}
// is v in the s side of the min s-t cut?
/**
* Is vertex <tt>v</tt> on the <tt>s</tt> side of the
minimum st-cut?
* @return <tt>true</tt> if vertex <tt>v</tt> is on the
<tt>s</tt> side of the micut,
*
and <tt>false</tt> if vertex <tt>v</tt> is on the
<tt>t</tt> side.
* @throws IndexOutOfBoundsException unless 0 <= v < V
*/
public boolean inCut(int v) {
validate(v, marked.length);
return marked[v];
}
// throw an exception if v is outside prescibed range
private void validate(int v, int V) {
if (v < 0 || v >= V)
throw new IndexOutOfBoundsException("vertex " +
v + " is not between 0 and " + (V-1));
}
// 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
private boolean hasAugmentingPath(FlowNetwork G, int s,
int t) {
edgeTo = new FlowEdge[G.V()];

marked = new boolean[G.V()];


// breadth-first search
Queue<Integer> queue = new Queue<Integer>();
queue.enqueue(s);
marked[s] = true;
while (!queue.isEmpty() && !marked[t]) {
int v = queue.dequeue();
for (FlowEdge e : G.adj(v)) {
int w = e.other(v);
// if residual capacity from v to w
if (e.residualCapacityTo(w) > 0) {
if (!marked[w]) {
edgeTo[w] = e;
marked[w] = true;
queue.enqueue(w);
}
}
}
}
// is there an augmenting path?
return marked[t];
}

// return excess flow at vertex v


private double excess(FlowNetwork G, int v) {
double excess = 0.0;
for (FlowEdge e : G.adj(v)) {
if (v == e.from()) excess -= e.flow();
else
excess += e.flow();
}
return excess;
}
// return excess flow at vertex v
private boolean isFeasible(FlowNetwork G, int s, int t)
{
// check that capacity constraints are satisfied
for (int v = 0; v < G.V(); v++) {
for (FlowEdge e : G.adj(v)) {

if (e.flow() < -FLOATING_POINT_EPSILON ||


e.flow() > e.capacity() + FLOATING_POINT_EPSILON) {
System.err.println("Edge does not
satisfy capacity constraints: " + e);
return false;
}
}
}
// check that net flow into a vertex equals zero,
except at source and sink
if (Math.abs(value + excess(G, s)) >
FLOATING_POINT_EPSILON) {
System.err.println("Excess at source = " +
excess(G, s));
System.err.println("Max flow
= " +
value);
return false;
}
if (Math.abs(value - excess(G, t)) >
FLOATING_POINT_EPSILON) {
System.err.println("Excess at sink
= " +
excess(G, t));
System.err.println("Max flow
= " +
value);
return false;
}
for (int v = 0; v < G.V(); v++) {
if (v == s || v == t) continue;
else if (Math.abs(excess(G, v)) >
FLOATING_POINT_EPSILON) {
System.err.println("Net flow out of " + v +
" doesn't equal zero");
return false;
}
}
return true;
}

// check optimality conditions


private boolean check(FlowNetwork G, int s, int t) {
// check that flow is feasible
if (!isFeasible(G, s, t)) {
System.err.println("Flow is infeasible");

return false;
}
// check that s is on the source side of min cut
and that t is not on source side
if (!inCut(s)) {
System.err.println("source " + s + " is not on
source side of min cut");
return false;
}
if (inCut(t)) {
System.err.println("sink " + t + " is on source
side of min cut");
return false;
}
// check that value of min cut = value of max flow
double mincutValue = 0.0;
for (int v = 0; v < G.V(); v++) {
for (FlowEdge e : G.adj(v)) {
if ((v == e.from()) && inCut(e.from()) && !
inCut(e.to()))
mincutValue += e.capacity();
}
}
if (Math.abs(mincutValue - value) >
FLOATING_POINT_EPSILON) {
System.err.println("Max flow value = " + value +
", min cut value = " + mincutValue);
return false;
}
return true;
}
/**
* Unit tests the <tt>FordFulkerson</tt> data type.
*/
public static void main(String[] args) {
// create flow network with V vertices and E edges
int V = Integer.parseInt(args[0]);
int E = Integer.parseInt(args[1]);
int s = 0, t = V-1;
FlowNetwork G = new FlowNetwork(V, E);

StdOut.println(G);
// compute maximum flow and minimum cut
FordFulkerson maxflow = new FordFulkerson(G, s, t);
StdOut.println("Max flow from " + s + " to " + t);
for (int v = 0; v < G.V(); v++) {
for (FlowEdge e : G.adj(v)) {
if ((v == e.from()) && e.flow() > 0)
StdOut.println("
" + e);
}
}
// print min-cut
StdOut.print("Min cut: ");
for (int v = 0; v < G.V(); v++) {
if (maxflow.inCut(v)) StdOut.print(v + " ");
}
StdOut.println();
StdOut.println("Max flow value = " +
maxflow.value());
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Sun Jul 26 11:14:34 EDT 2015.
FlowNetwork.java
Below is the syntax highlighted version
of FlowNetwork.java from 6.4 Maxflow.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac FlowNetwork.java
* Execution:
java FlowNetwork V E
* Dependencies: Bag.java FlowEdge.java
*
* A capacitated flow network, implemented using adjacency
lists.
*

***********************************************************
**************/
/**
* The <tt>FlowNetwork</tt> class represents a capacitated
network
* with vertices named 0 through <em>V</em> - 1, where
each directed
* edge is of type {@link FlowEdge} and has a real-valued
capacity
* and flow.
* It supports the following two primary operations: add
an edge to the network,
* iterate over all of the edges incident to or from a
vertex. It also provides
* methods for returning the number of vertices <em>V</em>
and the number
* of edges <em>E</em>. Parallel edges and self-loops are
permitted.
* <p>
* 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.
* <p>
* For additional documentation,
* see <a
href="http://algs4.cs.princeton.edu/64maxflow">Section
6.4</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class FlowNetwork {
private static final String NEWLINE =
System.getProperty("line.separator");
private final int V;
private int E;

private Bag<FlowEdge>[] adj;


/**
* Initializes an empty flow network with <tt>V</tt>
vertices and 0 edges.
* param V the number of vertices
* @throws java.lang.IllegalArgumentException if
<tt>V</tt> < 0
*/
public FlowNetwork(int V) {
if (V < 0) throw new
IllegalArgumentException("Number of vertices in a Graph must
be nonnegative");
this.V = V;
this.E = 0;
adj = (Bag<FlowEdge>[]) new Bag[V];
for (int v = 0; v < V; v++)
adj[v] = new Bag<FlowEdge>();
}
/**
* Initializes a random flow network with <tt>V</tt>
vertices and <em>E</em> edges.
* The capacities are integers between 0 and 99 and the
flow values are zero.
* param V the number of vertices
* param E the number of edges
* @throws java.lang.IllegalArgumentException if
<tt>V</tt> < 0
* @throws java.lang.IllegalArgumentException if
<tt>E</tt> < 0
*/
public FlowNetwork(int V, int E) {
this(V);
if (E < 0) throw new
IllegalArgumentException("Number of edges must be
nonnegative");
for (int i = 0; i < E; i++) {
int v = StdRandom.uniform(V);
int w = StdRandom.uniform(V);
double capacity = StdRandom.uniform(100);
addEdge(new FlowEdge(v, w, capacity));
}
}
/**
* Initializes a flow network from an input stream.

* The format is the number of vertices <em>V</em>,


* followed by the number of edges <em>E</em>,
* followed by <em>E</em> pairs of vertices and edge
capacities,
* with each entry separated by whitespace.
* @param in the input stream
* @throws java.lang.IndexOutOfBoundsException if the
endpoints of any edge are not in prescribed range
* @throws java.lang.IllegalArgumentException if the
number of vertices or edges is negative
*/
public FlowNetwork(In in) {
this(in.readInt());
int E = in.readInt();
if (E < 0) throw new
IllegalArgumentException("Number of edges must be
nonnegative");
for (int i = 0; i < E; i++) {
int v = in.readInt();
int w = in.readInt();
if (v < 0 || v >= V) throw new
IndexOutOfBoundsException("vertex " + v + " is not between 0
and " + (V-1));
if (w < 0 || w >= V) throw new
IndexOutOfBoundsException("vertex " + w + " is not between 0
and " + (V-1));
double capacity = in.readDouble();
addEdge(new FlowEdge(v, w, capacity));
}
}
/**
* Returns
graph.
* @return
graph
*/
public int
return
}

the number of vertices in the edge-weighted


the number of vertices in the edge-weighted
V() {
V;

/**
* Returns the number of edges in the edge-weighted
graph.
* @return the number of edges in the edge-weighted
graph

*/
public int E() {
return E;
}
// throw an IndexOutOfBoundsException unless 0 <= v < V
private void validateVertex(int v) {
if (v < 0 || v >= V)
throw new IndexOutOfBoundsException("vertex " +
v + " is not between 0 and " + (V-1));
}
/**
* Adds the edge <tt>e</tt> to the network.
* @param e the edge
* @throws java.lang.IndexOutOfBoundsException unless
endpoints of edge are between 0 and V-1
*/
public void addEdge(FlowEdge e) {
int v = e.from();
int w = e.to();
validateVertex(v);
validateVertex(w);
adj[v].add(e);
adj[w].add(e);
E++;
}
/**
* Returns the edges incident on vertex <tt>v</tt>
(includes both edges pointing to
* and from <tt>v</tt>).
* @param v the vertex
* @return the edges incident on vertex <tt>v</tt> as
an Iterable
* @throws java.lang.IndexOutOfBoundsException unless 0
<= v < V
*/
public Iterable<FlowEdge> adj(int v) {
validateVertex(v);
return adj[v];
}
// return list of all edges - excludes self loops
public Iterable<FlowEdge> edges() {
Bag<FlowEdge> list = new Bag<FlowEdge>();
for (int v = 0; v < V; v++)

for (FlowEdge e : adj(v)) {


if (e.to() != v)
list.add(e);
}
return list;
}
/**
* Returns a string representation of the flow network.
* This method takes time proportional to <em>E</em> +
<em>V</em>.
* @return the number of vertices <em>V</em>, followed
by the number of edges <em>E</em>,
*
followed by the <em>V</em> adjacency lists
*/
public String toString() {
StringBuilder s = new StringBuilder();
s.append(V + " " + E + NEWLINE);
for (int v = 0; v < V; v++) {
s.append(v + ": ");
for (FlowEdge e : adj[v]) {
if (e.to() != v) s.append(e + " ");
}
s.append(NEWLINE);
}
return s.toString();
}
/**
* Unit tests the <tt>FlowNetwork</tt> data type.
*/
public static void main(String[] args) {
In in = new In(args[0]);
FlowNetwork G = new FlowNetwork(in);
StdOut.println(G);
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Tue Jul 28 10:06:44 EDT 2015.
FlowEdge.java

Below is the syntax highlighted version


of FlowEdge.java from 6.4 Maxflow.
Here is the Javadoc.

/
***********************************************************
**************
* Compilation: javac FlowEdge.java
* Execution:
java FlowEdge
* Dependencies: StdOut.java
*
* Capacitated edge with a flow in a flow network.
*
***********************************************************
**************/
/**
* The <tt>FlowEdge</tt> 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
* of the directed edge and the weight. It also provides
methods for
* changing the amount of flow on the edge and determining
the residual
* capacity of the edge.
* <p>
* For additional documentation, see <a
href="http://algs4.cs.princeton.edu/64maxflow">Section
6.4</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class FlowEdge {
private final int v;
// from
private final int w;
// to
private final double capacity;
// capacity

private double flow;

// flow

/**
* Initializes an edge from vertex <tt>v</tt> to vertex
<tt>w</tt> with
* the given <tt>capacity</tt> and zero flow.
* @param v the tail vertex
* @param w the head vertex
* @param capacity the capacity of the edge
* @throws java.lang.IndexOutOfBoundsException if
either <tt>v</tt> or <tt>w</tt>
*
is a negative integer
* @throws java.lang.IllegalArgumentException if
<tt>capacity</tt> is negative
*/
public FlowEdge(int v, int w, double capacity) {
if (v < 0) throw new
IndexOutOfBoundsException("Vertex name must be a nonnegative
integer");
if (w < 0) throw new
IndexOutOfBoundsException("Vertex name must be a nonnegative
integer");
if (!(capacity >= 0.0)) throw new
IllegalArgumentException("Edge capacity must be
nonnegaitve");
this.v
= v;
this.w
= w;
this.capacity = capacity;
this.flow
= 0.0;
}
/**
* Initializes an edge from vertex <tt>v</tt> to vertex
<tt>w</tt> with
* the given <tt>capacity</tt> and <tt>flow</tt>.
* @param v the tail vertex
* @param w the head vertex
* @param capacity the capacity of the edge
* @param flow the flow on the edge
* @throws java.lang.IndexOutOfBoundsException if
either <tt>v</tt> or <tt>w</tt>
*
is a negative integer
* @throws java.lang.IllegalArgumentException if
<tt>capacity</tt> is negative
* @throws java.lang.IllegalArgumentException unless
<tt>flow</tt> is between
*
<tt>0.0</tt> and <tt>capacity</tt>.

*/
public FlowEdge(int v, int w, double capacity, double
flow) {
if (v < 0) throw new
IndexOutOfBoundsException("Vertex name must be a nonnegative
integer");
if (w < 0) throw new
IndexOutOfBoundsException("Vertex name must be a nonnegative
integer");
if (!(capacity >= 0.0)) throw new
IllegalArgumentException("Edge capacity must be
nonnegaitve");
if (!(flow <= capacity)) throw new
IllegalArgumentException("Flow exceeds capacity");
if (!(flow >= 0.0))
throw new
IllegalArgumentException("Flow must be nonnnegative");
this.v
= v;
this.w
= w;
this.capacity = capacity;
this.flow
= flow;
}
/**
* Initializes a flow edge from another flow edge.
* @param e the edge to copy
*/
public FlowEdge(FlowEdge e) {
this.v
= e.v;
this.w
= e.w;
this.capacity = e.capacity;
this.flow
= e.flow;
}
/**
* Returns
* @return
*/
public int
return
}
/**
* Returns
* @return
*/
public int
return

the tail vertex of the edge.


the tail vertex of the edge
from() {
v;

the head vertex of the edge.


the head vertex of the edge
to() {
w;

}
/**
* Returns the capacity of the edge.
* @return the capacity of the edge
*/
public double capacity() {
return capacity;
}
/**
* Returns the flow on the edge.
* @return the flow on the edge
*/
public double flow() {
return flow;
}
/**
* Returns the endpoint of the edge that is different
from the given vertex
* (unless the edge represents a self-loop in which
case it returns the same vertex).
* @param vertex one endpoint of the edge
* @return the endpoint of the edge that is different
from the given vertex
*
(unless the edge represents a self-loop in which
case it returns the same vertex)
* @throws java.lang.IllegalArgumentException if
<tt>vertex</tt> is not one of the endpoints
*
of the edge
*/
public int other(int vertex) {
if
(vertex == v) return w;
else if (vertex == w) return v;
else throw new IllegalArgumentException("Illegal
endpoint");
}
/**
* Returns the residual capacity of the edge in the
direction
* to the given <tt>vertex</tt>.
* @param vertex one endpoint of the edge
* @return the residual capacity of the edge in the
direction to the given vertex

*
If <tt>vertex</tt> is the tail vertex, the
residual capacity equals
*
<tt>capacity() - flow()</tt>; if <tt>vertex</tt>
is the head vertex, the
*
residual capacity equals <tt>flow()</tt>.
* @throws java.lang.IllegalArgumentException if
<tt>vertex</tt> is not one of the endpoints
*
of the edge
*/
public double residualCapacityTo(int vertex) {
if
(vertex == v) return flow;
//
backward edge
else if (vertex == w) return capacity - flow;
//
forward edge
else throw new IllegalArgumentException("Illegal
endpoint");
}
/**
* Increases the flow on the edge in the direction to
the given vertex.
*
If <tt>vertex</tt> is the tail vertex, this
increases the flow on the edge by <tt>delta</tt>;
*
if <tt>vertex</tt> is the head vertex, this
decreases the flow on the edge by <tt>delta</tt>.
* @param vertex one endpoint of the edge
* @throws java.lang.IllegalArgumentException if
<tt>vertex</tt> is not one of the endpoints
*
of the edge
* @throws java.lang.IllegalArgumentException if
<tt>delta</tt> makes the flow on
*
on the edge either negative or larger than its
capacity
* @throws java.lang.IllegalArgumentException if
<tt>delta</tt> is <tt>NaN</tt>
*/
public void addResidualFlowTo(int vertex, double delta)
{
if
(vertex == v) flow -= delta;
//
backward edge
else if (vertex == w) flow += delta;
//
forward edge
else throw new IllegalArgumentException("Illegal
endpoint");
if (Double.isNaN(delta)) throw new
IllegalArgumentException("Change in flow = NaN");

if (!(flow >= 0.0))


throw new
IllegalArgumentException("Flow is negative");
if (!(flow <= capacity)) throw new
IllegalArgumentException("Flow exceeds capacity");
}
/**
* Returns a string representation of the edge.
* @return a string representation of the edge
*/
public String toString() {
return v + "->" + w + " " + flow + "/" + capacity;
}
/**
* Unit tests the <tt>FlowEdge</tt> data type.
*/
public static void main(String[] args) {
FlowEdge e = new FlowEdge(12, 23, 3.14);
StdOut.println(e);
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Tue Jul 28 10:06:44 EDT 2015.
BipartiteMatching.java
Below is the syntax highlighted version
of BipartiteMatching.java from 6.5 Reductions.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac BipartiteMatching.java
* Execution:
java BipartiteMatching N E
* Dependencies: FordFulkerson.java FlowNetwork.java
FlowEdge.java
*

* Find a maximum matching in a bipartite graph. Solve by


reducing
* to maximum flow.
*
* The order of growth of the running time in the worst
case is E V
* because each augmentation increases the cardinality of
the matching
* by one.
*
* The Hopcroft-Karp algorithm improves this to E V^1/2 by
finding
* a maximal set of shortest augmenting paths in each
phase.
*
***********************************************************
**********/
public class BipartiteMatching {
public static void main(String[] args) {
// read in bipartite network with 2N vertices and E
edges
// we assume the vertices on one side of the
bipartition
// are named 0 to N-1 and on the other side are N
to 2N-1.
int N = Integer.parseInt(args[0]);
int E = Integer.parseInt(args[1]);
int s = 2*N, t = 2*N + 1;
FlowNetwork G = new FlowNetwork(2*N + 2);
for (int i = 0; i < E; i++) {
int v = StdRandom.uniform(N);
int w = StdRandom.uniform(N) + N;
G.addEdge(new FlowEdge(v, w,
Double.POSITIVE_INFINITY));
StdOut.println(v + "-" + w);
}
for (int i = 0; i < N; i++) {
G.addEdge(new FlowEdge(s,
i, 1.0));
G.addEdge(new FlowEdge(i + N, t, 1.0));
}
// compute maximum flow and minimum cut

FordFulkerson maxflow = new FordFulkerson(G, s, t);


StdOut.println();
// guaranteed to be an integer
StdOut.printf("Size of maximum matching = %.0f\n",
maxflow.value());
for (int v = 0; v < N; v++) {
for (FlowEdge e : G.adj(v)) {
if (e.from() == v && e.flow() > 0)
StdOut.println(e.from() + "-" + e.to());
}
}
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Wed Jul 29 06:33:53 EDT 2015.
AssignmentProblem.java
Below is the syntax highlighted version
of AssignmentProblem.java from 6.5 Reductions.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac AssignmentProblem.java
* Execution:
java AssignmentProblem N
* Dependencies: DijkstraSP.java DirectedEdge.java
*
* Solve an N-by-N assignment problem in N^3 log N time
using the
* successive shortest path algorithm.
*
* Remark: could use dense version of Dijsktra's algorithm
for
* improved theoretical efficiency of N^3, but it doesn't
seem to
* help in practice.
*
* Assumes N-by-N cost matrix is nonnegative.
*
*

***********************************************************
**********/
public class AssignmentProblem {
private static final int UNMATCHED = -1;
private
columns
private
private
for row i
private
for col j
private
match
private
match

int N;

// number of rows and

double[][] weight;
double[] px;

// the N-by-N cost matrix


// px[i] = dual variable

double[] py;

// py[j] = dual variable

int[] xy;

// xy[i] = j means i-j is a

int[] yx;

// yx[j] = i means i-j is a

public AssignmentProblem(double[][] weight) {


N = weight.length;
this.weight = new double[N][N];
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
this.weight[i][j] = weight[i][j];
// dual variables
px = new double[N];
py = new double[N];
// initial matching is empty
xy = new int[N];
yx = new int[N];
for (int i = 0; i < N; i++)
xy[i] = UNMATCHED;
for (int j = 0; j < N; j++)
yx[j] = UNMATCHED;
// add N edges to matching
for (int k = 0; k < N; k++) {
assert isDualFeasible();
assert isComplementarySlack();
augment();
}
assert check();
}

// find shortest augmenting path and upate


private void augment() {
// build residual graph
EdgeWeightedDigraph G = new
EdgeWeightedDigraph(2*N+2);
int s = 2*N, t = 2*N+1;
for (int i = 0; i < N; i++) {
if (xy[i] == UNMATCHED)
G.addEdge(new DirectedEdge(s, i, 0.0));
}
for (int j = 0; j < N; j++) {
if (yx[j] == UNMATCHED)
G.addEdge(new DirectedEdge(N+j, t, py[j]));
}
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (xy[i] == j) G.addEdge(new
DirectedEdge(N+j, i, 0.0));
else
G.addEdge(new
DirectedEdge(i, N+j, reduced(i, j)));
}
}
// compute shortest path from s to every other
vertex
DijkstraSP spt = new DijkstraSP(G, s);
// augment along alternating path
for (DirectedEdge e : spt.pathTo(t)) {
int i = e.from(), j = e.to() - N;
if (i < N) {
xy[i] = j;
yx[j] = i;
}
}
// update dual variables
for (int i = 0; i < N; i++)
px[i] += spt.distTo(i);
for (int j = 0; j < N; j++)
py[j] += spt.distTo(N+j);
}
// reduced cost of i-j
private double reduced(int i, int j) {

return weight[i][j] + px[i] - py[j];


}
// dual variable for row i
public double dualRow(int i) {
return px[i];
}
// dual variable for column j
public double dualCol(int j) {
return py[j];
}
// total weight of min weight perfect matching
public double weight() {
double total = 0.0;
for (int i = 0; i < N; i++) {
if (xy[i] != UNMATCHED)
total += weight[i][xy[i]];
}
return total;
}
public int sol(int i) {
return xy[i];
}
// check that dual variables are feasible
private boolean isDualFeasible() {
// check that all edges have >= 0 reduced cost
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (reduced(i, j) < 0) {
StdOut.println("Dual variables are not
feasible");
return false;
}
}
}
return true;
}
// check that primal and dual variables are
complementary slack
private boolean isComplementarySlack() {
// check that all matched edges have 0-reduced cost

for (int i = 0; i < N; i++) {


if ((xy[i] != UNMATCHED) && (reduced(i, xy[i]) !
= 0)) {
StdOut.println("Primal and dual variables
are not complementary slack");
return false;
}
}
return true;
}
// check that primal variables are a perfect matching
private boolean isPerfectMatching() {
// check that xy[] is a perfect matching
boolean[] perm = new boolean[N];
for (int i = 0; i < N; i++) {
if (perm[xy[i]]) {
StdOut.println("Not a perfect matching");
return false;
}
perm[xy[i]] = true;
}
// check that xy[] and yx[] are inverses
for (int j = 0; j < N; j++) {
if (xy[yx[j]] != j) {
StdOut.println("xy[] and yx[] are not
inverses");
return false;
}
}
for (int i = 0; i < N; i++) {
if (yx[xy[i]] != i) {
StdOut.println("xy[] and yx[] are not
inverses");
return false;
}
}
return true;
}
// check optimality conditions
private boolean check() {

return isPerfectMatching() && isDualFeasible() &&


isComplementarySlack();
}
public static void main(String[] args) {
In in = new In(args[0]);
int N = in.readInt();
double[][] weight = new double[N][N];
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
weight[i][j] = in.readDouble();
}
}
AssignmentProblem assignment = new
AssignmentProblem(weight);
StdOut.println("weight = " + assignment.weight());
for (int i = 0; i < N; i++)
StdOut.println(i + "-" + assignment.sol(i) + "'
" + weight[i][assignment.sol(i)]);
for (int i = 0; i < N; i++)
StdOut.println("px[" + i + "] = " +
assignment.dualRow(i));
for (int j = 0; j < N; j++)
StdOut.println("py[" + j + "] = " +
assignment.dualCol(j));
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
StdOut.println("reduced[" + i + "-" + j + "]
= " + assignment.reduced(i, j));
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Tue Jul 28 10:06:44 EDT 2015.
Simplex.java
Below is the syntax highlighted version
of Simplex.java from 6.5 Reductions.
Here is the Javadoc.

/
***********************************************************
**************
* Compilation: javac Simplex.java
* Execution:
java Simplex M N
* Dependencies: StdOut.java
*
* Given an M-by-N matrix A, an M-length vector b, and an
* N-length vector c, solve the LP { max cx : Ax <= b, x
>= 0 }.
* Assumes that b >= 0 so that x = 0 is a basic feasible
solution.
*
* Creates an (M+1)-by-(N+M+1) simplex tableaux with the
* RHS in column M+N, the objective function in row M, and
* slack variables in columns M through M+N-1.
*
***********************************************************
**************/
public class Simplex {
private static final double EPSILON = 1.0E-10;
private double[][] a;
// tableaux
private int M;
// number of constraints
private int N;
// number of original variables
private int[] basis;
corresponding to row i

// basis[i] = basic variable


// only needed to print out

solution, not book


// sets up the simplex tableaux
public Simplex(double[][] A, double[] b, double[] c) {
M = b.length;
N = c.length;
a = new double[M+1][N+M+1];
for (int i = 0; i < M; i++)
for (int j = 0; j < N; j++)
a[i][j] = A[i][j];
for (int i = 0; i < M; i++)
a[i][N+i] = 1.0;
for (int j = 0; j < N; j++)
a[M][j] = c[j];
for (int i = 0; i < M; i++)
a[i][M+N] = b[i];

basis = new int[M];


for (int i = 0; i < M; i++)
basis[i] = N + i;
solve();
// check optimality conditions
assert check(A, b, c);
}
// run simplex algorithm starting from initial BFS
private void solve() {
while (true) {
// find entering column q
int q = bland();
if (q == -1) break; // optimal
// find leaving row p
int p = minRatioRule(q);
if (p == -1) throw new
ArithmeticException("Linear program is unbounded");
// pivot
pivot(p, q);
// update basis
basis[p] = q;
}
}
// lowest index of a non-basic column with a positive
cost
private int bland() {
for (int j = 0; j < M + N; j++)
if (a[M][j] > 0) return j;
return -1; // optimal
}
// index
private
int
for

of a non-basic column with most positive cost


int dantzig() {
q = 0;
(int j = 1; j < M + N; j++)
if (a[M][j] > a[M][q]) q = j;

if (a[M][q] <= 0) return -1;


else return q;

// optimal

}
// find
private
int
for

row p using min ratio rule (-1 if no such row)


int minRatioRule(int q) {
p = -1;
(int i = 0; i < M; i++) {
if (a[i][q] <= 0) continue;
else if (p == -1) p = i;
else if ((a[i][M+N] / a[i][q]) < (a[p][M+N] /
a[p][q])) p = i;
}
return p;
}
// pivot on entry (p, q) using Gauss-Jordan elimination
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];
// zero out column q
for (int i = 0; i <= M; i++)
if (i != p) a[i][q] = 0.0;
// scale row p
for (int j = 0; j <= M + N; j++)
if (j != q) a[p][j] /= a[p][q];
a[p][q] = 1.0;
}
// return optimal objective value
public double value() {
return -a[M][M+N];
}
// return primal solution vector
public double[] primal() {
double[] x = new double[N];
for (int i = 0; i < M; i++)
if (basis[i] < N) x[basis[i]] = a[i][M+N];
return x;
}
// return dual solution vector

public double[] dual() {


double[] y = new double[M];
for (int i = 0; i < M; i++)
y[i] = -a[M][N+i];
return y;
}
// is the solution primal feasible?
private boolean isPrimalFeasible(double[][] A, double[]
b) {
double[] x = primal();
// check that x >= 0
for (int j = 0; j < x.length; j++) {
if (x[j] < 0.0) {
StdOut.println("x[" + j + "] = " + x[j] + "
is negative");
return false;
}
}
// check that Ax <= b
for (int i = 0; i < M; i++) {
double sum = 0.0;
for (int j = 0; j < N; j++) {
sum += A[i][j] * x[j];
}
if (sum > b[i] + EPSILON) {
StdOut.println("not primal feasible");
StdOut.println("b[" + i + "] = " + b[i] + ",
sum = " + sum);
return false;
}
}
return true;
}
// is the solution dual feasible?
private boolean isDualFeasible(double[][] A, double[] c)
{
double[] y = dual();
// check that y >= 0
for (int i = 0; i < y.length; i++) {
if (y[i] < 0.0) {

StdOut.println("y[" + i + "] = " + y[i] + "


is negative");
return false;
}
}
// check that yA >= c
for (int j = 0; j < N; j++) {
double sum = 0.0;
for (int i = 0; i < M; i++) {
sum += A[i][j] * y[i];
}
if (sum < c[j] - EPSILON) {
StdOut.println("not dual feasible");
StdOut.println("c[" + j + "] = " + c[j] + ",
sum = " + sum);
return false;
}
}
return true;
}
// check that optimal value = cx = yb
private boolean isOptimal(double[] b, double[] c) {
double[] x = primal();
double[] y = dual();
double value = value();
// check that value = cx = yb
double value1 = 0.0;
for (int j = 0; j < x.length; j++)
value1 += c[j] * x[j];
double value2 = 0.0;
for (int i = 0; i < y.length; i++)
value2 += y[i] * b[i];
if (Math.abs(value - value1) > EPSILON ||
Math.abs(value - value2) > EPSILON) {
StdOut.println("value = " + value + ", cx = " +
value1 + ", yb = " + value2);
return false;
}
return true;
}
private boolean check(double[][]A, double[] b, double[]
c) {

return isPrimalFeasible(A, b) && isDualFeasible(A,


c) && isOptimal(b, c);
}
// print tableaux
public void show() {
StdOut.println("M = " + M);
StdOut.println("N = " + N);
for (int i = 0; i <= M; i++) {
for (int j = 0; j <= M + N; j++) {
StdOut.printf("%7.2f ", a[i][j]);
}
StdOut.println();
}
StdOut.println("value = " + value());
for (int i = 0; i < M; i++)
if (basis[i] < N) StdOut.println("x_" + basis[i]
+ " = " + a[i][M+N]);
StdOut.println();
}
public static void test(double[][] A, double[] b,
double[] c) {
Simplex lp = new Simplex(A, b, c);
StdOut.println("value = " + lp.value());
double[] x = lp.primal();
for (int i = 0; i < x.length; i++)
StdOut.println("x[" + i + "] = " + x[i]);
double[] y = lp.dual();
for (int j = 0; j < y.length; j++)
StdOut.println("y[" + j + "] = " + y[j]);
}
public static void
double[][] A =
{ -1, 1,
{ 1, 4,
{ 2, 1,
{ 3, -4,
{ 0, 0,
};
double[] c = {
double[] b = {
test(A, b, c);
}

test1() {
{
0 },
0 },
0 },
0 },
1 },
1, 1, 1 };
5, 45, 27, 24, 4 };

// x0 = 12, x1 = 28, opt = 800


public static void test2() {
double[] c = { 13.0, 23.0 };
double[] b = { 480.0, 160.0, 1190.0 };
double[][] A = {
{ 5.0, 15.0 },
{ 4.0, 4.0 },
{ 35.0, 20.0 },
};
test(A, b, c);
}
// unbounded
public static void test3() {
double[] c = { 2.0, 3.0, -1.0, -12.0 };
double[] b = { 3.0,
2.0 };
double[][] A = {
{ -2.0, -9.0, 1.0, 9.0 },
{ 1.0, 1.0, -1.0, -2.0 },
};
test(A, b, c);
}
// degenerate - cycles if you choose most positive
objective function coefficient
public static void test4() {
double[] c = { 10.0, -57.0, -9.0, -24.0 };
double[] b = { 0.0,
0.0, 1.0 };
double[][] A = {
{ 0.5, -5.5, -2.5, 9.0 },
{ 0.5, -1.5, -0.5, 1.0 },
{ 1.0, 0.0, 0.0, 0.0 },
};
test(A, b, c);
}

// test client
public static void main(String[] args) {
StdOut.println("----- test 1 --------------------");
test1();
StdOut.println("----- test 2 --------------------");
test2();
StdOut.println("----- test 3 --------------------");

try {
test3();
}
catch (ArithmeticException e) {
e.printStackTrace();
}
StdOut.println("----- test 4 --------------------");
test4();
StdOut.println("----- test random ---------------");
int M = Integer.parseInt(args[0]);
int N = Integer.parseInt(args[1]);
double[] c = new double[N];
double[] b = new double[M];
double[][] A = new double[M][N];
for (int j = 0; j < N; j++)
c[j] = StdRandom.uniform(1000);
for (int i = 0; i < M; i++)
b[i] = StdRandom.uniform(1000);
for (int i = 0; i < M; i++)
for (int j = 0; j < N; j++)
A[i][j] = StdRandom.uniform(100);
Simplex lp = new Simplex(A, b, c);
StdOut.println(lp.value());
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Tue Jul 28 10:20:31 EDT 2015.

GaussianElimination.java
Below is the syntax highlighted version
of GaussianElimination.java from 9.9 Scientific Computing.
Here is the Javadoc.

/
***********************************************************
**************
* Compilation: javac GaussianElimination.java
* Execution:
java GaussianElimination
* Dependencies: StdOut.java
*
* Gaussian elimination with partial pivoting.
*
* % java GaussianElimination
* -1.0
* 2.0
* 2.0
*
***********************************************************
**************/

public class GaussianElimination {


private static final double EPSILON = 1e-10;
// Gaussian elimination with partial pivoting
public static double[] lsolve(double[][] A, double[] b)
{
int N

= b.length;

for (int p = 0; p < N; p++) {


// find pivot row and swap
int max = p;
for (int i = p + 1; i < N; i++) {
if (Math.abs(A[i][p]) > Math.abs(A[max][p]))
{
max = i;
}
}
double[] temp = A[p]; A[p] = A[max]; A[max] =
temp;
double

= b[p]; b[p] = b[max]; b[max] = t;

// singular or nearly singular


if (Math.abs(A[p][p]) <= EPSILON) {
throw new ArithmeticException("Matrix is
singular or nearly singular");
}
// pivot within A and b
for (int i = p + 1; i < N;
double alpha = A[i][p]
b[i] -= alpha * b[p];
for (int j = p; j < N;
A[i][j] -= alpha *
}
}

i++) {
/ A[p][p];
j++) {
A[p][j];

}
// back substitution
double[] x = new double[N];
for (int i = N - 1; i >= 0; i--) {
double sum = 0.0;
for (int j = i + 1; j < N; j++) {
sum += A[i][j] * x[j];
}
x[i] = (b[i] - sum) / A[i][i];
}

return x;
}
// sample client
public static void main(String[] args) {
int N = 3;
double[][] A = {
{ 0, 1, 1 },
{ 2, 4, -2 },
{ 0, 3, 15 }
};
double[] b = { 4, 2, 36 };
double[] x = lsolve(A, b);
// print results
for (int i = 0; i < N; i++) {
StdOut.println(x[i]);
}
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Tue Jul 28 14:54:14 EDT 2015.
FFT.java
Below is the syntax highlighted version
of FFT.java from 9.9 Scientific Computing.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac FFT.java
* Execution:
java FFT N
* Dependencies: Complex.java
*
* Compute the FFT and inverse FFT of a length N complex
sequence.

* Bare bones implementation that runs in O(N log N) time.


Our goal
* is to optimize the clarity of the code, rather than
performance.
*
* Limitations
* ----------*
- assumes N is a power of 2
*
*
- not the most memory efficient algorithm (because it
uses
*
an object type for representing complex numbers and
because
*
it re-allocates memory for the subarray, instead of
doing
*
in-place or reusing a single temporary array)
*
*
* % java FFT 4
* x
* ------------------* -0.03480425839330703
* 0.07910192950176387
* 0.7233322451735928
* 0.1659819820667019
*
* y = fft(x)
* ------------------* 0.9336118983487516
* -0.7581365035668999 + 0.08688005256493803i
* 0.44344407521182005
* -0.7581365035668999 - 0.08688005256493803i
*
* z = ifft(y)
* ------------------* -0.03480425839330703
* 0.07910192950176387 + 2.6599344570851287E-18i
* 0.7233322451735928
* 0.1659819820667019 - 2.6599344570851287E-18i
*
* c = cconvolve(x, x)
* ------------------* 0.5506798633981853
* 0.23461407150576394 - 4.033186818023279E-18i
* -0.016542951108772352
* 0.10288019294318276 + 4.033186818023279E-18i
*

*
*
*
*
*
*
*
*
*
*
*

d = convolve(x, x)
------------------0.001211336402308083 - 3.122502256758253E-17i
-0.005506167987577068 - 5.058885073636224E-17i
-0.044092969479563274 + 2.1934338938072244E-18i
0.10288019294318276 - 3.6147323062478115E-17i
0.5494685269958772 + 3.122502256758253E-17i
0.240120239493341 + 4.655566391833896E-17i
0.02755001837079092 - 2.1934338938072244E-18i
4.01805098805014E-17i

***********************************************************
**************/
public class FFT {
private static final Complex ZERO = new Complex(0, 0);
// compute the FFT of x[], assuming its length is a
power of 2
public static Complex[] fft(Complex[] x) {
int N = x.length;
// base case
if (N == 1) return new Complex[] { x[0] };
// radix 2 Cooley-Tukey FFT
if (N % 2 != 0) {
throw new IllegalArgumentException("N is not a
power of 2");
}
// fft of even terms
Complex[] even = new Complex[N/2];
for (int k = 0; k < N/2; k++) {
even[k] = x[2*k];
}
Complex[] q = fft(even);
// fft of odd terms
Complex[] odd = even; // reuse the array
for (int k = 0; k < N/2; k++) {
odd[k] = x[2*k + 1];
}
Complex[] r = fft(odd);

// combine
Complex[] y = new Complex[N];
for (int k = 0; k < N/2; k++) {
double kth = -2 * k * Math.PI / N;
Complex wk = new Complex(Math.cos(kth),
Math.sin(kth));
y[k]
= q[k].plus(wk.times(r[k]));
y[k + N/2] = q[k].minus(wk.times(r[k]));
}
return y;
}
// compute the inverse FFT of x[], assuming its length
is a power of 2
public static Complex[] ifft(Complex[] x) {
int N = x.length;
Complex[] y = new Complex[N];
// take conjugate
for (int i = 0; i < N; i++) {
y[i] = x[i].conjugate();
}
// compute forward FFT
y = fft(y);
// take conjugate again
for (int i = 0; i < N; i++) {
y[i] = y[i].conjugate();
}
// divide by N
for (int i = 0; i < N; i++) {
y[i] = y[i].times(1.0 / N);
}
return y;
}
// compute the circular convolution of x and y
public static Complex[] cconvolve(Complex[] x, Complex[]
y) {

// should probably pad x and y with 0s so that they


have same length
// and are powers of 2
if (x.length != y.length) {
throw new IllegalArgumentException("Dimensions
don't agree");
}
int N = x.length;
// compute FFT of each sequence
Complex[] a = fft(x);
Complex[] b = fft(y);
// point-wise multiply
Complex[] c = new Complex[N];
for (int i = 0; i < N; i++) {
c[i] = a[i].times(b[i]);
}
// compute inverse FFT
return ifft(c);
}
// compute the linear convolution of x and y
public static Complex[] convolve(Complex[] x, Complex[]
y) {
Complex[] a = new Complex[2*x.length];
for (int i = 0; i < x.length; i++)
a[i] = x[i];
for (int i = x.length; i < 2*x.length; i++)
a[i] = ZERO;
Complex[] b = new Complex[2*y.length];
for (int i = 0; i < y.length; i++)
b[i] = y[i];
for (int i = y.length; i < 2*y.length; i++)
b[i] = ZERO;
return cconvolve(a, b);
}
// display an array of Complex numbers to standard
output
public static void show(Complex[] x, String title) {
StdOut.println(title);

StdOut.println("-------------------");
for (int i = 0; i < x.length; i++) {
StdOut.println(x[i]);
}
StdOut.println();
}

/**********************************************************
***********
* Test client.
***********************************************************
**********/
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(-2*Math.random() + 1, 0);
}
show(x, "x");
// FFT of original data
Complex[] y = fft(x);
show(y, "y = fft(x)");
// take inverse FFT
Complex[] z = ifft(y);
show(z, "z = ifft(y)");
// circular convolution of x with itself
Complex[] c = cconvolve(x, x);
show(c, "c = cconvolve(x, x)");
// linear convolution of x with itself
Complex[] d = convolve(x, x);
show(d, "d = convolve(x, x)");
}
}

Copyright 20022010, Robert Sedgewick and Kevin Wayne.


Last updated: Tue Jul 28 14:54:14 EDT 2015.
Complex.java
Below is the syntax highlighted version
of Complex.java from 9.9 Scientific Computing.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac Complex.java
* Execution:
java Complex
* Dependencies: StdOut.java
*
* Data type for complex numbers.
*
* The data type is "immutable" so once you create and
initialize
* a Complex object, you cannot change it. The "final"
keyword
* when declaring re and im enforces this rule, making it
a
* compile-time error to change the .re or .im fields
after
* they've been initialized.
*
* % java Complex
* a
= 5.0 + 6.0i
* b
= -3.0 + 4.0i
* Re(a)
= 5.0
* Im(a)
= 6.0
* b + a
= 2.0 + 10.0i
* a - b
= 8.0 + 2.0i
* a * b
= -39.0 + 2.0i
* b * a
= -39.0 + 2.0i
* a / b
= 0.36 - 1.52i
* (a / b) * b = 5.0 + 6.0i
* conj(a)
= 5.0 - 6.0i
* |a|
= 7.810249675906654
* tan(a)
= -6.685231390246571E-6 +
1.0000103108981198i
*

***********************************************************
**************/
public class Complex {
private final double re;
private final double im;

// the real part


// the imaginary part

// create a new object with the given real and


imaginary parts
public Complex(double real, double imag) {
re = real;
im = imag;
}
// return a string representation of the invoking
Complex object
public String toString() {
if (im == 0) return re + "";
if (re == 0) return im + "i";
if (im < 0) return re + " - " + (-im) + "i";
return re + " + " + im + "i";
}
// return abs/modulus/magnitude and
angle/phase/argument
public double abs()
{ return Math.hypot(re, im); }
// Math.sqrt(re*re + im*im)
public double phase() { return Math.atan2(im, re); }
// between -pi and pi
// return a new Complex object whose value is (this +
b)
public Complex plus(Complex b) {
Complex a = this;
// invoking object
double real = a.re + b.re;
double imag = a.im + b.im;
return new Complex(real, imag);
}
// return a new Complex object whose value is (this b)
public Complex minus(Complex b) {
Complex a = this;
double real = a.re - b.re;
double imag = a.im - b.im;
return new Complex(real, imag);

}
// return a new Complex object whose value is (this *
b)
public Complex times(Complex b) {
Complex a = this;
double real = a.re * b.re - a.im * b.im;
double imag = a.re * b.im + a.im * b.re;
return new Complex(real, imag);
}
// scalar multiplication
// return a new object whose value is (this * alpha)
public Complex times(double alpha) {
return new Complex(alpha * re, alpha * im);
}
// return a new Complex object whose value is the
conjugate of this
public Complex conjugate() { return new Complex(re,
-im); }
// return a new Complex object whose value is the
reciprocal of this
public Complex reciprocal() {
double scale = re*re + im*im;
return new Complex(re / scale, -im / scale);
}
// return the real or imaginary part
public double re() { return re; }
public double im() { return im; }
// return a / b
public Complex divides(Complex b) {
Complex a = this;
return a.times(b.reciprocal());
}
// return a new Complex object whose value is the
complex exponential of this
public Complex exp() {
return new Complex(Math.exp(re) * Math.cos(im),
Math.exp(re) * Math.sin(im));
}

// return a new Complex object whose value is the


complex sine of this
public Complex sin() {
return new Complex(Math.sin(re) * Math.cosh(im),
Math.cos(re) * Math.sinh(im));
}
// return a new Complex object whose value is the
complex cosine of this
public Complex cos() {
return new Complex(Math.cos(re) * Math.cosh(im),
-Math.sin(re) * Math.sinh(im));
}
// return a new Complex object whose value is the
complex tangent of this
public Complex tan() {
return sin().divides(cos());
}

// a static version of plus


public static Complex plus(Complex a, Complex b) {
double real = a.re + b.re;
double imag = a.im + b.im;
Complex sum = new Complex(real, imag);
return sum;
}

// sample client for testing


public static void main(String[] args) {
Complex a = new Complex(5.0, 6.0);
Complex b = new Complex(-3.0, 4.0);
StdOut.println("a
StdOut.println("b
StdOut.println("Re(a)
StdOut.println("Im(a)
StdOut.println("b + a
StdOut.println("a - b
StdOut.println("a * b
StdOut.println("b * a
StdOut.println("a / b

=
=
=
=
=
=
=
=
=

"
"
"
"
"
"
"
"
"

+
+
+
+
+
+
+
+
+

a);
b);
a.re());
a.im());
b.plus(a));
a.minus(b));
a.times(b));
b.times(a));
a.divides(b));

StdOut.println("(a / b) * b
a.divides(b).times(b));
StdOut.println("conj(a)
StdOut.println("|a|
StdOut.println("tan(a)
}

= " +
= " + a.conjugate());
= " + a.abs());
= " + a.tan());

}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Tue Jul 28 14:54:14 EDT 2015.
GrahamScan.java
Below is the syntax highlighted version
of GrahamScan.java from 9.9 Convex Hull.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac GrahamaScan.java
* Execution:
java GrahamScan < input.txt
* Dependencies: Point2D.java
*
* Create points from standard input and compute the
convex hull using
* Graham scan algorithm.
*
* May be floating-point issues if x- and y-coordinates
are not integers.
*
***********************************************************
**************/
import java.util.Arrays;
public class GrahamScan {
private Stack<Point2D> hull = new Stack<Point2D>();
public GrahamScan(Point2D[] pts) {

// defensive copy
int N = pts.length;
Point2D[] points = new Point2D[N];
for (int i = 0; i < N; i++)
points[i] = pts[i];
// preprocess so that points[0] has lowest ycoordinate; break ties by x-coordinate
// points[0] is an extreme point of the convex hull
// (alternatively, could do easily in linear time)
Arrays.sort(points);
// sort by polar angle with respect to base point
points[0],
// breaking ties by distance to points[0]
Arrays.sort(points, 1, N, points[0].polarOrder());
hull.push(points[0]);
extreme point

// p[0] is first

// find index k1 of first point not equal to


points[0]
int k1;
for (k1 = 1; k1 < N; k1++)
if (!points[0].equals(points[k1])) break;
if (k1 == N) return;
// all points equal
// find index k2 of first point not collinear with
points[0] and points[k1]
int k2;
for (k2 = k1 + 1; k2 < N; k2++)
if (Point2D.ccw(points[0], points[k1],
points[k2]) != 0) break;
hull.push(points[k2-1]);
// points[k2-1] is
second extreme point
// Graham scan; note that points[N-1] is extreme
point different from points[0]
for (int i = k2; i < N; i++) {
Point2D top = hull.pop();
while (Point2D.ccw(hull.peek(), top, points[i])
<= 0) {
top = hull.pop();
}
hull.push(top);
hull.push(points[i]);
}

assert isConvex();
}
// return extreme points on convex hull in
counterclockwise order as an Iterable
public Iterable<Point2D> hull() {
Stack<Point2D> s = new Stack<Point2D>();
for (Point2D p : hull) s.push(p);
return s;
}
// check that boundary of hull is strictly convex
private boolean isConvex() {
int N = hull.size();
if (N <= 2) return true;
Point2D[] points = new Point2D[N];
int n = 0;
for (Point2D p : hull()) {
points[n++] = p;
}
for (int i = 0; i < N; i++) {
if (Point2D.ccw(points[i], points[(i+1) % N],
points[(i+2) % N]) <= 0) {
return false;
}
}
return true;
}
// test client
public static void main(String[] args) {
int N = StdIn.readInt();
Point2D[] points = new Point2D[N];
for (int i = 0; i < N; i++) {
int x = StdIn.readInt();
int y = StdIn.readInt();
points[i] = new Point2D(x, y);
}
GrahamScan graham = new GrahamScan(points);
for (Point2D p : graham.hull())
StdOut.println(p);
}
}

Copyright 20022010, Robert Sedgewick and Kevin Wayne.


Last updated: Wed Jul 29 10:02:52 EDT 2015.
FarthestPair.java
Below is the syntax highlighted version
of FarthestPair.java from 9.9 Convex Hull.

/
***********************************************************
**************
* Compilation: javac FarthestPair.java
* Execution:
java FarthestPair < input.txt
* Dependencies: GrahamScan.java Point2D.java
*
* Given a set of N points in the plane, find the farthest
pair
* (equivalently, compute the diameter of the set of
points).
*
* Computes the convex hull of the set of points and using
the
* rotating callipers method to find all antipodal point
pairs
* and the farthest pair.
*
***********************************************************
**************/
public class FarthestPair {
// farthest pair of points and distance
private Point2D best1, best2;
private double bestDistance = Double.NEGATIVE_INFINITY;
public FarthestPair(Point2D[] points) {
GrahamScan graham = new GrahamScan(points);
// single point
if (points.length <= 1) return;

// number of points on the hull


int M = 0;
for (Point2D p : graham.hull())
M++;
// the hull, in counterclockwise order
Point2D[] hull = new Point2D[M+1];
int m = 1;
for (Point2D p : graham.hull()) {
hull[m++] = p;
}
// all points are equal
if (M == 1) return;
// points are collinear
if (M == 2) {
best1 = hull[1];
best2 = hull[2];
bestDistance = best1.distanceTo(best2);
return;
}
// k = farthest vertex from edge from hull[1] to
hull[M]
int k = 2;
while (Point2D.area2(hull[M], hull[k+1], hull[1]) >
Point2D.area2(hull[M], hull[k], hull[1])) {
k++;
}
int j = k;
for (int i = 1; i <= k; i++) {
// StdOut.println("hull[i] + " and " + hull[j]
+ " are antipodal");
if (hull[i].distanceTo(hull[j]) > bestDistance)
{
best1 = hull[i];
best2 = hull[j];
bestDistance = hull[i].distanceTo(hull[j]);
}
while ((j < M) && Point2D.area2(hull[i],
hull[j+1], hull[i+1]) > Point2D.area2(hull[i], hull[j],
hull[i+1])) {
j++;
// StdOut.println(hull[i] + " and " +
hull[j] + " are antipodal");

double distance =
hull[i].distanceTo(hull[j]);
if (distance > bestDistance) {
best1 = hull[i];
best2 = hull[j];
bestDistance =
hull[i].distanceTo(hull[j]);
}
}
}
}
public Point2D either()
public Point2D other()
public double distance()

{ return best1;
}
{ return best2;
}
{ return bestDistance; }

public static void main(String[] args) {


int N = StdIn.readInt();
Point2D[] points = new Point2D[N];
for (int i = 0; i < N; i++) {
int x = StdIn.readInt();
int y = StdIn.readInt();
points[i] = new Point2D(x, y);
}
FarthestPair farthest = new FarthestPair(points);
StdOut.println(farthest.distance() + " from " +
farthest.either() + " to " + farthest.other());
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Sat Aug 6 09:11:10 EDT 2011.
ClosestPair.java
Below is the syntax highlighted version
of ClosestPair.java from 9.9 Convex Hull.
the Javadoc.

Here is

/
***********************************************************
**************

* Compilation: javac ClosestPair.java


* Execution:
java ClosestPair < input.txt
* Dependencies: Point2D.java
*
* 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
* instead of Euclidean distances.
*
***********************************************************
**************/
import java.util.Arrays;
public class ClosestPair {
// closest pair of points and their Euclidean distance
private Point2D best1, best2;
private double bestDistance = Double.POSITIVE_INFINITY;
public ClosestPair(Point2D[] points) {
int N = points.length;
if (N <= 1) return;
// sort by x-coordinate (breaking ties by ycoordinate)
Point2D[] pointsByX = new Point2D[N];
for (int i = 0; i < N; i++)
pointsByX[i] = points[i];
Arrays.sort(pointsByX, Point2D.X_ORDER);
// check for coincident points
for (int i = 0; i < N-1; i++) {
if (pointsByX[i].equals(pointsByX[i+1])) {
bestDistance = 0.0;
best1 = pointsByX[i];
best2 = pointsByX[i+1];
return;
}
}
// sort by y-coordinate (but not yet sorted)
Point2D[] pointsByY = new Point2D[N];
for (int i = 0; i < N; i++)

pointsByY[i] = pointsByX[i];
// auxiliary array
Point2D[] aux = new Point2D[N];
closest(pointsByX, pointsByY, aux, 0, N-1);
}
// find closest pair of points in pointsByX[lo..hi]
// precondition: pointsByX[lo..hi] and
pointsByY[lo..hi] are the same sequence of points
// precondition: pointsByX[lo..hi] sorted by xcoordinate
// postcondition: pointsByY[lo..hi] sorted by ycoordinate
private double closest(Point2D[] pointsByX, Point2D[]
pointsByY, Point2D[] aux, int lo, int hi) {
if (hi <= lo) return Double.POSITIVE_INFINITY;
int mid = lo + (hi - lo) / 2;
Point2D median = pointsByX[mid];
// compute closest pair with both endpoints in left
subarray or both in right subarray
double delta1 = closest(pointsByX, pointsByY, aux,
lo, mid);
double delta2 = closest(pointsByX, pointsByY, aux,
mid+1, hi);
double delta = Math.min(delta1, delta2);
// merge back so that pointsByY[lo..hi] are sorted
by y-coordinate
merge(pointsByY, aux, lo, mid, hi);
// aux[0..M-1] = sequence of points closer than
delta, sorted by y-coordinate
int M = 0;
for (int i = lo; i <= hi; i++) {
if (Math.abs(pointsByY[i].x() - median.x()) <
delta)
aux[M++] = pointsByY[i];
}
// compare each point to its neighbors with ycoordinate closer than delta
for (int i = 0; i < M; i++) {

// a geometric packing argument shows that this


loop iterates at most 7 times
for (int j = i+1; (j < M) && (aux[j].y() aux[i].y() < delta); j++) {
double distance = aux[i].distanceTo(aux[j]);
if (distance < delta) {
delta = distance;
if (distance < bestDistance) {
bestDistance = delta;
best1 = aux[i];
best2 = aux[j];
// StdOut.println("better distance
= " + delta + " from " + best1 + " to " + best2);
}
}
}
}
return delta;
}
public Point2D either() { return best1; }
public Point2D other() { return best2; }
public double distance() {
return bestDistance;
}
// is v < w ?
private static boolean less(Comparable v, Comparable w)
{
return (v.compareTo(w) < 0);
}
// stably merge a[lo .. mid] with a[mid+1 ..hi] using
aux[lo .. hi]
// precondition: a[lo .. mid] and a[mid+1 .. hi] are
sorted subarrays
private static void merge(Comparable[] a, Comparable[]
aux, int lo, int mid, int hi) {
// copy to aux[]
for (int k = lo; k <= hi; 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]
else if (j > hi)
a[k]
else if (less(aux[j], aux[i])) a[k]
else
a[k]

=
=
=
=

aux[j++];
aux[i++];
aux[j++];
aux[i++];

}
}

public static void main(String[] args) {


int N = StdIn.readInt();
Point2D[] points = new Point2D[N];
for (int i = 0; i < N; i++) {
double x = StdIn.readDouble();
double y = StdIn.readDouble();
points[i] = new Point2D(x, y);
}
ClosestPair closest = new ClosestPair(points);
StdOut.println(closest.distance() + " from " +
closest.either() + " to " + closest.other());
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Tue Jul 28 15:06:57 EDT 2015.
FenwickTree.java
Below is the syntax highlighted version
of FenwickTree.java from 9.9 Miscellaneous.
the Javadoc.

Here is

import java.util.ArrayList;
import java.util.Arrays;
/**
* Created by ricardodpsx@gmail.com on 4/01/15.
* <p/>
* In <tt>Fenwick Tree</tt> structure We arrange the array
in an smart way to perform efficient <em>range queries and
updates</em>.

* The key point is this: In a fenwick array, each position


"responsible" for storing cumulative data of N previous
positions (N could be 1)
* For example:
* array[40] stores: array[40] + array[39] ... + array[32]
(8 positions)
* array[32] stores: array[32] + array[31] ... + array[1]
(32 positions)
* <p/>
* <strong>But, how do you know how much positions a given
index is "responsible" for?</strong>
* <p>
* To know the number of items that a given array position
'ind' is responsible for
* We should extract from 'ind' the portion up to the first
significant one of the binary representation of 'ind'
* for example, given ind == 40 (101000 in binary),
according to Fenwick algorithm
* what We want is to extract 1000(8 in decimal).
* </p>
* <p/>
* <p>
* This means that array[40] has cumulative information of
8 array items.
* But We still need to know the cumulative data bellow
array[40 - 8 = 32]
* 32 is 100000 in binnary, and the portion up to the
least significant one is 32 itself!
* So array[32] has information of 32 items, and We are
done!
* </p>
* <p/>
* <p>
* So cummulative data of array[1...40] = array[40] +
array[32]
* Because 40 has information of items from 40 to 32, and
32 has information of items from 32 to 1
* </p>
* <p/>
* Memory usage: O(n)
*
* @author Ricardo Pacheco
*/
public class FenwickTree {

int[] array; // 1-indexed array, In this array We save


cumulative information to perform efficient range queries
and updates
public FenwickTree(int size) {
array = new int[size + 1];
}
/**
* Range Sum query from 1 to ind
* ind is 1-indexed
* <p/>
* Time-Complexity:
O(log(n))
*/
public int rsq(int ind) {
assert ind > 0;
int sum = 0;
while (ind > 0) {
sum += array[ind];
//Extracting the portion up to the first
significant one of the binary representation of 'ind' and
decrementing ind by that number
ind -= ind & (-ind);
}
return sum;
}
/**
* Range Sum Query from a to b.
* Search for the sum from array index from a to b
* a and b are 1-indexed
* <p/>
* Time-Complexity:
O(log(n))
*/
public int rsq(int a, int b) {
assert b >= a && a > 0 && b > 0;
return rsq(b) - rsq(a - 1);
}
/**
* Update the array at ind and all the affected regions
above ind.
* ind is 1-indexed
* <p/>
* Time-Complexity:
O(log(n))

*/
public void update(int ind, int value) {
assert ind > 0;
while (ind < array.length) {
array[ind] += value;
//Extracting the portion up to the first
significant one of the binary representation of 'ind' and
incrementing ind by that number
ind += ind & (-ind);
}
}
public int size() {
return array.length - 1;
}
/**
* Read the following commands:
* init n
Initializes the array of size n all
zeroes
* set a b c
Initializes the array with [a, b,
c ...]
* rsq a b
Range Sum Query for the range [a,b]
* up i v
Update the i position of the array with
value v.
* exit
* <p/>
* The array is 1-indexed
* Example:
* <<set 1 2 3 4 5 6
* <<rsq 1 3
* >>Sum from 1 to 3 = 6
* <<rmq 1 3
* >>Min from 1 to 3 = 1
* <<input up 1 3
* >>[3,2,3,4,5,6]
*
* @param args
*/
public static void main(String[] args) {
FenwickTree ft = null;
String cmd = "cmp";
while (true) {

String[] line = StdIn.readLine().split(" ");


if (line[0].equals("exit")) break;
int arg1 = 0, arg2 = 0;
if (line.length > 1) {
arg1 = Integer.parseInt(line[1]);
}
if (line.length > 2) {
arg2 = Integer.parseInt(line[2]);
}
if ((!line[0].equals("set") && !
line[0].equals("init")) && ft == null) {
StdOut.println("FenwickTree not
initialized");
continue;
}
if (line[0].equals("init")) {
ft = new FenwickTree(arg1);
for (int i = 1; i <= ft.size(); i++) {
StdOut.print(ft.rsq(i, i) + " ");
}
StdOut.println();
}
else if (line[0].equals("set")) {
ft = new FenwickTree(line.length - 1);
for (int i = 1; i <= line.length - 1; i++) {
ft.update(i, Integer.parseInt(line[i]));
}
}
else if (line[0].equals("up")) {
ft.update(arg1, arg2);
for (int i = 1; i <= ft.size(); i++) {
StdOut.print(ft.rsq(i, i) + " ");
}
StdOut.println();
}
else if (line[0].equals("rsq")) {
StdOut.printf("Sum from %d to %d = %d%n",
arg1, arg2, ft.rsq(arg1, arg2));
}
else {
StdOut.println("Invalid command");

}
}
StdOut.close();
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Wed Jul 22 16:03:11 EDT 2015.
SegmentTree.java
Below is the syntax highlighted version
of SegmentTree.java from 9.9 Miscellaneous.
the Javadoc.

Here is

import java.util.Arrays;
/**
* The <tt>SegmentTree</tt> class is an structure for
efficient search of cummulative data.
* It performs Range Minimum Query and Range Sum Query in
O(log(n)) time.
* It can be easily customizable to support Range Max
Query, Range Multiplication Query etc.
* <p/>
* Also it has been develop with <tt>LazyPropagation</tt>
for range updates, which means
* when you perform update operations over a range, the
update process affects the least nodes as possible
* so that the bigger the range you want to update the less
time it consumes to update it. Eventually those changes
will be propagated
* to the children and the whole array will be up to date.
* <p/>
* <p/>
* <p/>
* Example:
* <p/>
* SegmentTreeHeap st = new SegmentTreeHeap(new Integer[]
{1,3,4,2,1, -2, 4});

* st.update(0,3, 1)
* In the above case only the node that represents the
range [0,3] will be updated (and not their children) so in
this case
* the update task will be less than n*log(n)
*
* Memory usage: O(n)
*
* @author Ricardo Pacheco
* <p/>
*/
public class SegmentTree {
private Node[] heap;
private int[] array;
private int size;
/**
* Time-Complexity: O(n*log(n))
*
* @param array the Initialization array
*/
public SegmentTree(int[] array) {
this.array = Arrays.copyOf(array, array.length);
//The max size of this array is about 2 * 2 ^
log2(n) + 1
size = (int) (2 * Math.pow(2.0,
Math.floor((Math.log((double) array.length) / Math.log(2.0))
+ 1)));
heap = new Node[size];
build(1, 0, array.length);
}
public int size() {
return array.length;
}
//Initialize the Nodes of the Segment tree
private void build(int v, int from, int size) {
heap[v] = new Node();
heap[v].from = from;
heap[v].to = from + size - 1;
if (size == 1) {
heap[v].sum = array[from];
heap[v].min = array[from];

} else {
//Build childs
build(2 * v, from, size / 2);
build(2 * v + 1, from + size / 2, size - size /
2);
heap[v].sum = heap[2 * v].sum + heap[2 * v +
1].sum;
//min = min of the children
heap[v].min = Math.min(heap[2 * v].min, heap[2 *
v + 1].min);
}
}
/**
* Range Sum Query
*
* Time-Complexity: O(log(n))
*/
public int RSQ(int from, int to) {
return RSQ(1, from, to);
}
private int RSQ(int v, int from, int to) {
Node n = heap[v];
//If you did a range update that contained this
node, you can infer the Sum without going down the tree
if (n.pendingVal != null && contains(n.from, n.to,
from, to)) {
return (to - from + 1) * n.pendingVal;
}
if (contains(from, to, n.from, n.to)) {
return heap[v].sum;
}
if (intersects(from, to, n.from, n.to)) {
propagate(v);
int leftSum = RSQ(2 * v, from, to);
int rightSum = RSQ(2 * v + 1, from, to);
return leftSum + rightSum;
}
return 0;
}

/**
* Range Min Query
*
* Time-Complexity: O(log(n))
*/
public int RMinQ(int from, int to) {
return RMinQ(1, from, to);
}
private int RMinQ(int v, int from, int to) {
Node n = heap[v];
//If you did a range update that contained this
node, you can infer the Min value without going down the
tree
if (n.pendingVal != null && contains(n.from, n.to,
from, to)) {
return n.pendingVal;
}
if (contains(from, to, n.from, n.to)) {
return heap[v].min;
}
if (intersects(from, to, n.from, n.to)) {
propagate(v);
int leftMin = RMinQ(2 * v, from, to);
int rightMin = RMinQ(2 * v + 1, from, to);
return Math.min(leftMin, rightMin);
}
return Integer.MAX_VALUE;
}
/**
* Range Update Operation.
* With this operation you can update either one
position or a range of positions with a given number.
* The update operations will update the less it can to
update the whole range (Lazy Propagation).
* The values will be propagated lazily from top to
bottom of the segment tree.

* This behavior is really useful for updates on


portions of the array
* <p/>
* Time-Complexity: O(log(n))
*
* @param from
* @param to
* @param value
*/
public void update(int from, int to, int value) {
update(1, from, to, value);
}
private void update(int v, int from, int to, int value)
{
//The Node of the heap tree represents a range of
the array with bounds: [n.from, n.to]
Node n = heap[v];
/**
* If the updating-range contains the portion of
the current Node We lazily update it.
* This means We do NOT update each position of the
vector, but update only some temporal
* values into the Node; such values into the Node
will be propagated down to its children only when they need
to.
*/
if (contains(from, to, n.from, n.to)) {
change(n, value);
}
if (n.size() == 1) return;
if (intersects(from, to, n.from, n.to)) {
/**
* Before keeping going down to the tree We
need to propagate the
* the values that have been temporally/lazily
saved into this Node to its children
* So that when We visit them the values are
properly updated
*/
propagate(v);
update(2 * v, from, to, value);

update(2 * v + 1, from, to, value);


n.sum = heap[2 * v].sum + heap[2 * v + 1].sum;
n.min = Math.min(heap[2 * v].min, heap[2 * v +
1].min);
}
}
//Propagate temporal values to children
private void propagate(int v) {
Node n = heap[v];
if (n.pendingVal != null) {
change(heap[2 * v], n.pendingVal);
change(heap[2 * v + 1], n.pendingVal);
n.pendingVal = null; //unset the pending
propagation value
}
}
//Save the temporal values that will be propagated
lazily
private void change(Node n, int value) {
n.pendingVal = value;
n.sum = n.size() * value;
n.min = value;
array[n.from] = value;
}
//Test if the range1 contains range2
private boolean contains(int from1, int to1, int from2,
int to2) {
return from2 >= from1 && to2 <= to1;
}
//check inclusive intersection, test if range1[from1,
to1] intersects range2[from2, to2]
private boolean intersects(int from1, int to1, int
from2, int to2) {
return from1 <= from2 && to1 >= from2
// (.
[..)..] or (.[...]..)
|| from1 >= from2 && from1 <= to2; // [.
(..]..) or [..(..)..
}

//The Node class represents a partition range of the


array.
static class Node {
int sum;
int min;
//Here We store the value that will be propagated
lazily
Integer pendingVal = null;
int from;
int to;
int size() {
return to - from + 1;
}
}
/**
* Read the following commands:
* init n v
Initializes the array of size n with
all v's
* set a b c... Initializes the array with [a, b,
c ...]
* rsq a b
Range Sum Query for the range [a, b]
* rmq a b
Range Min Query for the range [a, b]
* up a b v
Update the [a,b] portion of the array
with value v.
* exit
* <p/>
* Example:
* <<init
* <<set 1 2 3 4 5 6
* <<rsq 1 3
* >>Sum from 1 to 3 = 6
* <<rmq 1 3
* >>Min from 1 to 3 = 1
* <<input up 1 3
* >>[3,2,3,4,5,6]
*
* @param args
*/
public static void main(String[] args) {
SegmentTree st = null;
String cmd = "cmp";

while (true) {
String[] line = StdIn.readLine().split(" ");
if (line[0].equals("exit")) break;
int arg1 = 0, arg2 = 0, arg3 = 0;
if (line.length > 1) {
arg1 = Integer.parseInt(line[1]);
}
if (line.length > 2) {
arg2 = Integer.parseInt(line[2]);
}
if (line.length > 3) {
arg3 = Integer.parseInt(line[3]);
}
if ((!line[0].equals("set") && !
line[0].equals("init")) && st == null) {
StdOut.println("Segment Tree not
initialized");
continue;
}
int array[];
if (line[0].equals("set")) {
array = new int[line.length - 1];
for (int i = 0; i < line.length - 1; i++) {
array[i] = Integer.parseInt(line[i +
1]);
}
st = new SegmentTree(array);
}
else if (line[0].equals("init")) {
array = new int[arg1];
Arrays.fill(array, arg2);
st = new SegmentTree(array);
for (int i = 0; i < st.size(); i++) {
StdOut.print(st.RSQ(i, i) + " ");
}
StdOut.println();
}
else if (line[0].equals("up")) {
st.update(arg1, arg2, arg3);
for (int i = 0; i < st.size(); i++) {
StdOut.print(st.RSQ(i, i) + " ");

}
StdOut.println();
}
else if (line[0].equals("rsq")) {
StdOut.printf("Sum from %d to %d = %d%n",
arg1, arg2, st.RSQ(arg1, arg2));
}
else if (line[0].equals("rmq")) {
StdOut.printf("Min from %d to %d = %d%n",
arg1, arg2, st.RMinQ(arg1, arg2));
}
else {
StdOut.println("Invalid command");
}
}
StdOut.close();
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Wed Jul 22 16:09:11 EDT 2015.
PatriciaST.java
Below is the syntax highlighted version
of PatriciaST.java from 9.9 Miscellaneous.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac PatriciaST.java
* Execution:
java PatriciaST
* Dependencies: StdOut.java StdRandom.java Queue.java
* Data files:
n/a
*
* A symbol table implementation based on PATRICIA.
*
* % java PatriciaST 1000000 1

*
*
*
*
*
*
*
*
*
*
*
*
*
*
*

Creating dataset (1000000 items)...


Shuffling...
Adding (1000000 items)...
Iterating...
1000000 items iterated
Shuffling...
Deleting (500000 items)...
Iterating...
500000 items iterated
Checking...
500000 items found and 500000 (deleted) items missing
Deleting the rest (500000 items)...
PASS 1 TESTS SUCCEEDED
%

***********************************************************
**************/
/**
* The <code>PatriciaST</code> class provides an
implementation of an unordered
* symbol table of key-value pairs, with the restriction
that the key is of
* class {@link java.lang.String}. It supports the usual
<em>put</em>,
* <em>get</em>, <em>contains</em>, <em>delete</em>,
<em>size</em>, and
* <em>is-empty</em> methods. It also provides a
<em>keys</em> method for
* iterating over all of the keys. A symbol table
implements the
* <em>associative array</em> abstraction: when
associating a value with a key
* that is already in the symbol table, the convention is
to replace the old
* value with the new value. Unlike {@link java.util.Map},
this class uses the
* convention that values cannot be
<code>null</code>&mdash;setting the value
* associated with a key to <code>null</code> is
equivalent to deleting the key
* from the symbol table.
* <p>
* This unordered symbol table class implements PATRICIA
(Practical Algorithm

* to Retrieve Information Coded In Alphanumeric). In


spite of the acronym,
* string keys are not limited to alphanumeric content. A
key may possess any
* string value, except for the string of zero length (the
empty string).
* <p>
* Unlike other generic symbol table implementations that
can accept a
* parameterized key type, this symbol table class can
only accommodate keys
* of class {@link java.lang.String}. This unfortunate
restriction stems from a
* limitation in Java. Although Java provides excellent
support for generic
* programming, the current infrastructure somewhat limits
generic collection
* implementations to those that employ comparison-based
or hash-based methods.
* PATRICIA does not employ comparisons or hashing;
instead, it relies on
* bit-test operations. Because Java does not furnish any
generic abstractions
* (or implementations) for bit-testing the contents of an
object, providing
* support for generic keys using PATRICIA does not seem
practical.
* <p>
* PATRICIA is a variation of a trie, and it is often
classified as a
* space-optimized trie. In a classical trie, each level
represents a
* subsequent digit in a key. In PATRICIA, nodes only
exist to identify the
* digits (bits) that distinguish the individual keys
within the trie. Because
* PATRICIA uses a radix of two, each node has only two
children, like a binary
* tree. Also like a binary tree, the number of nodes,
within the trie, equals
* the number of keys. Consequently, some classify
PATRICIA as a tree.
* <p>
* The analysis of PATRICIA is complicated. The
theoretical wost-case
* performance for a <em>get</em>, <em>put</em>, or
<em>delete</em> operation

* is <strong>O(N)</strong>, when <strong>N</strong> is


less than
* <strong>W</strong> (where <strong>W</strong> is the
length in bits of the
* longest key), and <strong>O(W)</strong>, when
<strong>N</strong> is greater
* than <strong>W</strong>. However, the worst case is
unlikely to occur with
* typical use. The average (and usual) performance of
PATRICIA is
* approximately <strong>~lg N</strong> for each
<em>get</em>, <em>put</em>, or
* <em>delete</em> operation. Although this appears to put
PATRICIA on the same
* footing as binary trees, this time complexity
represents the number of
* single-bit test operations (under PATRICIA), and not
full-key comparisons
* (as required by binary trees). After the single-bit
tests conclude, PATRICIA
* requires just one full-key comparison to confirm the
existence (or absence)
* of the key (per <em>get</em>, <em>put</em>, or
<em>delete</em> operation).
* <p>
* In practice, decent implementations of PATRICIA can
often outperform
* balanced binary trees, and even hash tables. Although
this particular
* 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,
* or in another programming language.
* <p>
* Other resources for PATRICIA:<br>
* Sedgewick, R. (1990) <i>Algorithms in C</i>, AddisonWesley<br>
* Knuth, D. (1973) <i>The Art of Computer
Programming</i>, Addison-Wesley<br>
*
* @author John Hentosh (based on an implementation by
Robert Sedgewick)

*/
public class PatriciaST<Value> {
private Node head;
private int count;
/* An inner Node class specifies the objects that hold
each key-value pair.
* The b value indicates the relevant bit position.
*/
private class Node {
private Node left, right;
private String key;
private Value val;
private int b;
public Node(String key, Value val, int b) {
this.key = key;
this.val = val;
this.b = b;
}
};
/**
* Initializes an empty PATRICIA-based symbol table.
*/
/* The constructor creates a head (sentinel) node that
contains a
* zero-length string.
*/
public PatriciaST() {
head = new Node("", null, 0);
head.left = head;
head.right = head;
count = 0;
}
/**
* Places a key-value pair into the symbol table. If
the table already
* contains the specified key, then its associated
value becomes updated.
* If the value provided is <code>null</code>, then the
key becomes removed
* from the symbol table.
* @param key the key
* @param val the value

* @throws NullPointerException if <code>key</code> is


<code>null</code>
* @throws IllegalArgumentException if <code>key</code>
is the empty string.
*/
public void put(String key, Value val) {
if (key == null) throw new
NullPointerException("called put(null)");
if (key.length() == 0) throw new
IllegalArgumentException("invalid key");
if (val == null) delete(key);
Node p;
Node x = head;
do {
p = x;
if (safeBitTest(key, x.b)) x = x.right;
else
x = x.left;
} while (p.b < x.b);
if (!x.key.equals(key)) {
int b = firstDifferingBit(x.key, key);
x = head;
do {
p = x;
if (safeBitTest(key, x.b)) x = x.right;
else
x = x.left;
} while (p.b < x.b && x.b < b);
Node t = new Node(key, val, b);
if (safeBitTest(key, b)) {
t.left = x;
t.right = t;
}
else {
t.left = t;
t.right = x;
}
if (safeBitTest(key, p.b)) p.right = t;
else
p.left = t;
count++;
}
else x.val = val;
}
/**
* Retrieves the value associated with the given key.
* @param key the key
* @return the value associated with the given key if
the key is in the

* symbol table and <code>null</code> if the key is not


in the symbol table
* @throws NullPointerException if <code>key</code> is
<code>null</code>
* @throws IllegalArgumentException if <code>key</code>
is the empty string.
*/
public Value get(String key) {
if (key == null) throw new
NullPointerException("called get(null)");
if (key.length() == 0) throw new
IllegalArgumentException("invalid key");
Node p;
Node x = head;
do {
p = x;
if (safeBitTest(key, x.b)) x = x.right;
else
x = x.left;
} while (p.b < x.b);
if (x.key.equals(key)) return x.val;
else
return null;
}
/**
* Removes a key and its associated value from the
symbol table, if it
* exists.
* @param key the key
* @throws NullPointerException if <code>key</code> is
<code>null</code>
* @throws IllegalArgumentException if <code>key</code>
is the empty string.
*/
public void delete(String key) {
if (key == null) throw new
NullPointerException("called delete(null)");
if (key.length() == 0) throw new
IllegalArgumentException("invalid key");
Node g;
// previous previous
(grandparent)
Node p = head;
// previous (parent)
Node x = head;
// node to delete
do {
g = p;
p = x;
if (safeBitTest(key, x.b)) x = x.right;
else
x = x.left;

} while (p.b < x.b);


if (x.key.equals(key)) {
Node z;
Node y = head;
do {
// find the true parent (z) of
x
z = y;
if (safeBitTest(key, y.b)) y = y.right;
else
y = y.left;
} while (y != x);
if (x == p) {
// case 1: remove (leaf node) x
Node c;
// child of x
if (safeBitTest(key, x.b)) c = x.left;
else
c = x.right;
if (safeBitTest(key, z.b)) z.right = c;
else
z.left = c;
}
else {
// case 2: p replaces (internal
node) x
Node c;
// child
if (safeBitTest(key,
else
if (safeBitTest(key,
else
if (safeBitTest(key,
else
p.left = x.left;
p.right = x.right;
p.b = x.b;

of p
p.b)) c = p.left;
c = p.right;
g.b)) g.right = c;
g.left = c;
z.b)) z.right = p;
z.left = p;

}
count--;
}
}
/**
* Returns <code>true</code> if the key-value pair,
specified by the given
* key, exists within the symbol table.
* @param key the key
* @return <code>true</code> if this symbol table
contains the given
* <code>key</code> and <code>false</code> otherwise
* @throws NullPointerException if <code>key</code> is
<code>null</code>
* @throws IllegalArgumentException if <code>key</code>
is the empty string.
*/

public boolean contains(String key) {


return get(key) != null;
}
/**
* Returns <code>true</code> if the symbol table is
empty.
* @return <code>true</code> if this symbol table is
empty and
* <code>false</code> otherwise
*/
boolean isEmpty() {
return count == 0;
}
/**
* Returns
symbol table.
* @return
symbol table
*/
int size()
return
}

the number of key-value pairs within the


the number of key-value pairs within this
{
count;

/**
* Returns all keys in the symbol table as an
<code>Iterable</code>.
* To iterate over all of the keys in the symbol table
named
* <code>st</code>, use the foreach notation:
* <code>for (Key key : st.keys())</code>.
* @return all keys in the sybol table as an
<code>Iterable</code>
*/
public Iterable<String> keys() {
Queue<String> queue = new Queue<String>();
if (head.left != head) keys(head.left, 0, queue);
if (head.right != head) keys(head.right, 0, queue);
return queue;
}
private void keys(Node x, int b, Queue<String> queue) {
if (x.b > b) {
keys(x.left, x.b, queue);
queue.enqueue(x.key);
keys(x.right, x.b, queue);

}
}
/* The safeBitTest function logically appends a
terminating sequence (when
* required) to extend (logically) the string beyond
its length.
*
* The inner loops of the get and put methods flow much
better when they
* are not concerned with the lengths of strings, so a
trick is employed to
* allow the get and put methods to view every string
as an "infinite"
* sequence of bits. Logically, every string gets a
'\uffff' character,
* followed by an "infinite" sequence of '\u0000'
characters, appended to
* the end.
*
* Note that the '\uffff' character serves to mark the
end of the string,
* and it is necessary. Simply padding with '\u0000' is
insufficient to
* make all unique Unicode strings "look" unique to the
get and put methods
* (because these methods do not regard string
lengths).
*/
private static boolean safeBitTest(String key, int b) {
if (b < key.length() * 16)
return bitTest(key,
b) != 0;
if (b > key.length() * 16 + 15) return false;
//
padding
/* 16 bits of 0xffff */
return true;
//
end marker
}
private static int bitTest(String key, int b) {
return (key.charAt(b >>> 4) >>> (b & 0xf)) & 1;
}
/* Like the safeBitTest function, the safeCharAt
function makes every
* string look like an "infinite" sequence of
characters. Logically, every

* string gets a '\uffff' character, followed by an


"infinite" sequence of
* '\u0000' characters, appended to the end.
*/
private static int safeCharAt(String key, int i) {
if (i < key.length()) return key.charAt(i);
if (i > key.length()) return 0x0000;
//
padding
else
return 0xffff;
//
end marker
}
/* For efficiency's sake, the firstDifferingBit
function compares entire
* characters first, and then considers the individual
bits (once it finds
* two characters that do not match). Also, the least
significant bits of
* an individual character are examined first. There
are many Unicode
* alphabets where most (if not all) of the "action"
occurs in the least
* significant bits.
*
* Notice that the very first character comparison
excludes the
* least-significant bit. The firstDifferingBit
function must never return
* zero; otherwise, a node would become created as a
child to the head
* (sentinel) node that matches the bit-index value
(zero) stored in the
* head node. This would violate the invariant that
bit-index values
* increase as you descend into the trie.
*/
private static int firstDifferingBit(String k1, String
k2) {
int i = 0;
int c1 = safeCharAt(k1, 0) & ~1;
int c2 = safeCharAt(k2, 0) & ~1;
if (c1 == c2) {
i = 1;
while (safeCharAt(k1, i) == safeCharAt(k2, i))
i++;
c1 = safeCharAt(k1, i);
c2 = safeCharAt(k2, i);

}
int b = 0;
while (((c1 >>> b) & 1) == ((c2 >>> b) & 1)) b++;
return i * 16 + b;
}
/**
* Unit tests the <code>PatriciaST</code> data type.
* This test fixture runs a series of tests on a
randomly generated dataset.
* You may specify up to two integer parameters on the
command line. The
* first parameter indicates the size of the dataset.
The second parameter
* controls the number of passes (a new random dataset
becomes generated at
* the start of each pass).
*/
public static void main(String[] args) {
PatriciaST<Integer> st = new PatriciaST<Integer>();
int limitItem = 1000000;
int limitPass = 1;
int countPass = 0;
boolean ok = true;
if (args.length > 0) limitItem =
Integer.parseInt(args[0]);
if (args.length > 1) limitPass =
Integer.parseInt(args[1]);
do {
String[] a = new String[limitItem];
int[]
v = new int[limitItem];
StdOut.printf("Creating dataset (%d
items)...\n", limitItem);
for (int i = 0; i < limitItem; i++) {
a[i] = Integer.toString(i, 16);
v[i] = i;
}
StdOut.printf("Shuffling...\n");
StdRandom.shuffle(v);
StdOut.printf("Adding (%d items)...\n",
limitItem);
for (int i = 0; i < limitItem; i++)

st.put(a[v[i]], v[i]);
int countKeys = 0;
StdOut.printf("Iterating...\n");
for (String key : st.keys()) countKeys++;
StdOut.printf("%d items iterated\n", countKeys);
if (countKeys != limitItem) ok = false;
if (countKeys != st.size()) ok = false;
StdOut.printf("Shuffling...\n");
StdRandom.shuffle(v);
int limitDelete = limitItem / 2;
StdOut.printf("Deleting (%d items)...\n",
limitDelete);
for (int i = 0; i < limitDelete; i++)
st.delete(a[v[i]]);
countKeys = 0;
StdOut.printf("Iterating...\n");
for (String key : st.keys()) countKeys++;
StdOut.printf("%d items iterated\n", countKeys);
if (countKeys != limitItem - limitDelete) ok =
false;
if (countKeys != st.size())

ok =

false;
int countDelete = 0;
int countRemain = 0;
StdOut.printf("Checking...\n");
for (int i = 0; i < limitItem; i++) {
if (i < limitDelete) {
if (!st.contains(a[v[i]])) countDelete+
+;
}
else {
int val = st.get(a[v[i]]);
if (val == v[i]) countRemain++;
}
}
StdOut.printf("%d items found and %d (deleted)
items missing\n",
countRemain, countDelete);
if (countRemain + countDelete != limitItem) ok =
false;
if (countRemain
!= st.size()) ok =
false;

if (st.isEmpty())

ok =

false;
StdOut.printf("Deleting the rest (%d
items)...\n",
limitItem - countDelete);
for (int i = countDelete; i < limitItem; i++)
st.delete(a[v[i]]);
if (!st.isEmpty()) ok = false;
countPass++;
if (ok) StdOut.printf("PASS %d TESTS
SUCCEEDED\n", countPass);
else
StdOut.printf("PASS %d TESTS FAILED\n",
countPass);
} while (ok && countPass < limitPass);
if (!ok) throw new java.lang.RuntimeException("TESTS
FAILED");
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Tue Jul 28 15:06:57 EDT 2015.
PatriciaSET.java
Below is the syntax highlighted version
of PatriciaSET.java from 9.9 Miscellaneous.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac PatriciaSET.java
* Execution:
java PatriciaSET
* Dependencies: StdOut.java StdRandom.java Queue.java
* Data files:
n/a
*
* A set implementation based on PATRICIA.
*
* % java PatriciaSET 1000000 1
* Creating dataset (1000000 items)...
* Shuffling...

*
*
*
*
*
*
*
*
*
*
*
*
*

Adding (1000000 items)...


Iterating...
1000000 items iterated
Shuffling...
Deleting (500000 items)...
Iterating...
500000 items iterated
Checking...
500000 items found and 500000 (deleted) items missing
Deleting the rest (500000 items)...
PASS 1 TESTS SUCCEEDED
%

***********************************************************
**************/
import java.util.Iterator;
/**
* The <code>PatriciaSET</code> class provides an
implementation of an
* unordered set, with the restriction that the items
(keys) are of class
* {@link java.lang.String}. It supports the usual
<em>add</em>,
* <em>contains</em>, <em>delete</em>, <em>size</em>, and
<em>is-empty</em>
* methods. It also provides an <em>iterator</em> method
for iterating over all
* the elements in the set.
* <p>
* This unordered set class implements PATRICIA (Practical
Algorithm to
* Retrieve Information Coded In Alphanumeric). In spite
of the acronym, string
* keys are not limited to alphanumeric content. A key may
possess any string
* value, with one exception: a zero-length string is not
permitted.
* <p>
* Unlike other generic set implementations that can
accept a parameterized key
* type, this set class can only accommodate keys of class
* {@link java.lang.String}. This unfortunate restriction
stems from a

* limitation in Java. Although Java provides excellent


support for generic
* programming, the current infrastructure somewhat limits
generic collection
* implementations to those that employ comparison-based
or hash-based methods.
* PATRICIA does not employ comparisons or hashing;
instead, it relies on
* bit-test operations. Because Java does not furnish any
generic abstractions
* (or implementations) for bit-testing the contents of an
object, providing
* support for generic keys using PATRICIA does not seem
practical.
* <p>
* PATRICIA is a variation of a trie, and it is often
classified as a
* space-optimized trie. In a classical trie, each level
represents a
* subsequent digit in a key. In PATRICIA, nodes only
exist to identify the
* digits (bits) that distinguish the individual keys
within the trie. Because
* PATRICIA uses a radix of two, each node has only two
children, like a binary
* tree. Also like a binary tree, the number of nodes,
within the trie, equals
* the number of keys. Consequently, some classify
PATRICIA as a tree.
* <p>
* The analysis of PATRICIA is complicated. The
theoretical wost-case
* performance for an <em>add</em>, <em>contains</em>, or
<em>delete</em>
* operation is <strong>O(N)</strong>, when
<strong>N</strong> is less than
* <strong>W</strong> (where <strong>W</strong> is the
length in bits of the
* longest key), and <strong>O(W)</strong>, when
<strong>N</strong> is greater
* than <strong>W</strong>. However, the worst case is
unlikely to occur with
* typical use. The average (and usual) performance of
PATRICIA is
* approximately <strong>~lg N</strong> for each
<em>add</em>,

* <em>contains</em>, or <em>delete</em> operation.


Although this appears to
* put PATRICIA on the same footing as binary trees, this
time complexity
* represents the number of single-bit test operations
(under PATRICIA), and
* not full-key comparisons (as required by binary trees).
After the single-bit
* tests conclude, PATRICIA requires just one full-key
comparison to confirm
* the existence (or absence) of the key (per
<em>add</em>, <em>contains</em>,
* or <em>delete</em> operation).
* <p>
* In practice, decent implementations of PATRICIA can
often outperform
* balanced binary trees, and even hash tables. Although
this particular
* 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,
* or in another programming language.
* <p>
* Other resources for PATRICIA:<br>
* Sedgewick, R. (1990) <i>Algorithms in C</i>, AddisonWesley<br>
* Knuth, D. (1973) <i>The Art of Computer
Programming</i>, Addison-Wesley<br>
*
* @author John Hentosh (based on an implementation by
Robert Sedgewick)
*/
public class PatriciaSET implements Iterable<String> {
private Node head;
private int count;
/* An inner Node class specifies the objects that hold
each key. The b
* value indicates the relevant bit position.
*/
private class Node {
private Node left, right;

private String key;


private int b;
public Node(String key, int b) {
this.key = key;
this.b = b;
}
};
/**
* Initializes an empty PATRICIA-based set.
*/
/* The constructor creates a head (sentinel) node that
contains a
* zero-length string.
*/
public PatriciaSET() {
head = new Node("", 0);
head.left = head;
head.right = head;
count = 0;
}
/**
* Adds the key to the set if it is not already
present.
* @param key the key to add
* @throws NullPointerException if <code>key</code> is
<code>null</code>
* @throws IllegalArgumentException if <code>key</code>
is the empty string.
*/
public void add(String key) {
if (key == null) throw new
NullPointerException("called add(null)");
if (key.length() == 0) throw new
IllegalArgumentException("invalid key");
Node p;
Node x = head;
do {
p = x;
if (safeBitTest(key, x.b)) x = x.right;
else
x = x.left;
} while (p.b < x.b);
if (!x.key.equals(key)) {
int b = firstDifferingBit(x.key, key);
x = head;

do {
p = x;
if (safeBitTest(key, x.b)) x = x.right;
else
x = x.left;
} while (p.b < x.b && x.b < b);
Node t = new Node(key, b);
if (safeBitTest(key, b)) {
t.left = x;
t.right = t;
}
else {
t.left = t;
t.right = x;
}
if (safeBitTest(key, p.b)) p.right = t;
else
p.left = t;
count++;
}
}
/**
* Does the set contain the given key?
* @param key the key
* @return <code>true</code> if the set contains
<code>key</code> and
* <code>false</code> otherwise
* @throws NullPointerException if <code>key</code> is
<code>null</code>
* @throws IllegalArgumentException if <code>key</code>
is the empty string.
*/
public boolean contains(String key) {
if (key == null) throw new
NullPointerException("called contains(null)");
if (key.length() == 0) throw new
IllegalArgumentException("invalid key");
Node p;
Node x = head;
do {
p = x;
if (safeBitTest(key, x.b)) x = x.right;
else
x = x.left;
} while (p.b < x.b);
return (x.key.equals(key));
}
/**

* Removes the key from the set if the key is present.


* @param key the key
* @throws NullPointerException if <code>key</code> is
<code>null</code>
* @throws IllegalArgumentException if <code>key</code>
is the empty string.
*/
public void delete(String key) {
if (key == null) throw new
NullPointerException("called delete(null)");
if (key.length() == 0) throw new
IllegalArgumentException("invalid key");
Node g;
// previous previous
(grandparent)
Node p = head;
// previous (parent)
Node x = head;
// node to delete
do {
g = p;
p = x;
if (safeBitTest(key, x.b)) x = x.right;
else
x = x.left;
} while (p.b < x.b);
if (x.key.equals(key)) {
Node z;
Node y = head;
do {
// find the true parent (z) of
x
z = y;
if (safeBitTest(key, y.b)) y = y.right;
else
y = y.left;
} while (y != x);
if (x == p) {
// case 1: remove (leaf node) x
Node c;
// child of x
if (safeBitTest(key, x.b)) c = x.left;
else
c = x.right;
if (safeBitTest(key, z.b)) z.right = c;
else
z.left = c;
}
else {
// case 2: p replaces (internal
node) x
Node c;
// child of p
if (safeBitTest(key, p.b)) c = p.left;
else
c = p.right;
if (safeBitTest(key, g.b)) g.right = c;
else
g.left = c;
if (safeBitTest(key, z.b)) z.right = p;
else
z.left = p;

p.left = x.left;
p.right = x.right;
p.b = x.b;
}
count--;
}
}
/**
* Is the set empty?
* @return <code>true</code> if the set is empty, and
<code>false</code>
* otherwise
*/
boolean isEmpty() {
return count == 0;
}
/**
* Returns
* @return
*/
int size()
return
}

the number of keys in the set.


the number of keys in the set
{
count;

/**
* Returns all of the keys in the set, as an iterator.
* To iterate over all of the keys in a set named
<code>set</code>, use the
* foreach notation: <code>for (Key key : set)</code>.
* @return an iterator to all of the keys in the set
*/
public Iterator<String> iterator() {
Queue<String> queue = new Queue<String>();
if (head.left != head) collect(head.left, 0,
queue);
if (head.right != head) collect(head.right, 0,
queue);
return queue.iterator();
}
private void collect(Node x, int b, Queue<String> queue)
{
if (x.b > b) {
collect(x.left, x.b, queue);
queue.enqueue(x.key);

collect(x.right, x.b, queue);


}
}
/**
* Returns a string representation of this set.
* @return a string representation of this set, with
the keys separated
* by single spaces
*/
public String toString() {
StringBuilder s = new StringBuilder();
for (String key : this) s.append(key + " ");
if (s.length() > 0) s.deleteCharAt(s.length() - 1);
return s.toString();
}
/* The safeBitTest function logically appends a
terminating sequence (when
* required) to extend (logically) the string beyond
its length.
*
* The inner loops of the get and put methods flow much
better when they
* are not concerned with the lengths of strings, so a
trick is employed to
* allow the get and put methods to view every string
as an "infinite"
* sequence of bits. Logically, every string gets a
'\uffff' character,
* followed by an "infinite" sequence of '\u0000'
characters, appended to
* the end.
*
* Note that the '\uffff' character serves to mark the
end of the string,
* and it is necessary. Simply padding with '\u0000' is
insufficient to
* make all unique Unicode strings "look" unique to the
get and put methods
* (because these methods do not regard string
lengths).
*/
private static boolean safeBitTest(String key, int b) {
if (b < key.length() * 16)
return bitTest(key,
b) != 0;

if (b > key.length() * 16 + 15) return false;

//

padding
/* 16 bits of 0xffff */
end marker
}

return true;

//

private static int bitTest(String key, int b) {


return (key.charAt(b >>> 4) >>> (b & 0xf)) & 1;
}
/* Like the safeBitTest function, the safeCharAt
function makes every
* string look like an "infinite" sequence of
characters. Logically, every
* string gets a '\uffff' character, followed by an
"infinite" sequence of
* '\u0000' characters, appended to the end.
*/
private static int safeCharAt(String key, int i) {
if (i < key.length()) return key.charAt(i);
if (i > key.length()) return 0x0000;
//
padding
else
return 0xffff;
//
end marker
}
/* For efficiency's sake, the firstDifferingBit
function compares entire
* characters first, and then considers the individual
bits (once it finds
* two characters that do not match). Also, the least
significant bits of
* an individual character are examined first. There
are many Unicode
* alphabets where most (if not all) of the "action"
occurs in the least
* significant bits.
*
* Notice that the very first character comparison
excludes the
* least-significant bit. The firstDifferingBit
function must never return
* zero; otherwise, a node would become created as a
child to the head
* (sentinel) node that matches the bit-index value
(zero) stored in the

* head node. This would violate the invariant that


bit-index values
* increase as you descend into the trie.
*/
private static int firstDifferingBit(String k1, String
k2) {
int i = 0;
int c1 = safeCharAt(k1, 0) & ~1;
int c2 = safeCharAt(k2, 0) & ~1;
if (c1 == c2) {
i = 1;
while (safeCharAt(k1, i) == safeCharAt(k2, i))
i++;
c1 = safeCharAt(k1, i);
c2 = safeCharAt(k2, i);
}
int b = 0;
while (((c1 >>> b) & 1) == ((c2 >>> b) & 1)) b++;
return i * 16 + b;
}
/**
* Unit tests the <code>PatriciaSET</code> data type.
* This test fixture runs a series of tests on a
randomly generated dataset.
* You may specify up to two integer parameters on the
command line. The
* first parameter indicates the size of the dataset.
The second parameter
* controls the number of passes (a new random dataset
becomes generated at
* the start of each pass).
*/
public static void main(String[] args) {
PatriciaSET set = new PatriciaSET();
int limitItem = 1000000;
int limitPass = 1;
int countPass = 0;
boolean ok = true;
if (args.length > 0) limitItem =
Integer.parseInt(args[0]);
if (args.length > 1) limitPass =
Integer.parseInt(args[1]);
do {
String[] a = new String[limitItem];

StdOut.printf("Creating dataset (%d


items)...\n", limitItem);
for (int i = 0; i < limitItem; i++)
a[i] = Integer.toString(i, 16);
StdOut.printf("Shuffling...\n");
StdRandom.shuffle(a);
StdOut.printf("Adding (%d items)...\n",
limitItem);
for (int i = 0; i < limitItem; i++)
set.add(a[i]);
int countItems = 0;
StdOut.printf("Iterating...\n");
for (String key : set) countItems++;
StdOut.printf("%d items iterated\n",
countItems);
if (countItems != limitItem) ok = false;
if (countItems != set.size()) ok = false;
StdOut.printf("Shuffling...\n");
StdRandom.shuffle(a);
int limitDelete = limitItem / 2;
StdOut.printf("Deleting (%d items)...\n",
limitDelete);
for (int i = 0; i < limitDelete; i++)
set.delete(a[i]);
countItems = 0;
StdOut.printf("Iterating...\n");
for (String key : set) countItems++;
StdOut.printf("%d items iterated\n",
countItems);
if (countItems != limitItem - limitDelete) ok =
false;
if (countItems != set.size())
ok =
false;
int countDelete = 0;
int countRemain = 0;
StdOut.printf("Checking...\n");
for (int i = 0; i < limitItem; i++) {
if (i < limitDelete) {
if (!set.contains(a[i])) countDelete++;

}
else {
if (set.contains(a[i])) countRemain++;
}
}
StdOut.printf("%d items found and %d (deleted)
items missing\n",
countRemain, countDelete);
if (countRemain + countDelete != limitItem) ok
= false;
if (countRemain
!= set.size()) ok
= false;
if (set.isEmpty())
ok
= false;
StdOut.printf("Deleting the rest (%d
items)...\n",
limitItem - countDelete);
for (int i = countDelete; i < limitItem; i++)
set.delete(a[i]);
if (!set.isEmpty()) ok = false;
countPass++;
if (ok) StdOut.printf("PASS %d TESTS
SUCCEEDED\n", countPass);
else
StdOut.printf("PASS %d TESTS FAILED\n",
countPass);
} while (ok && countPass < limitPass);
if (!ok) throw new java.lang.RuntimeException("TESTS
FAILED");
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Tue Jul 28 15:06:57 EDT 2015.
MultiwayMinPQ.java
Below is the syntax highlighted version
of MultiwayMinPQ.java from 9.9 Miscellaneous.
the Javadoc.

import java.util.Iterator;

Here is

import java.util.Comparator;
import java.util.NoSuchElementException;
/**
* The MultiwayMinPQ class represents a priority queue of
generic keys.
* It supports the usual insert and delete-the-minimum
operations.
* It also supports methods for peeking at the minimum
key,
* testing if the priority queue is empty, and iterating
through
* the keys.
* It is possible to build the priority queue using a
Comparator.
* If not, the natural order relation between the keys
will be used.
*
* This implementation uses a multiway heap.
* For simplified notations, logarithm in base d will be
referred as log-d
* The delete-the-minimum operation takes time
proportional to d*log-d(n)
* The insert takes time proportional to log-d(n)
* The is-empty, min-key and size operations take constant
time.
* Constructor takes time proportional to the specified
capacity.
*
* @author Tristan Claverie
*/
public class MultiwayMinPQ<Key> implements Iterable<Key> {
private final int d;
//Dimension of the heap
private int n;
//Number of keys currently in the heap
private int order;
//Number
of levels of the tree
private Key[] keys;
//Array
of keys
private final Comparator<Key> comp;
//Comparator
over the keys
/**
* Initializes an empty priority queue

* Worst case is O(d)


* @param D dimension of the heap
* @throws java.lang.IllegalArgumentException if D < 2
*/
public MultiwayMinPQ(int D) {
if (D < 2) throw new
IllegalArgumentException("Dimension should be 2 or over");
this.d = D;
order = 1;
keys = (Key[]) new Comparable[D << 1];
comp = new MyComparator();
}
/**
* Initializes an empty priority queue
* Worst case is O(d)
* @param D dimension of the heap
* @param C a Comparator over the keys
* @throws java.lang.IllegalArgumentException if D < 2
*/
public MultiwayMinPQ(Comparator<Key> C, int D) {
if (D < 2) throw new
IllegalArgumentException("Dimension should be 2 or over");
this.d = D;
order = 1;
keys = (Key[]) new Comparable[D << 1];
comp = C;
}
/**
* Initializes a priority queue with given indexes
* Worst case is O(n*log-d(n))
* @param D dimension of the heap
* @param a an array of keys
* @throws java.lang.IllegalArgumentException if D < 2
*/
public MultiwayMinPQ(Key[] a, int D) {
if (D < 2) throw new
IllegalArgumentException("Dimension should be 2 or over");
this.d = D;
order = 1;
keys = (Key[]) new Comparable[D << 1];
comp = new MyComparator();
for (Key k : a) insert(k);
}
/**
* Initializes a priority queue with given indexes

* Worst case is O(a*log-d(n))


* @param D dimension of the heap
* @param C a Comparator over the keys
* @param a an array of keys
* @throws java.lang.IllegalArgumentException if D < 2
*/
public MultiwayMinPQ(Comparator<Key> C, Key[] a, int
D) {
if (D < 2) throw new
IllegalArgumentException("Dimension should be 2 or over");
this.d = D;
order = 1;
keys = (Key[]) new Comparable[D << 1];
comp = C;
for (Key k : a) insert(k);
}
/**
* Whether the priority queue is empty
* Worst case is O(1)
* @return true if the priority queue is empty, false
if not
*/
public boolean isEmpty() {
return n == 0;
}
/**
* Number of elements currently on the priority queue
* Worst case is O(1)
* @return the number of elements on the priority
queue
*/
public int size() {
return n;
}
/**
* Puts a Key on the priority queue
* Worst case is O(log-d(n))
* @param key a Key
*/
public void insert(Key key) {
keys[n+d] = key;
swim(n++);
if (n == keys.length-d) {
resize(getN(order+1)+d);

order++;
}
}
/**
* Gets the minimum key currently in the queue
* Worst case is O(1)
* @throws java.util.NoSuchElementException if the
priority queue is empty
* @return the minimum key currently in the priority
queue
*/
public Key minKey() {
if (isEmpty()) throw new
NoSuchElementException("Priority queue is empty");
return keys[d];
}
/**
* Deletes the minimum key
* Worst case is O(d*log-d(n))
* @throws java.util.NoSuchElementException if the
priority queue is empty
* @return the minimum key
*/
public Key delMin() {
if (isEmpty()) throw new
NoSuchElementException("Priority queue is empty");
exch(0, --n);
sink(0);
Key min = keys[n+d];
keys[n+d] = null;
int number = getN(order-2);
if(order > 1 && n == number) {
resize(number+(int)Math.pow(d, order1)+d);
order--;
}
return min;
}
/***************************
* General helper functions
**************************/
//Compares two keys
private boolean greater(int x, int y) {

int i = x+d, j = y+d;


if (keys[i] == null) return false;
if (keys[j] == null) return true;
return comp.compare(keys[i], keys[j]) > 0;
}
//Exchanges the position of two keys
private void exch(int x, int y) {
int i = x+d, j = y+d;
Key swap = keys[i];
keys[i] = keys[j];
keys[j] = swap;
}
//Gets the maximum number of keys in the heap, given
the number of levels of the tree
private int getN(int order) {
return (1-((int)Math.pow(d, order+1)))/(1-d);
}
/***************************
* Functions for moving upward or downward
**************************/
//Moves upward
private void swim(int i) {
if (i > 0 && greater((i-1)/d, i)) {
exch(i, (i-1)/d);
swim((i-1)/d);
}
}
//Moves downward
private void sink(int i) {
int child = d*i+1;
if (child >= n) return;
int min = minChild(i);
while (min < n && greater(i, min)) {
exch(i, min);
i = min;
min = minChild(i);
}
}
/***************************
* Deletes the minimum child
**************************/

//Return the minimum child of i


private int minChild(int i) {
int loBound = d*i+1, hiBound = d*i+d;
int min = loBound;
for (int cur = loBound; cur <= hiBound; cur++)
{
if (cur < n && greater(min, cur)) min =
cur;
}
return min;
}
/***************************
* Resize the priority queue
**************************/
//Resizes the array containing the keys
//If the heap is full, it adds one floor
//If the heap has two floors empty, it removes one
private void resize(int N) {
Key[] array = (Key[]) new Comparable[N];
for (int i = 0; i < Math.min(keys.length,
array.length); i++) {
array[i] = keys[i];
keys[i] = null;
}
keys = array;
}
/***************************
* Iterator
**************************/
/**
* Gets an Iterator over the keys in the priority
queue in ascending order
* The Iterator does not implement the remove()
method
* iterator() : Worst case is O(n)
* next() : Worst case is O(d*log-d(n))
* hasNext() :
Worst case is O(1)
* @return an Iterator over the keys in the priority
queue in ascending order
*/
public Iterator<Key> iterator() {
return new MyIterator();
}

//Constructs an Iterator over the keys in linear time


private class MyIterator implements Iterator<Key> {
MultiwayMinPQ<Key> data;
public MyIterator() {
data = new MultiwayMinPQ<Key>(comp, d);
data.keys = (Key[]) new
Comparable[keys.length];
data.n = n;
for (int i = 0; i < keys.length; i++) {
data.keys[i] = keys[i];
}
}
public boolean hasNext() {
return !data.isEmpty();
}
public Key next() {
return data.delMin();
}
public void remove() {
throw new
UnsupportedOperationException();
}
}
/***************************
* Comparator
**************************/
//default Comparator
private class MyComparator implements Comparator<Key>
{
@Override
public int compare(Key key1, Key key2) {
return ((Comparable<Key>)
key1).compareTo(key2);
}
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Sat May 2 05:42:54 EDT 2015.

IndexMultiwayMinPQ.java
Below is the syntax highlighted version
of IndexMultiwayMinPQ.java from 9.9 Miscellaneous.
is the Javadoc.

Here

import java.util.Comparator;
import java.util.Iterator;
import java.util.NoSuchElementException;
/**
* The IndexMultiwayMinPQ class represents an indexed
priority queue of generic keys.
* It supports the usual insert and delete-the-minimum
operations,
* along with delete and change-the-key methods.
* In order to let the client refer to keys on the
priority queue,
* an integer between 0 and N-1 is associated with each
key ; the client
* uses this integer to specify which key to delete or
change.
* It also supports methods for peeking at the minimum
key,
* testing if the priority queue is empty, and iterating
through
* the keys.
*
* This implementation uses a multiway heap along with an
array to associate
* keys with integers in the given range.
* For simplified notations, logarithm in base d will be
referred as log-d
* The delete-the-minimum, delete, change-key and
increase-key operations
* take time proportional to d*log-d(n)
* The insert and decrease-key take time proportional to
log-d(n)
* The is-empty, min-index, min-key, size, contains and
key-of operations take constant time.
* Construction takes time proportional to the specified
capacity.
*

* The arrays used in this structure have the first d


indices empty,
* it apparently helps with caching effects.
*
* @author Tristan Claverie
*/
public class IndexMultiwayMinPQ<Key> implements
Iterable<Integer> {
private final int d;
//Dimension of the heap
private int n;
//Number of keys currently in the queue
private int nmax;
//Maximum number of items in the queue
private int[] pq;
//Multiway heap
private int[] qp;
//Inverse of pq : qp[pq[i]] = pq[qp[i]] = i
private Key[] keys;
//keys[i] = priority of i
private final Comparator<Key> comp; //Comparator over
the keys
/**
* Initializes an empty indexed priority queue with
indices between 0 and N-1
* Worst case is O(n)
* @param N number of keys in the priority queue, index
from 0 to N-1
* @param D dimension of the heap
* @throws java.lang.IllegalArgumentException if N < 0
* @throws java.lang.IllegalArgumentException if D < 2
*/
public IndexMultiwayMinPQ(int N, int D) {
if (N < 0) throw new
IllegalArgumentException("Maximum number of elements cannot
be negative");
if (D < 2) throw new
IllegalArgumentException("Dimension should be 2 or over");
this.d = D;
nmax = N;
pq = new int[nmax+D];
qp = new int[nmax+D];
keys = (Key[]) new Comparable[nmax+D];
for (int i = 0; i < nmax+D; qp[i++] = -1);

comp = new MyComparator();


}
/**
* Initializes an empty indexed priority queue with
indices between 0 and N-1
* Worst case is O(n)
* @param N number of keys in the priority queue, index
from 0 to N-1
* @param D dimension of the heap
* @param C a Comparator over the keys
* @throws java.lang.IllegalArgumentException if N < 0
* @throws java.lang.IllegalArgumentException if D < 2
*/
public IndexMultiwayMinPQ(int N, Comparator<Key> C,
int D) {
if (N < 0) throw new
IllegalArgumentException("Maximum number of elements cannot
be negative");
if (D < 2) throw new
IllegalArgumentException("Dimension should be 2 or over");
this.d = D;
nmax = N;
pq = new int[nmax+D];
qp = new int[nmax+D];
keys = (Key[]) new Comparable[nmax+D];
for (int i = 0; i < nmax+D; qp[i++] = -1);
comp = C;
}
/**
* Whether the priority queue is empty
* Worst case is O(1)
* @return true if the priority queue is empty, false
if not
*/
public boolean isEmpty() {
return n == 0;
}
/**
* Does the priority queue contains the index i ?
* Worst case is O(1)
* @param i an index
* @throws java.lang.IndexOutOfBoundsException if the
specified index is invalid

* @return true if i is on the priority queue, false


if not
*/
public boolean contains(int i) {
if (i < 0 ||i >= nmax) throw new
IndexOutOfBoundsException();
return qp[i+d] != -1;
}
/**
* Number of elements currently on the priority queue
* Worst case is O(1)
* @return the number of elements on the priority
queue
*/
public int size() {
return n;
}
/**
* Associates a key with an index
* Worst case is O(log-d(n))
* @param i an index
* @param key a Key associated with i
* @throws java.lang.IndexOutOfBoundsException if the
specified index is invalid
* @throws java.util.IllegalArgumentException if the
index is already in the queue
*/
public void insert(int i, Key key) {
if (i < 0 || i >= nmax) throw new
IndexOutOfBoundsException();
if (contains(i)) throw new
IllegalArgumentException("Index already there");
keys[i+d] = key;
pq[n+d] = i;
qp[i+d] = n;
swim(n++);
}
/**
* Gets the index associated with the minimum key
* Worst case is O(1)
* @throws java.util.NoSuchElementException if the
priority queue is empty
* @return the index associated with the minimum key
*/

public int minIndex() {


if (isEmpty()) throw new
NoSuchElementException("Priority queue is empty");
return pq[d];
}
/**
* Gets the minimum key currently in the queue
* Worst case is O(1)
* @throws java.util.NoSuchElementException if the
priority queue is empty
* @return the minimum key currently in the priority
queue
*/
public Key minKey() {
if (isEmpty()) throw new
NoSuchElementException("Priority queue is empty");
return keys[pq[d]+d];
}
/**
* Deletes the minimum key
* Worst case is O(d*log-d(n))
* @throws java.util.NoSuchElementException if the
priority queue is empty
* @return the index associated with the minimum key
*/
public int delMin() {
if (isEmpty()) throw new
NoSuchElementException("Priority queue is empty");
int min = pq[d];
exch(0, --n);
sink(0);
qp[min+d] = -1;
keys[pq[n+d]+d] = null;
pq[n+d] = -1;
return min;
}
/**
* Gets the key associated with index i
* Worst case is O(1)
* @param i an index
* @throws java.lang.IndexOutOfBoundsException if the
specified index is invalid
* @throws java.util.IllegalArgumentException if the
index is not in the queue

* @return the key associated with index i


*/
public Key keyOf(int i) {
if (i < 0 || i >= nmax) throw new
IndexOutOfBoundsException();
if (! contains(i)) throw new
NoSuchElementException("Specified index is not in the
queue");
return keys[i+d];
}
/**
* Changes the key associated with index i to the
given key
* If the given key is greater, Worst case is
O(d*log-d(n))
* If the given key is lower,
Worst case is O(logd(n))
* @param i an index
* @param key the key to associate with i
* @throws java.lang.IndexOutOfBoundsException if the
specified index is invalid
* @throws java.util.IllegalArgumentException if the
index has no key associated with
*/
public void changeKey(int i, Key key) {
if (i < 0 || i >= nmax) throw new
IndexOutOfBoundsException();
if (! contains(i)) throw new
NoSuchElementException("Specified index is not in the
queue");
Key tmp = keys[i+d];
keys[i+d] = key;
if (comp.compare(key, tmp) <= 0) {
swim(qp[i+d]);}
else
{
sink(qp[i+d]);}
}
/**
* Decreases the key associated with index i to the
given key
* Worst case is O(log-d(n))
* @param i an index
* @param key the key to associate with i
* @throws java.lang.IndexOutOfBoundsException if the
specified index is invalid

* @throws java.util.NoSuchElementException if the


index has no key associated with
* @throws java.util.IllegalArgumentException if the
given key is greater than the current key
*/
public void decreaseKey(int i, Key key) {
if (i < 0 || i >=nmax) throw new
IndexOutOfBoundsException();
if (! contains(i)) throw new
NoSuchElementException("Specified index is not in the
queue");
if (comp.compare(keys[i+d], key) <= 0) throw
new IllegalArgumentException("Calling with this argument
would not decrease the Key");
keys[i+d] = key;
swim(qp[i+d]);
}
/**
* Increases the key associated with index i to the
given key
* Worst case is O(d*log-d(n))
* @param i an index
* @param key the key to associate with i
* @throws java.lang.IndexOutOfBoundsException if the
specified index is invalid
* @throws java.util.NoSuchElementException if the
index has no key associated with
* @throws java.util.IllegalArgumentException if the
given key is lower than the current key
*/
public void increaseKey(int i, Key key) {
if (i < 0 || i >=nmax) throw new
IndexOutOfBoundsException();
if (! contains(i)) throw new
NoSuchElementException("Specified index is not in the
queue");
if (comp.compare(keys[i+d], key) >= 0) throw
new IllegalArgumentException("Calling with this argument
would not increase the Key");
keys[i+d] = key;
sink(qp[i+d]);
}
/**
* Deletes the key associated to the given index
* Worst case is O(d*log-d(n))

* @param i an index
* @throws java.lang.IndexOutOfBoundsException if the
specified index is invalid
* @throws java.util.NoSuchElementException if the
given index has no key associated with
*/
public void delete(int i) {
if (i < 0 || i >= nmax) throw new
IndexOutOfBoundsException();
if (! contains(i)) throw new
NoSuchElementException("Specified index is not in the
queue");
int idx = qp[i+d];
exch(idx, --n);
swim(idx);
sink(idx);
keys[i+d] = null;
qp[i+d] = -1;
}
/***************************
* General helper functions
**************************/
//Compares two keys
private boolean greater(int i, int j) {
return comp.compare(keys[pq[i+d]+d],
keys[pq[j+d]+d]) > 0;
}
//Exchanges two keys
private void exch(int x, int y) {
int i = x+d, j = y+d;
int swap = pq[i];
pq[i] = pq[j];
pq[j] = swap;
qp[pq[i]+d] = x;
qp[pq[j]+d] = y;
}
/***************************
* Functions for moving upward or downward
**************************/
//Moves upward
private void swim(int i) {
if (i > 0 && greater((i-1)/d, i)) {
exch(i, (i-1)/d);

swim((i-1)/d);
}
}
//Moves downward
private void sink(int i) {
if (d*i+1 >= n) return;
int min = minChild(i);
while (min < n && greater(i, min)) {
exch(i, min);
i = min;
min = minChild(i);
}
}
/***************************
* Deletes the minimum child
**************************/
//Return the minimum child of i
private int minChild(int i) {
int loBound = d*i+1, hiBound = d*i+d;
int min = loBound;
for (int cur = loBound; cur <= hiBound; cur++)
{
if (cur < n && greater(min, cur)) min =
cur;
}
return min;
}
/***************************
* Iterator
**************************/
/**
* Gets an Iterator over the indexes in the priority
queue in ascending order
* The Iterator does not implement the remove()
method
* iterator() : Worst case is O(n)
* next() : Worst case is O(d*log-d(n))
* hasNext() :
Worst case is O(1)
* @return an Iterator over the indexes in the
priority queue in ascending order
*/
public Iterator<Integer> iterator() {

return new MyIterator();


}
//Constructs an Iterator over the indices in linear
time
private class MyIterator implements Iterator<Integer>
{
IndexMultiwayMinPQ<Key> clone;
public MyIterator() {
clone = new
IndexMultiwayMinPQ<Key>(nmax, comp, d);
for (int i = 0; i < n; i++) {
clone.insert(pq[i+d], keys[pq[i+d]
+d]);
}
}
public boolean hasNext() {
return !clone.isEmpty();
}
public Integer next() {
return clone.delMin();
}
public void remove() {
throw new
UnsupportedOperationException();
}
}
/***************************
* Comparator
**************************/
//default Comparator
private class MyComparator implements Comparator<Key>
{
@Override
public int compare(Key key1, Key key2) {
return ((Comparable<Key>)
key1).compareTo(key2);
}
}
}

Copyright 20022010, Robert Sedgewick and Kevin Wayne.


Last updated: Sat May 2 05:42:54 EDT 2015.
BinomialMinPQ.java
Below is the syntax highlighted version
of BinomialMinPQ.java from 9.9 Miscellaneous.
the Javadoc.

Here is

import java.util.Iterator;
import java.util.Comparator;
import java.util.NoSuchElementException;
/**
* The BinomialMinPQ class represents a priority queue of
generic keys.
* It supports the usual insert and delete-the-minimum
operations,
* along with the merging of two heaps together.
* It also supports methods for peeking at the minimum
key,
* testing if the priority queue is empty, and iterating
through
* the keys.
* It is possible to build the priority queue using a
Comparator.
* If not, the natural order relation between the keys
will be used.
*
* This implementation uses a binomial heap.
* The insert, delete-the-minimum, union, min-key
* and size operations take logarithmic time.
* The is-empty and constructor operations take constant
time.
*
* @author Tristan Claverie
*/
public class BinomialMinPQ<Key> implements Iterable<Key> {
private Node head;
//head
of the list of roots
private final Comparator<Key> comp;
//Comparator
over the keys
//Represents a Node of a Binomial Tree

private class Node {


Key key;
//Key contained by the Node
int order;
//The order of the Binomial Tree rooted by this Node
Node child, sibling;
//child
and sibling of this Node
}
/**
* Initializes an empty priority queue
* Worst case is O(1)
*/
public BinomialMinPQ() {
comp = new MyComparator();
}
/**
* Initializes an empty priority queue using the
given Comparator
* Worst case is O(1)
* @param C a comparator over the keys
*/
public BinomialMinPQ(Comparator<Key> C) {
comp = C;
}
/**
* Initializes a priority queue with given keys
* Worst case is O(n*log(n))
* @param a an array of keys
*/
public BinomialMinPQ(Key[] a) {
comp = new MyComparator();
for (Key k : a) insert(k);
}
/**
* Initializes a priority queue with given keys using
the given Comparator
* Worst case is O(n*log(n))
* @param C a comparator over the keys
* @param a an array of keys
*/
public BinomialMinPQ(Comparator<Key> C, Key[] a) {
comp = C;
for (Key k : a) insert(k);
}

/**
* Whether the priority queue is empty
* Worst case is O(1)
* @return true if the priority queue is empty, false
if not
*/
public boolean isEmpty() {
return head == null;
}
/**
* Number of elements currently on the priority queue
* Worst case is O(log(n))
* @throws java.lang.ArithmeticException if there are
more than 2^63-1 elements in the queue
* @return the number of elements on the priority
queue
*/
public int size() {
int result = 0, tmp;
for (Node node = head; node != null; node =
node.sibling) {
if (node.order > 30) { throw new
ArithmeticException("The number of elements cannot be
evaluated, but the priority queue is still valid."); }
tmp = 1 << node.order;
result |= tmp;
}
return result;
}
/**
* Puts a Key in the heap
* Worst case is O(log(n))
* @param key a Key
*/
public void insert(Key key) {
Node x = new Node();
x.key = key;
x.order = 0;
BinomialMinPQ<Key> H = new
BinomialMinPQ<Key>(); //The Comparator oh the H heap is not
used
H.head = x;
this.head = this.union(H).head;
}

/**
* Get the minimum key currently in the queue
* Worst case is O(log(n))
* @throws java.util.NoSuchElementException if the
priority queue is empty
* @return the minimum key currently in the priority
queue
*/
public Key minKey() {
if (isEmpty()) throw new
NoSuchElementException("Priority queue is empty");
Node min = head;
Node current = head;
while (current.sibling != null) {
min = (greater(min.key,
current.sibling.key)) ? current : min;
current = current.sibling;
}
return min.key;
}
/**
* Deletes the minimum key
* Worst case is O(log(n))
* @throws java.util.NoSuchElementException if the
priority queue is empty
* @return the minimum key
*/
public Key delMin() {
if(isEmpty()) throw new
NoSuchElementException("Priority queue is empty");
Node min = eraseMin();
Node x = (min.child == null) ? min : min.child;
if (min.child != null) {
min.child = null;
Node prevx = null, nextx = x.sibling;
while (nextx != null) {
x.sibling = prevx;
prevx = x;
x = nextx;nextx = nextx.sibling;
}
x.sibling = prevx;
BinomialMinPQ<Key> H = new
BinomialMinPQ<Key>();
H.head = x;
head = union(H).head;

}
return min.key;
}
/**
* Merges two Binomial heaps together
* This operation is destructive
* Worst case is O(log(n))
* @param heap a Binomial Heap to be merged with the
current heap
* @throws java.util.IllegalArgumentException if the
heap in parameter is null
* @return the union of two heaps
*/
public BinomialMinPQ<Key> union(BinomialMinPQ<Key>
heap) {
if (heap == null) throw new
IllegalArgumentException("Cannot merge a Binomial Heap with
null");
this.head = merge(new Node(), this.head,
heap.head).sibling;
Node x = this.head;
Node prevx = null, nextx = x.sibling;
while (nextx != null) {
if (x.order < nextx.order ||
(nextx.sibling != null &&
nextx.sibling.order == x.order)) {
prevx = x; x = nextx;
} else if (greater(nextx.key, x.key)) {
x.sibling = nextx.sibling;
link(nextx, x);
} else {
if (prevx == null) { this.head =
nextx; }
else { prevx.sibling = nextx; }
link(x, nextx);
x = nextx;
}
nextx = x.sibling;
}
return this;
}
/*************************************************
* General helper functions
************************************************/
//Compares two keys

private boolean greater(Key n, Key m) {


if (n == null) return false;
if (m == null) return true;
return comp.compare(n, m) > 0;
}
//Assuming root1 holds a greater key than root2,
root2 becomes the new root
private void link(Node root1, Node root2) {
root1.sibling = root2.child;
root2.child = root1;
root2.order++;
}
//Deletes and return the node containing the minimum
key
private Node eraseMin() {
Node min = head;
Node previous = new Node();
Node current = head;
while (current.sibling != null) {
if (greater(min.key,
current.sibling.key)) {
previous = current;
min = current.sibling;
}
current = current.sibling;
}
previous.sibling = min.sibling;
if (min == head) head = min.sibling;
return min;
}
/**************************************************
* Functions for inserting a key in the heap
*************************************************/
//Merges two root lists into one, there can be up to
2 Binomial Trees of same order
private Node merge(Node h, Node x, Node y) {
if (x == null && y == null) return h;
else if (x == null)
h.sibling =
merge(y, x, y.sibling);
else if (y == null)
h.sibling =
merge(x, x.sibling, y);
else if (x.order < y.order) h.sibling =
merge(x, x.sibling, y);

else
= merge(y, x, y.sibling);
return h;
}

h.sibling

/****************************************************
**************
* Iterator
***********************************************************
******/
/**
* Gets an Iterator over the keys in the priority
queue in ascending order
* The Iterator does not implement the remove()
method
* iterator() : Worst case is O(n)
* next() : Worst case is O(log(n))
* hasNext() :
Worst case is O(1)
* @return an Iterator over the keys in the priority
queue in ascending order
*/
public Iterator<Key> iterator() {
return new MyIterator();
}
private class MyIterator implements Iterator<Key> {
BinomialMinPQ<Key> data;
//Constructor clones recursively the elements
in the queue
//It takes linear time
public MyIterator() {
data = new BinomialMinPQ<Key>(comp);
data.head = clone(head, false, false,
null);
}
private Node clone(Node x, boolean isParent,
boolean isChild, Node parent) {
if (x == null) return null;
Node node = new Node();
node.key = x.key;
node.sibling = clone(x.sibling, false,
false, parent);
node.child = clone(x.child, false, true,
node);

return node;
}
public boolean hasNext() {
return !data.isEmpty();
}
public Key next() {
return data.delMin();
}
public void remove() {
throw new
UnsupportedOperationException();
}
}
/***************************
* Comparator
**************************/
//default Comparator
private class MyComparator implements Comparator<Key>
{
@Override
public int compare(Key key1, Key key2) {
return ((Comparable<Key>)
key1).compareTo(key2);
}
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Fri Jul 24 11:49:07 EDT 2015.
IndexBinomialMinPQ.java
Below is the syntax highlighted version
of IndexBinomialMinPQ.java from 9.9 Miscellaneous.
is the Javadoc.

import java.util.Comparator;
import java.util.Iterator;
import java.util.NoSuchElementException;

Here

/**
* The IndexBinomialMinPQ class represents an indexed
priority queue of generic keys.
* It supports the usual insert and delete-the-minimum
operations,
* along with delete and change-the-key methods.
* In order to let the client refer to keys on the
priority queue,
* an integer between 0 and N-1 is associated with each
key ; the client
* uses this integer to specify which key to delete or
change.
* It also supports methods for peeking at the minimum
key,
* testing if the priority queue is empty, and iterating
through
* the keys.
*
* This implementation uses a binomial heap along with an
array to associate
* keys with integers in the given range.
* The insert, delete-the-minimum, delete, change-key,
decrease-key,
* increase-key and size operations take logarithmic time.
* The is-empty, min-index, min-key, and key-of operations
take constant time.
* Construction takes time proportional to the specified
capacity.
*
* @author Tristan Claverie
*/
public class IndexBinomialMinPQ<Key> implements
Iterable<Integer> {
private Node<Key> head;
of the list of roots
private Node<Key>[] nodes;
of indexed Nodes of the heap
private int n;
//Maximum size of the tree
private final Comparator<Key> comparator;
//Comparator over the keys
//Represents a node of a Binomial Tree
private class Node<Key> {

//Head
//Array

Key key;

//Key contained

by the Node
int order;
the Binomial Tree rooted by this Node
int index;
associated with the Key
Node<Key> parent;
this Node
Node<Key> child, sibling;
sibling of this Node
}

//The order of
//Index
//parent of
//child and

/**
* Initializes an empty indexed priority queue with
indices between 0 and N-1
* Worst case is O(n)
* @param N number of keys in the priority queue, index
from 0 to N-1
* @throws java.lang.IllegalArgumentException if N < 0
*/
public IndexBinomialMinPQ(int N) {
if (N < 0) throw new
IllegalArgumentException("Cannot create a priority queue of
negative size");
comparator = new MyComparator();
nodes = (Node<Key>[]) new Node[N];
this.n = N;
}
/**
* Initializes an empty indexed priority queue with
indices between 0 and N-1
* Worst case is O(n)
* @param N number of keys in the priority queue, index
from 0 to N-1
* @param comparator a Comparator over the keys
* @throws java.lang.IllegalArgumentException if N < 0
*/
public IndexBinomialMinPQ(int N, Comparator<Key>
comparator) {
if (N < 0) throw new
IllegalArgumentException("Cannot create a priority queue of
negative size");
this.comparator = comparator;
nodes = (Node<Key>[]) new Node[N];
this.n = N;
}

/**
* Whether the priority queue is empty
* Worst case is O(1)
* @return true if the priority queue is empty, false
if not
*/
public boolean isEmpty() {
return head == null;
}
/**
* Does the priority queue contains the index i ?
* Worst case is O(1)
* @param i an index
* @throws java.lang.IndexOutOfBoundsException if the
specified index is invalid
* @return true if i is on the priority queue, false
if not
*/
public boolean contains(int i) {
if (i < 0 || i >= n) throw new
IndexOutOfBoundsException();
else return nodes[i] != null;
}
/**
* Number of elements currently on the priority queue
* Worst case is O(log(n))
* @return the number of elements on the priority
queue
*/
public int size() {
int result = 0, tmp;
for (Node<Key> node = head; node != null; node
= node.sibling) {
if (node.order > 30) { throw new
ArithmeticException("The number of elements cannot be
evaluated, but the priority queue is still valid."); }
tmp = 1 << node.order;
result |= tmp;
}
return result;
}
/**
* Associates a key with an index

* Worst case is O(log(n))


* @param i an index
* @param key a Key associated with i
* @throws java.lang.IndexOutOfBoundsException if the
specified index is invalid
* @throws java.util.IllegalArgumentException if the
index is already in the queue
*/
public void insert(int i, Key key) {
if (i < 0 || i >= n) throw new
IndexOutOfBoundsException();
if (contains(i)) throw new
IllegalArgumentException("Specified index is already in the
queue");
Node<Key> x = new Node<Key>();
x.key = key;
x.index = i;
x.order = 0;
nodes[i] = x;
IndexBinomialMinPQ<Key> H = new
IndexBinomialMinPQ<Key>();
H.head = x;
head = union(H).head;
}
/**
* Gets the index associated with the minimum key
* Worst case is O(log(n))
* @throws java.util.NoSuchElementException if the
priority queue is empty
* @return the index associated with the minimum key
*/
public int minIndex() {
if (isEmpty()) throw new
NoSuchElementException("Priority queue is empty");
Node<Key> min = head;
Node<Key> current = head;
while (current.sibling != null) {
min = (greater(min.key,
current.sibling.key)) ? current.sibling : min;
current = current.sibling;
}
return min.index;
}
/**

* Gets the minimum key currently in the queue


* Worst case is O(log(n))
* @throws java.util.NoSuchElementException if the
priority queue is empty
* @return the minimum key currently in the priority
queue
*/
public Key minKey() {
if (isEmpty()) throw new
NoSuchElementException("Priority queue is empty");
Node<Key> min = head;
Node<Key> current = head;
while (current.sibling != null) {
min = (greater(min.key,
current.sibling.key)) ? current.sibling : min;
current = current.sibling;
}
return min.key;
}
/**
* Deletes the minimum key
* Worst case is O(log(n))
* @throws java.util.NoSuchElementException if the
priority queue is empty
* @return the index associated with the minimum key
*/
public int delMin() {
if(isEmpty()) throw new
NoSuchElementException("Priority queue is empty");
Node<Key> min = eraseMin();
Node<Key> x = (min.child == null) ? min :
min.child;
if (min.child != null) {
min.child = null;
Node<Key> prevx = null, nextx =
x.sibling;
while (nextx != null) {
x.parent = null; // for garbage
collection
x.sibling = prevx;
prevx = x;
x = nextx;nextx = nextx.sibling;
}
x.parent = null;

x.sibling = prevx;
IndexBinomialMinPQ<Key> H = new
IndexBinomialMinPQ<Key>();
H.head = x;
head = union(H).head;
}
return min.index;
}
/**
* Gets the key associated with index i
* Worst case is O(1)
* @param i an index
* @throws java.lang.IndexOutOfBoundsException if the
specified index is invalid
* @throws java.util.IllegalArgumentException if the
index is not in the queue
* @return the key associated with index i
*/
public Key keyOf(int i) {
if (i < 0 || i >= n) throw new
IndexOutOfBoundsException();
if (!contains(i)) throw new
IllegalArgumentException("Specified index is not in the
queue");
return nodes[i].key;
}
/**
* Changes the key associated with index i to the
given key
* Worst case is O(log(n))
* @param i an index
* @param key the key to associate with i
* @throws java.lang.IndexOutOfBoundsException if the
specified index is invalid
* @throws java.util.IllegalArgumentException if the
index has no key associated with
*/
public void changeKey(int i, Key key) {
if (i < 0 || i >= n)
throw new
IndexOutOfBoundsException();
if (!contains(i))
throw new
IllegalArgumentException("Specified index is not in the
queue");

if (greater(nodes[i].key, key))

decreaseKey(i,

key);
else
increaseKey(i, key);
}
/**
* Decreases the key associated with index i to the
given key
* Worst case is O(log(n))
* @param i an index
* @param key the key to associate with i
* @throws java.lang.IndexOutOfBoundsException if the
specified index is invalid
* @throws java.util.NoSuchElementException if the
index has no key associated with
* @throws java.util.IllegalArgumentException if the
given key is greater than the current key
*/
public void decreaseKey(int i, Key key) {
if (i < 0 || i >= n)
throw new
IndexOutOfBoundsException();
if (!contains(i))
throw new
NoSuchElementException("Specified index is not in the
queue");
if (greater(key, nodes[i].key)) throw new
IllegalArgumentException("Calling with this argument would
not decrease the key");
Node<Key> x = nodes[i];
x.key = key;
swim(i);
}
/**
* Increases the key associated with index i to the
given key
* Worst case is O(log(n))
* @param i an index
* @param key the key to associate with i
* @throws java.lang.IndexOutOfBoundsException if the
specified index is invalid
* @throws java.util.NoSuchElementException if the
index has no key associated with
* @throws java.util.IllegalArgumentException if the
given key is lower than the current key
*/

public void increaseKey(int i, Key key) {


if (i < 0 || i >= n)
throw new
IndexOutOfBoundsException();
if (!contains(i))
throw new
NoSuchElementException("Specified index is not in the
queue");
if (greater(nodes[i].key, key)) throw new
IllegalArgumentException("Calling with this argument would
not increase the key");
delete(i);
insert(i, key);
}
/**
* Deletes the key associated the given index
* Worst case is O(log(n))
* @param i an index
* @throws java.lang.IndexOutOfBoundsException if the
specified index is invalid
* @throws java.util.NoSuchElementException if the
given index has no key associated with
*/
public void delete(int i) {
if (i < 0 || i >= n)
throw new
IndexOutOfBoundsException();
if (!contains(i))
throw new
NoSuchElementException("Specified index is not in the
queue");
toTheRoot(i);
Node<Key> x = erase(i);
if (x.child != null) {
Node<Key> y = x;
x = x.child;
y.child = null;
Node<Key> prevx = null, nextx =
x.sibling;
while (nextx != null) {
x.parent = null;
x.sibling = prevx;
prevx = x;
x = nextx; nextx = nextx.sibling;
}
x.parent = null;
x.sibling = prevx;

IndexBinomialMinPQ<Key> H = new
IndexBinomialMinPQ<Key>();
H.head = x;
head = union(H).head;
}
}
/*************************************************
* General helper functions
************************************************/
//Compares two keys
private boolean greater(Key n, Key m) {
if (n == null) return false;
if (m == null) return true;
return comparator.compare(n, m) > 0;
}
//Exchanges the positions of two nodes
private void exchange(Node<Key> x, Node<Key> y) {
Key tempKey = x.key; x.key = y.key; y.key =
tempKey;
int tempInt = x.index; x.index = y.index;
y.index = tempInt;
nodes[x.index] = x;
nodes[y.index] = y;
}
//Assuming root1 holds a greater key than root2,
root2 becomes the new root
private void link(Node<Key> root1, Node<Key> root2) {
root1.sibling = root2.child;
root1.parent = root2;
root2.child = root1;
root2.order++;
}
/*************************************************
* Functions for moving upward
************************************************/
//Moves a Node upward
private void swim(int i) {
Node<Key> x = nodes[i];
Node<Key> parent = x.parent;
if (parent != null && greater(parent.key,
x.key)) {
exchange(x, parent);

swim(i);
}
}
//The key associated with i becomes the root of its
Binomial Tree,
//regardless of the order relation defined for the
keys
private void toTheRoot(int i) {
Node<Key> x = nodes[i];
Node<Key> parent = x.parent;
if (parent != null) {
exchange(x, parent);
toTheRoot(i);
}
}
/**************************************************
* Functions for deleting a key
*************************************************/
//Assuming the key associated with i is in the root
list,
//deletes and return the node of index i
private Node<Key> erase(int i) {
Node<Key> reference = nodes[i];
Node<Key> x = head;
Node<Key> previous = new Node<Key>();
while (x != reference) {
previous = x;
x = x.sibling;
}
previous.sibling = x.sibling;
if (x == head) head = head.sibling;
nodes[i] = null;
return x;
}
//Deletes and return the node containing the minimum
key
private Node<Key> eraseMin() {
Node<Key> min = head;
Node<Key> previous = new Node<Key>();
Node<Key> current = head;
while (current.sibling != null) {
if (greater(min.key,
current.sibling.key)) {
previous = current;

min = current.sibling;
}
current = current.sibling;
}
previous.sibling = min.sibling;
if (min == head) head = min.sibling;
nodes[min.index] = null;
return min;
}
/**************************************************
* Functions for inserting a key in the heap
*************************************************/
//Merges two root lists into one,
2 Binomial Trees of same order
private Node<Key> merge(Node<Key>
Node<Key> y) {
if (x == null && y == null)
else if (x == null)
merge(y, x, y.sibling);
else if (y == null)
merge(x, x.sibling, y);
else if (x.order < y.order)
merge(x, x.sibling, y);
else
= merge(y, x, y.sibling);
return h;
}

there can be up to
h, Node<Key> x,
return h;
h.sibling =
h.sibling =
h.sibling =
h.sibling

//Merges two Binomial Heaps together and returns the


resulting Binomial Heap
//It destroys the two Heaps in parameter, which
should not be used any after.
//To guarantee logarithmic time, this function
assumes the arrays are up-to-date
private IndexBinomialMinPQ<Key>
union(IndexBinomialMinPQ<Key> heap) {
this.head = merge(new Node<Key>(), this.head,
heap.head).sibling;
Node<Key> x = this.head;
Node<Key> prevx = null, nextx = x.sibling;
while (nextx != null) {
if (x.order < nextx.order ||
(nextx.sibling != null &&
nextx.sibling.order == x.order)) {
prevx = x; x = nextx;
} else if (greater(nextx.key, x.key)) {

x.sibling = nextx.sibling;
link(nextx, x);
} else {
if (prevx == null) { this.head =
nextx; }
else { prevx.sibling = nextx; }
link(x, nextx);
x = nextx;
}
nextx = x.sibling;
}
return this;
}
/****************************************************
**************
* Constructor
***********************************************************
******/
//Creates an empty heap
//The comparator is instanciated because it needs to,
//but won't be used by any heap created by this
constructor
private IndexBinomialMinPQ() { comparator = null; }
/****************************************************
**************
* Iterator
***********************************************************
******/
/**
* Gets an Iterator over the indexes in the priority
queue in ascending order
* The Iterator does not implement the remove()
method
* iterator() : Worst case is O(n)
* next() : Worst case is O(log(n))
* hasNext() :
Worst case is O(1)
* @return an Iterator over the indexes in the
priority queue in ascending order
*/
public Iterator<Integer> iterator() {
return new MyIterator();

}
private class MyIterator implements Iterator<Integer>
{
IndexBinomialMinPQ<Key> data;
//Constructor clones recursively the elements
in the queue
//It takes linear time
public MyIterator() {
data = new IndexBinomialMinPQ<Key>(n,
comparator);
data.head = clone(head, false, false,
null);
}
private Node<Key> clone(Node<Key> x, boolean
isParent, boolean isChild, Node<Key> parent) {
if (x == null) return null;
Node<Key> node = new Node<Key>();
node.index = x.index;
node.key = x.key;
data.nodes[node.index] = node;
node.parent = parent;
node.sibling = clone(x.sibling, false,
false, parent);
node.child = clone(x.child, false, true,
node);
return node;
}
public boolean hasNext() {
return !data.isEmpty();
}
public Integer next() {
return data.delMin();
}
public void remove() {
throw new
UnsupportedOperationException();
}
}
/***************************
* Comparator
**************************/

//default Comparator
private class MyComparator implements Comparator<Key>
{
@Override
public int compare(Key key1, Key key2) {
return ((Comparable<Key>)
key1).compareTo(key2);
}
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Fri Jul 24 11:49:07 EDT 2015.
FibonacciMinPQ.java
Below is the syntax highlighted version
of FibonacciMinPQ.java from 9.9 Miscellaneous.
the Javadoc.

import
import
import
import

Here is

java.util.Iterator;
java.util.HashMap;
java.util.NoSuchElementException;
java.util.Comparator;

/**
* The FibonacciMinPQ class represents a priority queue of
generic keys.
* It supports the usual insert and delete-the-minimum
operations,
* along with the merging of two heaps together.
* It also supports methods for peeking at the minimum
key,
* testing if the priority queue is empty, and iterating
through
* the keys.
* It is possible to build the priority queue using a
Comparator.
* If not, the natural order relation between the keys
will be used.
*

* This implementation uses a Fibonacci heap.


* The delete-the-minimum operation takes amortized
logarithmic time.
* The insert, min-key, is-empty, size, union and
constructor take constant time.
*
* @author Tristan Claverie
*/
public class FibonacciMinPQ<Key> implements Iterable<Key> {
private Node head;
//Head
of the circular root list
private Node min;
//Minimum Node of the root list
private int size;
//Number
of keys in the heap
private final Comparator<Key> comp;
//Comparator
over the keys
private HashMap<Integer, Node> table = new
HashMap<Integer, Node>(); //Used for the consolidate
operation
//Represents a Node of a tree
private class Node {
Key key;
//Key of this Node
int order;
//Order of the tree rooted by this Node
Node prev, next;
//Siblings of this Node
Node child;
//Child of this Node
}
/**
* Initializes an empty priority queue
* Worst case is O(1)
* @param C a Comparator over the Keys
*/
public FibonacciMinPQ(Comparator<Key> C) {
comp = C;
}
/**
* Initializes an empty priority queue
* Worst case is O(1)
*/
public FibonacciMinPQ() {
comp = new MyComparator();

}
/**
* Initializes a priority queue with given keys
* Worst case is O(n)
* @param a an array of keys
*/
public FibonacciMinPQ(Key[] a) {
comp = new MyComparator();
for (Key k : a) insert(k);
}
/**
* Initializes a priority queue with given keys
* Worst case is O(n)
* @param C a comparator over the keys
* @param a an array of keys
*/
public FibonacciMinPQ(Comparator<Key> C, Key[] a) {
comp = C;
for (Key k : a) insert(k);
}
/**
* Whether the priority queue is empty
* Worst case is O(1)
* @return true if the priority queue is empty, false
if not
*/
public boolean isEmpty() {
return size == 0;
}
/**
* Number of elements currently on the priority queue
* Worst case is O(1)
* @return the number of elements on the priority
queue
*/
public int size() {
return size;
}
/**
* Insert a key in the queue
* Worst case is O(1)
* @param key a Key

*/
public void insert(Key key) {
Node x = new Node();
x.key = key;
size++;
head = insert(x, head);
if (min == null) min = head;
else
min = (greater(min.key,
key)) ? head : min;
}
/**
* Gets the minimum key currently in the queue
* Worst case is O(1)
* @throws java.util.NoSuchElementException if the
priority queue is empty
* @return the minimum key currently in the priority
queue
*/
public Key minKey() {
if (isEmpty()) throw new
NoSuchElementException("Priority queue is empty");
return min.key;
}
/**
* Deletes the minimum key
* Worst case is O(log(n)) (amortized)
* @throws java.util.NoSuchElementException if the
priority queue is empty
* @return the minimum key
*/
public Key delMin() {
if (isEmpty()) throw new
NoSuchElementException("Priority queue is empty");
head = cut(min, head);
Node x = min.child;
Key key = min.key;
min.key = null;
if (x != null) {
head = meld(head, x);
min.child = null;
}
size--;
if (!isEmpty()) consolidate();
else
min = null;
return key;

}
/**
* Merges two heaps together
* This operation is destructive
* Worst case is O(1)
* @param that a Fibonacci heap
* @return the union of the two heaps
*/
public FibonacciMinPQ<Key> union(FibonacciMinPQ<Key>
that) {
this.head = meld(head, that.head);
this.min = (greater(this.min.key,
that.min.key)) ? that.min : this.min;
this.size = this.size+that.size;
return this;
}
/*************************************
* General helper functions
************************************/
//Compares two keys
private boolean greater(Key n, Key m) {
if (n == null) return false;
if (m == null) return true;
return comp.compare(n,m) > 0;
}
//Assuming root1 holds a greater key than root2,
root2 becomes the new root
private void link(Node root1, Node root2) {
root2.child = insert(root1, root2.child);
root2.order++;
}
/*************************************
* Function for consolidating all trees in the root
list
************************************/
//Coalesce the roots, thus reshapes the tree
private void consolidate() {
table.clear();
Node x = head;
int maxOrder = 0;
min = head;
Node y = null; Node z = null;

do {
y = x;
x = x.next;
z = table.get(y.order);
while (z != null) {
table.remove(y.order);
if (greater(y.key, z.key)) {
link(y, z);
y = z;
} else {
link(z, y);
}
z = table.get(y.order);
}
table.put(y.order, y);
if (y.order > maxOrder) maxOrder =
y.order;
} while (x != head);
head = null;
for (Node n : table.values()) {
if (n != null) {
min = greater(min.key, n.key) ? n
: min;
head = insert(n, head);
}
}
}
/*************************************
* General helper functions for manipulating circular
lists
************************************/
//Inserts a Node in a circular list containing head,
returns a new head
private Node insert(Node x, Node head) {
if (head == null) {
x.prev = x;
x.next = x;
} else {
head.prev.next = x;
x.next = head;
x.prev = head.prev;
head.prev = x;
}
return x;
}

//Removes a tree from the list defined by the head


pointer
private Node cut(Node x, Node head) {
if (x.next == x) {
x.next = null;
x.prev = null;
return null;
} else {
x.next.prev = x.prev;
x.prev.next = x.next;
Node res = x.next;
x.next = null;
x.prev = null;
if (head == x) return res;
else
return head;
}
}
//Merges two root lists together
private Node meld(Node x, Node y) {
if (x == null) return y;
if (y == null) return x;
x.prev.next = y.next;
y.next.prev = x.prev;
x.prev = y;
y.next = x;
return x;
}
/*************************************
* Iterator
************************************/
/**
* Gets an Iterator over the Keys in the priority
queue in ascending order
* The Iterator does not implement the remove()
method
* iterator() : Worst case is O(n)
* next() : Worst case is O(log(n)) (amortized)
* hasNext() :
Worst case is O(1)
* @return an Iterator over the Keys in the priority
queue in ascending order
*/
public Iterator<Key> iterator() {
return new MyIterator();
}

private class MyIterator implements Iterator<Key> {


private FibonacciMinPQ<Key> copy;
//Constructor takes linear time
public MyIterator() {
copy = new FibonacciMinPQ<Key>(comp);
insertAll(head);
}
private void insertAll(Node head) {
if (head == null) return;
Node x = head;
do {
copy.insert(x.key);
insertAll(x.child);
x = x.next;
} while (x != head);
}
public void remove() {
throw new
UnsupportedOperationException();
}
public boolean hasNext() {
return !copy.isEmpty();
}
//Takes amortized logarithmic time
public Key next() {
if (!hasNext()) throw new
NoSuchElementException();
return copy.delMin();
}
}
/*************************************
* Comparator
************************************/
//default Comparator
private class MyComparator implements Comparator<Key>
{
@Override
public int compare(Key key1, Key key2) {
return ((Comparable<Key>)
key1).compareTo(key2);

}
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Sat May 2 05:42:54 EDT 2015.
IndexFibonacciMinPQ.java
Below is the syntax highlighted version
of IndexFibonacciMinPQ.java from 9.9 Miscellaneous.
is the Javadoc.

import
import
import
import

Here

java.util.Comparator;
java.util.Iterator;
java.util.HashMap;
java.util.NoSuchElementException;

/**
* The IndexFibonacciMinPQ class represents an indexed
priority queue of generic keys.
* It supports the usual insert and delete-the-minimum
operations,
* along with delete and change-the-key methods.
* In order to let the client refer to keys on the
priority queue,
* an integer between 0 and N-1 is associated with each
key ; the client
* uses this integer to specify which key to delete or
change.
* It also supports methods for peeking at the minimum
key,
* testing if the priority queue is empty, and iterating
through
* the keys.
*
* This implementation uses a Fibonacci heap along with an
array to associate
* keys with integers in the given range.
* The insert, size, is-empty, contains, minimum-index,
minimum-key
* and key-of take constant time.

* The decrease-key operation takes amortized constant


time.
* The delete, increase-key, delete-the-minimum, changekey take amortized logarithmic time.
* Construction takes time proportional to the specified
capacity
*
* @author Tristan Claverie
*/
public class IndexFibonacciMinPQ<Key> implements
Iterable<Integer> {
private Node<Key>[] nodes;
//Array
of Nodes in the heap
private Node<Key> head;
//Head
of the circular root list
private Node<Key> min;
//Minimum Node in the heap
private int size;
//Number
of keys in the heap
private int n;
//Maximum number of elements in the heap
private final Comparator<Key> comp; //Comparator over
the keys
private HashMap<Integer, Node<Key>> table = new
HashMap<Integer, Node<Key>>(); //Used for the consolidate
operation
//Represents a Node of a tree
private class Node<Key> {
Key key;
//Key of the Node
int order;
//The order of the tree rooted by this Node
int index;
//Index associated with the key
Node<Key> prev, next;
//siblings of the Node
Node<Key> parent, child;
//parent and
child of this Node
boolean mark;
//Indicates if this Node already lost a child
}
/**
* Initializes an empty indexed priority queue with
indices between 0 and N-1
* Worst case is O(n)

* @param N number of keys in the priority queue, index


from 0 to N-1
* @throws java.lang.IllegalArgumentException if N < 0
*/
public IndexFibonacciMinPQ(int N) {
if (N < 0) throw new
IllegalArgumentException("Cannot create a priority queue of
negative size");
n = N;
nodes = (Node<Key>[]) new Node[n];
comp = new MyComparator();
}
/**
* Initializes an empty indexed priority queue with
indices between 0 and N-1
* Worst case is O(n)
* @param N number of keys in the priority queue, index
from 0 to N-1
* @param C a Comparator over the keys
* @throws java.lang.IllegalArgumentException if N < 0
*/
public IndexFibonacciMinPQ(Comparator<Key> C, int N)
{
if (N < 0) throw new
IllegalArgumentException("Cannot create a priority queue of
negative size");
n = N;
nodes = (Node<Key>[]) new Node[n];
comp = C;
}
/**
* Whether the priority queue is empty
* Worst case is O(1)
* @return true if the priority queue is empty, false
if not
*/
public boolean isEmpty() {
return size == 0;
}
/**
* Does the priority queue contains the index i ?
* Worst case is O(1)
* @param i an index

* @throws java.lang.IndexOutOfBoundsException if the


specified index is invalid
* @return true if i is on the priority queue, false
if not
*/
public boolean contains(int i) {
if (i < 0 || i >= n) throw new
IndexOutOfBoundsException();
else
return nodes[i] !=
null;
}
/**
* Number of elements currently on the priority queue
* Worst case is O(1)
* @return the number of elements on the priority
queue
*/
public int size() {
return size;
}
/**
* Associates a key with an index
* Worst case is O(1)
* @param i an index
* @param key a Key associated with i
* @throws java.lang.IndexOutOfBoundsException if the
specified index is invalid
* @throws java.util.IllegalArgumentException if the
index is already in the queue
*/
public void insert(int i, Key key) {
if (i < 0 || i >= n) throw new
IndexOutOfBoundsException();
if (contains(i)) throw new
IllegalArgumentException("Specified index is already in the
queue");
Node<Key> x = new Node<Key>();
x.key = key;
x.index = i;
nodes[i] = x;
size++;
head = insert(x, head);
if (min == null) min = head;

else
key)) ? head : min;
}

min = (greater(min.key,

/**
* Get the index associated with the minimum key
* Worst case is O(1)
* @throws java.util.NoSuchElementException if the
priority queue is empty
* @return the index associated with the minimum key
*/
public int minIndex() {
if (isEmpty()) throw new
NoSuchElementException("Priority queue is empty");
return min.index;
}
/**
* Get the minimum key currently in the queue
* Worst case is O(1)
* @throws java.util.NoSuchElementException if the
priority queue is empty
* @return the minimum key currently in the priority
queue
*/
public Key minKey() {
if (isEmpty()) throw new
NoSuchElementException("Priority queue is empty");
return min.key;
}
/**
* Delete the minimum key
* Worst case is O(log(n)) (amortized)
* @throws java.util.NoSuchElementException if the
priority queue is empty
* @return the index associated with the minimum key
*/
public int delMin() {
if (isEmpty()) throw new
NoSuchElementException("Priority queue is empty");
head = cut(min, head);
Node<Key> x = min.child;
int index = min.index;

min.key = null;
//For garbage collection
if (x != null) {
do {
x.parent = null;
x = x.next;
} while (x != min.child);
head = meld(head, x);
min.child = null;
garbage collection
}
size--;
if (!isEmpty()) consolidate();
else
min = null;
nodes[index] = null;
return index;
}

//For

/**
* Get the key associated with index i
* Worst case is O(1)
* @param i an index
* @throws java.lang.IndexOutOfBoundsException if the
specified index is invalid
* @throws java.util.NoSuchElementException if the
index is not in the queue
* @return the key associated with index i
*/
public Key keyOf(int i) {
if (i < 0 || i >= n) throw new
IndexOutOfBoundsException();
if (!contains(i)) throw new
NoSuchElementException("Specified index is not in the
queue");
return nodes[i].key;
}
/**
* Changes the key associated with index i to the
given key
* If the given key is greater, Worst case is
O(log(n))
* If the given key is lower, Worst case is O(1)
(amortized)
* @param i an index
* @param key the key to associate with i

* @throws java.lang.IndexOutOfBoundsException if the


specified index is invalid
* @throws java.util.NoSuchElementException if the
index has no key associated with
*/
public void changeKey(int i, Key key) {
if (i < 0 || i >= n)
throw new
IndexOutOfBoundsException();
if (!contains(i))
throw new
NoSuchElementException("Specified index is not in the
queue");
if (greater(key, nodes[i].key)) increaseKey(i,
key);
else
decreaseKey(i, key);
}
/**
* Decreases the key associated with index i to the
given key
* Worst case is O(1) (amortized).
* @param i an index
* @param key the key to associate with i
* @throws java.lang.IndexOutOfBoundsException if the
specified index is invalid
* @throws java.util.NoSuchElementException if the
index has no key associated with
* @throws java.util.IllegalArgumentException if the
given key is greater than the current key
*/
public void decreaseKey(int i, Key key) {
if (i < 0 || i >= n)
throw new
IndexOutOfBoundsException();
if (!contains(i))
throw new
NoSuchElementException("Specified index is not in the
queue");
if (greater(key, nodes[i].key)) throw new
IllegalArgumentException("Calling with this argument would
not decrease the key");
Node<Key> x = nodes[i];
x.key = key;
if (greater(min.key, key)) min = x;
if (x.parent != null && greater(x.parent.key,
key)) {
cut(i);

}
}
/**
* Increases the key associated with index i to the
given key
* Worst case is O(log(n))
* @param i an index
* @param key the key to associate with i
* @throws java.lang.IndexOutOfBoundsException if the
specified index is invalid
* @throws java.util.NoSuchElementException if the
index has no key associated with
* @throws java.util.IllegalArgumentException if the
given key is lower than the current key
*/
public void increaseKey(int i, Key key) {
if (i < 0 || i >= n)
throw new
IndexOutOfBoundsException();
if (!contains(i))
throw new
NoSuchElementException("Specified index is not in the
queue");
if (greater(nodes[i].key, key)) throw new
IllegalArgumentException("Calling with this argument would
not increase the key");
delete(i);
insert(i, key);
}
/**
* Deletes the key associated the given index
* Worst case is O(log(n)) (amortized)
* @param i an index
* @throws java.lang.IndexOutOfBoundsException if the
specified index is invalid
* @throws java.util.NoSuchElementException if the
given index has no key associated with
*/
public void delete(int i) {
if (i < 0 || i >= n)
throw new
IndexOutOfBoundsException();
if (!contains(i))
throw new
NoSuchElementException("Specified index is not in the
queue");
Node<Key> x = nodes[i];

x.key = null;
garbage collection
if (x.parent != null) {
cut(i);
}
head = cut(x, head);
if (x.child != null) {
Node<Key> child = x.child;
x.child = null;
garbage collection
x = child;
do {
child.parent = null;
child = child.next;
} while (child != x);
head = meld(head, child);
}
if (!isEmpty()) consolidate();
else
min = null;
nodes[i] = null;
size--;
}

//For

//For

/*************************************
* General helper functions
************************************/
//Compares two keys
private boolean greater(Key n, Key m) {
if (n == null) return false;
if (m == null) return true;
return comp.compare(n, m) > 0;
}
//Assuming root1 holds a greater key than root2,
root2 becomes the new root
private void link(Node<Key> root1, Node<Key> root2) {
root1.parent = root2;
root2.child = insert(root1, root2.child);
root2.order++;
}
/*************************************
* Function for decreasing a key
************************************/
//Removes a Node from its parent's child list and
insert it in the root list

//If the parent Node already lost a child, reshapes


the heap accordingly
private void cut(int i) {
Node<Key> x = nodes[i];
Node<Key> parent = x.parent;
parent.child = cut(x, parent.child);
x.parent = null;
parent.order--;
head = insert(x, head);
parent.mark = !parent.mark;
if (!parent.mark && parent.parent != null) {
cut(parent.index);}
}
/*************************************
* Function for consolidating all trees in the root
list
************************************/
//Coalesces the roots, thus reshapes the heap
//Caching a HashMap improves greatly performances
private void consolidate() {
table.clear();
Node<Key> x = head;
int maxOrder = 0;
min = head;
Node<Key> y = null, z = null;
do {
y = x;
x = x.next;
z = table.get(y.order);
while (z != null) {
table.remove(y.order);
if (greater(y.key, z.key)) {
link(y, z);
y = z;
} else {
link(z, y);
}
z = table.get(y.order);
}
table.put(y.order, y);
if (y.order > maxOrder) maxOrder =
y.order;
} while (x != head);
head = null;
for (Node<Key> n : table.values()) {

min = greater(min.key, n.key) ? n : min;


head = insert(n, head);
}
}
/*************************************
* General helper functions for manipulating circular
lists
************************************/
//Inserts a Node in a circular list containing head,
returns a new head
private Node<Key> insert(Node<Key> x, Node<Key> head)
{
if (head == null) {
x.prev = x;
x.next = x;
} else {
head.prev.next = x;
x.next = head;
x.prev = head.prev;
head.prev = x;
}
return x;
}
//Removes a tree from the list defined by the head
pointer
private Node<Key> cut(Node<Key> x, Node<Key> head) {
if (x.next == x) {
x.next = null;
x.prev = null;
return null;
} else {
x.next.prev = x.prev;
x.prev.next = x.next;
Node<Key> res = x.next;
x.next = null;
x.prev = null;
if (head == x) return res;
else
return head;
}
}
//Merges two lists together.
private Node<Key> meld(Node<Key> x, Node<Key> y) {
if (x == null) return y;
if (y == null) return x;

x.prev.next = y.next;
y.next.prev = x.prev;
x.prev = y;
y.next = x;
return x;
}
/*************************************
* Iterator
************************************/
/**
* Get an Iterator over the indexes in the priority
queue in ascending order
* The Iterator does not implement the remove()
method
* iterator() : Worst case is O(n)
* next() : Worst case is O(log(n)) (amortized)
* hasNext() :
Worst case is O(1)
* @return an Iterator over the indexes in the
priority queue in ascending order
*/
public Iterator<Integer> iterator() {
return new MyIterator();
}
private class MyIterator implements Iterator<Integer>
{
private IndexFibonacciMinPQ<Key> copy;
//Constructor takes linear time
public MyIterator() {
copy = new
IndexFibonacciMinPQ<Key>(comp, n);
for (Node<Key> x : nodes) {
if (x != null)
copy.insert(x.index, x.key);
}
}
public void remove() {
throw new
UnsupportedOperationException();
}
public boolean hasNext() {

return !copy.isEmpty();
}
//Takes amortized logarithmic time
public Integer next() {
if (!hasNext()) throw new
NoSuchElementException();
return copy.delMin();
}
}
/***************************
* Comparator
**************************/
//default Comparator
private class MyComparator implements Comparator<Key>
{
@Override
public int compare(Key key1, Key key2) {
return ((Comparable<Key>)
key1).compareTo(key2);
}
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Wed Jul 22 16:02:29 EDT 2015.
StdIn.java
Below is the syntax highlighted version of StdIn.java from
Standard Libraries.
Here is the Javadoc.

/
***********************************************************
**************
* Compilation: javac StdIn.java
* Execution:
java StdIn
(interactive test of basic
functionality)
* Dependencies: none
*
* Reads in data of various types from standard input.
*

***********************************************************
**************/
import
import
import
import
import
import

java.util.ArrayList;
java.util.InputMismatchException;
java.util.Locale;
java.util.NoSuchElementException;
java.util.Scanner;
java.util.regex.Pattern;

/**
* The <tt>StdIn</tt> class provides static methods for
reading strings
* and numbers from standard input. See
* <a
href="http://introcs.cs.princeton.edu/15inout">Section
1.5</a> of
* <i>Introduction to Programming in Java: An
Interdisciplinary Approach</i>
* by Robert Sedgewick and Kevin Wayne.
* <p>
* For uniformity across platforms, this class uses
<tt>Locale.US</tt>
* for the locale and <tt>"UTF-8"</tt> for the characterset encoding.
* The English language locale is consistent with the
formatting conventions
* for Java floating-point literals, command-line
arguments
* (via {@link Double#parseDouble(String)}) and standard
output.
* <p>
* Like {@link Scanner}, reading a <em>token</em> also
consumes preceding Java
* whitespace; reading a line consumes the following endof-line
* delimeter; reading a character consumes nothing extra.
* <p>
* Whitespace is defined in {@link
Character#isWhitespace(char)}. Newlines
* consist of \n, \r, \r\n, and Unicode hex code points
0x2028, 0x2029, 0x0085;
* see <tt><a
href="http://www.docjar.com/html/api/java/util/Scanner.java.
html">

* Scanner.java</a></tt> (NB: Java 6u23 and earlier uses


only \r, \r, \r\n).
* <p>
* See {@link In} for a version that handles input from
files, URLs,
* and sockets.
* <p>
* Note that Java's UTF-8 encoding does not recognize the
optional byte-order
* mask. If the input begins with the optional byte-order
mask, <tt>StdIn</tt>
* will have an extra character <tt>uFEFF</tt> at the
beginning.
* For details, see
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4508058.
*
* @author David Pritchard
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public final class StdIn {
/*** 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
// is held by the scanner's delimiter between calls
private static final Pattern WHITESPACE_PATTERN =
Pattern.compile("\\p{javaWhitespace}+");
// makes whitespace characters significant
private static final Pattern EMPTY_PATTERN =
Pattern.compile("");
// used to read the entire input
private static final Pattern EVERYTHING_PATTERN =
Pattern.compile("\\A");

/*** end: section (1 of 2) of code duplicated from In


to StdIn. */
private static Scanner scanner;
// it doesn't make sense to instantiate this class
private StdIn() { }
/*** begin: section (2 of 2) of code duplicated from In
to StdIn,
* with all methods changed from "public" to "public
static" ***/
/**
* Is the input empty (except possibly for whitespace)?
Use this
* to know whether the next call to {@link
#readString()},
* {@link #readDouble()}, etc will succeed.
* @return true if standard input is empty (except
possibly
*
for whitespae), and false otherwise
*/
public static boolean isEmpty() {
return !scanner.hasNext();
}
/**
* Does the input have a next line? Use this to know
whether the
* next call to {@link #readLine()} will succeed. <p>
Functionally
* equivalent to {@link #hasNextChar()}.
* @return true if standard input is empty, and false
otherwise
*/
public static boolean hasNextLine() {
return scanner.hasNextLine();
}
/**
* Is the input empty (including whitespace)? Use this
to know
* whether the next call to {@link #readChar()} will
succeed.
* <p>Functionally equivalent to {@link
#hasNextLine()}.

* @return true if standard input is empty, and false


otherwise
*/
public static boolean hasNextChar() {
scanner.useDelimiter(EMPTY_PATTERN);
boolean result = scanner.hasNext();
scanner.useDelimiter(WHITESPACE_PATTERN);
return result;
}
/**
* Reads and returns the next line, excluding the line
separator if present.
* @return the next line, excluding the line separator
if present
*/
public static String readLine() {
String line;
try {
line = scanner.nextLine();
}
catch (NoSuchElementException e) {
line = null;
}
return line;
}
/**
* Reads and returns the next character.
* @return the next character
*/
public static char readChar() {
scanner.useDelimiter(EMPTY_PATTERN);
String ch = scanner.next();
assert (ch.length() == 1) : "Internal
(Std)In.readChar() error!"
+ " Please contact the authors.";
scanner.useDelimiter(WHITESPACE_PATTERN);
return ch.charAt(0);
}
/**
* Reads and returns the remainder of the input, as a
string.
* @return the remainder of the input, as a string

*/
public static String readAll() {
if (!scanner.hasNextLine())
return "";
String result =
scanner.useDelimiter(EVERYTHING_PATTERN).next();
// not that important to reset delimeter, since now
scanner is empty
scanner.useDelimiter(WHITESPACE_PATTERN); // but
let's do it anyway
return result;
}
/**
* Reads the next token and returns the
<tt>String</tt>.
* @return the next <tt>String</tt>
*/
public static String readString() {
return scanner.next();
}
/**
* Reads the next token from standard input, parses it
as an integer, and returns the integer.
* @return the next integer on standard input
* @throws InputMismatchException if the next token
cannot be parsed as an <tt>int</tt>
*/
public static int readInt() {
return scanner.nextInt();
}
/**
* Reads the next token from standard input, parses it
as a double, and returns the double.
* @return the next double on standard input
* @throws InputMismatchException if the next token
cannot be parsed as a <tt>double</tt>
*/
public static double readDouble() {
return scanner.nextDouble();
}
/**

* Reads the next token from standard input, parses it


as a float, and returns the float.
* @return the next float on standard input
* @throws InputMismatchException if the next token
cannot be parsed as a <tt>float</tt>
*/
public static float readFloat() {
return scanner.nextFloat();
}
/**
* Reads the next token from standard input, parses it
as a long integer, and returns the long integer.
* @return the next long integer on standard input
* @throws InputMismatchException if the next token
cannot be parsed as a <tt>long</tt>
*/
public static long readLong() {
return scanner.nextLong();
}
/**
* Reads the next token from standard input, parses it
as a short integer, and returns the short integer.
* @return the next short integer on standard input
* @throws InputMismatchException if the next token
cannot be parsed as a <tt>short</tt>
*/
public static short readShort() {
return scanner.nextShort();
}
/**
* Reads the next token from standard input, parses it
as a byte, and returns the byte.
* @return the next byte on standard input
* @throws InputMismatchException if the next token
cannot be parsed as a <tt>byte</tt>
*/
public static byte readByte() {
return scanner.nextByte();
}
/**
* Reads the next token from standard input, parses it
as a boolean,
* and returns the boolean.

* @return the next boolean on standard input


* @throws InputMismatchException if the next token
cannot be parsed as a <tt>boolean</tt>:
*
<tt>true</tt> or <tt>1</tt> for true, and
<tt>false</tt> or <tt>0</tt> for false,
*
ignoring case
*/
public static boolean readBoolean() {
String s = readString();
if (s.equalsIgnoreCase("true")) return true;
if (s.equalsIgnoreCase("false")) return false;
if (s.equals("1"))
return true;
if (s.equals("0"))
return false;
throw new InputMismatchException();
}
/**
* Reads all remaining tokens from standard input and
returns them as an array of strings.
* @return all remaining tokens on standard input, as
an array of strings
*/
public static String[] readAllStrings() {
// we could use readAll.trim().split(), but that's
not consistent
// because trim() uses characters 0x00..0x20 as
whitespace
String[] tokens =
WHITESPACE_PATTERN.split(readAll());
if (tokens.length == 0 || tokens[0].length() > 0)
return tokens;
// don't include first token if it is leading
whitespace
String[] decapitokens = new String[tokens.length-1];
for (int i = 0; i < tokens.length - 1; i++)
decapitokens[i] = tokens[i+1];
return decapitokens;
}
/**
* Reads all remaining lines from standard input and
returns them as an array of strings.
* @return all remaining lines on standard input, as an
array of strings
*/
public static String[] readAllLines() {

ArrayList<String> lines = new ArrayList<String>();


while (hasNextLine()) {
lines.add(readLine());
}
return lines.toArray(new String[0]);
}
/**
* Reads all remaining tokens from standard input,
parses them as integers, and returns
* them as an array of integers.
* @return all remaining integers on standard input, as
an array
* @throws InputMismatchException if any token cannot
be parsed as an <tt>int</tt>
*/
public static int[] readAllInts() {
String[] fields = readAllStrings();
int[] vals = new int[fields.length];
for (int i = 0; i < fields.length; i++)
vals[i] = Integer.parseInt(fields[i]);
return vals;
}
/**
* Reads all remaining tokens from standard input,
parses them as doubles, and returns
* them as an array of doubles.
* @return all remaining doubles on standard input, as
an array
* @throws InputMismatchException if any token cannot
be parsed as a <tt>double</tt>
*/
public static double[] readAllDoubles() {
String[] fields = readAllStrings();
double[] vals = new double[fields.length];
for (int i = 0; i < fields.length; i++)
vals[i] = Double.parseDouble(fields[i]);
return vals;
}
/*** end: section (2 of 2) of code duplicated from In
to StdIn */
// do this once when StdIn is initialized
static {
resync();

}
/**
* If StdIn changes, use this to reinitialize the
scanner.
*/
private static void resync() {
setScanner(new Scanner(new
java.io.BufferedInputStream(System.in), CHARSET_NAME));
}
private static void setScanner(Scanner scanner) {
StdIn.scanner = scanner;
StdIn.scanner.useLocale(LOCALE);
}
/**
* Reads all remaining tokens, parses them as integers,
and returns
* them as an array of integers.
* @return all remaining integers, as an array
* @throws InputMismatchException if any token cannot
be parsed as an <tt>int</tt>
* @deprecated For more consistency, use {@link
#readAllInts()}
*/
public static int[] readInts() {
return readAllInts();
}
/**
* Reads all remaining tokens, parses them as doubles,
and returns
* them as an array of doubles.
* @return all remaining doubles, as an array
* @throws InputMismatchException if any token cannot
be parsed as a <tt>double</tt>
* @deprecated For more consistency, use {@link
#readAllDoubles()}
*/
public static double[] readDoubles() {
return readAllDoubles();
}
/**
* Reads all remaining tokens and returns them as an
array of strings.

* @return all remaining tokens, as an array of strings


* @deprecated For more consistency, use {@link
#readAllStrings()}
*/
public static String[] readStrings() {
return readAllStrings();
}
/**
* Interactive test of basic functionality.
*/
public static void main(String[] args) {
System.out.println("Type a string: ");
String s = StdIn.readString();
System.out.println("Your string was: " + s);
System.out.println();
System.out.println("Type an int: ");
int a = StdIn.readInt();
System.out.println("Your int was: " + a);
System.out.println();
System.out.println("Type a boolean: ");
boolean b = StdIn.readBoolean();
System.out.println("Your boolean was: " + b);
System.out.println();
System.out.println("Type a double: ");
double c = StdIn.readDouble();
System.out.println("Your double was: " + c);
System.out.println();
}
}
Copyright 20002011, Robert Sedgewick and Kevin Wayne.
Last updated: Tue Jul 28 06:54:02 EDT 2015.
StdOut.java
Below is the syntax highlighted version
of StdOut.java from Standard Libraries.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac StdOut.java
* Execution:
java StdOut
* Dependencies: none
*
* Writes data of various types to standard output.
*
***********************************************************
**************/
import
import
import
import

java.io.OutputStreamWriter;
java.io.PrintWriter;
java.io.UnsupportedEncodingException;
java.util.Locale;

/**
* <i>Standard output</i>. This class provides methods for
writing strings
* and numbers to standard output.
* <p>
* For additional documentation, see <a
href="http://introcs.cs.princeton.edu/15inout">Section
1.5</a> of
* <i>Introduction to Programming in Java: An
Interdisciplinary Approach</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public final class StdOut {
// force Unicode UTF-8 encoding; otherwise it's system
dependent
private static final String CHARSET_NAME = "UTF-8";
// assume language = English, country = US for
consistency with StdIn
private static final Locale LOCALE = Locale.US;
// send output here
private static PrintWriter out;

// this is called before invoking any methods


static {
try {
out = new PrintWriter(new
OutputStreamWriter(System.out, CHARSET_NAME), true);
}
catch (UnsupportedEncodingException e) {
System.out.println(e);
}
}
// don't instantiate
private StdOut() { }
// close the output stream (not required)
/**
* Close standard output.
*/
public static void close() {
out.close();
}
/**
* Terminate the current line by printing the line
separator string.
*/
public static void println() {
out.println();
}
/**
* Print an object to standard output and then
terminate the line.
*/
public static void println(Object x) {
out.println(x);
}
/**
* Print a boolean to standard output and then
terminate the line.
*/
public static void println(boolean x) {
out.println(x);
}

/**
* Print a char to standard output and then terminate
the line.
*/
public static void println(char x) {
out.println(x);
}
/**
* Print a double to standard output and then terminate
the line.
*/
public static void println(double x) {
out.println(x);
}
/**
* Print a float to standard output and then terminate
the line.
*/
public static void println(float x) {
out.println(x);
}
/**
* Print an int to standard output and then terminate
the line.
*/
public static void println(int x) {
out.println(x);
}
/**
* Print a long to standard output and then terminate
the line.
*/
public static void println(long x) {
out.println(x);
}
/**
* Print a short to standard output and then terminate
the line.
*/
public static void println(short x) {
out.println(x);
}

/**
* Print a byte to standard output and then terminate
the line.
*/
public static void println(byte x) {
out.println(x);
}
/**
* Flush standard output.
*/
public static void print() {
out.flush();
}
/**
* Print an Object to standard output and flush
standard output.
*/
public static void print(Object x) {
out.print(x);
out.flush();
}
/**
* Print a boolean to standard output and flush
standard output.
*/
public static void print(boolean x) {
out.print(x);
out.flush();
}
/**
* Print a char to standard output and flush standard
output.
*/
public static void print(char x) {
out.print(x);
out.flush();
}
/**
* Print a double to standard output and flush standard
output.
*/

public static void print(double x) {


out.print(x);
out.flush();
}
/**
* Print a float to standard output and flush standard
output.
*/
public static void print(float x) {
out.print(x);
out.flush();
}
/**
* Print an int to standard output and flush standard
output.
*/
public static void print(int x) {
out.print(x);
out.flush();
}
/**
* Print a long to standard output and flush standard
output.
*/
public static void print(long x) {
out.print(x);
out.flush();
}
/**
* Print a short to standard output and flush standard
output.
*/
public static void print(short x) {
out.print(x);
out.flush();
}
/**
* Print a byte to standard output and flush standard
output.
*/
public static void print(byte x) {
out.print(x);

out.flush();
}
/**
* Print a formatted string to standard output using
the specified
* format string and arguments, and flush standard
output.
*/
public static void printf(String format, Object... args)
{
out.printf(LOCALE, format, args);
out.flush();
}
/**
* Print a formatted string to standard output using
the specified
* locale, format string, and arguments, and flush
standard output.
*/
public static void printf(Locale locale, String format,
Object... args) {
out.printf(locale, format, args);
out.flush();
}
// This method is just here to test the class
public static void main(String[] args) {
// write to stdout
StdOut.println("Test");
StdOut.println(17);
StdOut.println(true);
StdOut.printf("%.6f\n", 1.0/7.0);
}
}
Copyright 20002011, Robert Sedgewick and Kevin Wayne.
Last updated: Fri Jul 24 09:39:19 EDT 2015.
StdDraw.java
Below is the syntax highlighted version

of StdDraw.java from Standard Libraries.


the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac StdDraw.java
* Execution:
java StdDraw
* Dependencies: none
*
* Standard drawing library. This class 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.
*
* Todo
* ---*
- Add support for gradient fill, etc.
*
- Fix setCanvasSize() so that it can only be called
once.
*
- On some systems, drawing a line (or other shape)
that extends way
*
beyond canvas (e.g., to infinity) dimensions does
not get drawn.
*
* Remarks
* ------*
- don't use AffineTransform for rescaling since it
inverts
*
images and strings
*
- careful using setFont in inner loop within an
animation *
it can cause flicker
*
***********************************************************
**************/
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.FileDialog;

import
import
import
import
import
import
import

java.awt.Font;
java.awt.FontMetrics;
java.awt.Graphics2D;
java.awt.Image;
java.awt.MediaTracker;
java.awt.RenderingHints;
java.awt.Toolkit;

import
import
import
import
import
import
import

java.awt.event.ActionEvent;
java.awt.event.ActionListener;
java.awt.event.MouseEvent;
java.awt.event.MouseListener;
java.awt.event.MouseMotionListener;
java.awt.event.KeyEvent;
java.awt.event.KeyListener;

import
import
import
import
import

java.awt.geom.Arc2D;
java.awt.geom.Ellipse2D;
java.awt.geom.GeneralPath;
java.awt.geom.Line2D;
java.awt.geom.Rectangle2D;

import java.awt.image.BufferedImage;
import java.awt.image.DirectColorModel;
import java.awt.image.WritableRaster;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.LinkedList;
import java.util.TreeSet;
import javax.imageio.ImageIO;
import
import
import
import
import
import
import

javax.swing.ImageIcon;
javax.swing.JFrame;
javax.swing.JLabel;
javax.swing.JMenu;
javax.swing.JMenuBar;
javax.swing.JMenuItem;
javax.swing.KeyStroke;

/**
* <i>Standard draw</i>. This class 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.
* <p>
* For additional documentation, see <a
href="http://introcs.cs.princeton.edu/15inout">Section
1.5</a> of
* <i>Introduction to Programming in Java: An
Interdisciplinary Approach</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public final class StdDraw implements ActionListener,
MouseListener, MouseMotionListener, KeyListener {
// pre-defined colors
public static final Color
public static final Color
public static final Color
public static final Color
public static final Color
public static final Color
public static final Color
public static final Color
public static final Color
public static final Color
public static final Color
public static final Color
public static final Color

BLACK
BLUE
CYAN
DARK_GRAY
GRAY
GREEN
LIGHT_GRAY
MAGENTA
ORANGE
PINK
RED
WHITE
YELLOW

=
=
=
=
=
=
=
=
=
=
=
=
=

Color.BLACK;
Color.BLUE;
Color.CYAN;
Color.DARK_GRAY;
Color.GRAY;
Color.GREEN;
Color.LIGHT_GRAY;
Color.MAGENTA;
Color.ORANGE;
Color.PINK;
Color.RED;
Color.WHITE;
Color.YELLOW;

/**
* 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);
public static final Color BOOK_LIGHT_BLUE = new
Color(103, 198, 243);
/**

* 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);
// default colors
private static final Color DEFAULT_PEN_COLOR
= BLACK;
private static final Color DEFAULT_CLEAR_COLOR = WHITE;
// current pen color
private static Color penColor;
// default canvas size is DEFAULT_SIZE-by-DEFAULT_SIZE
private static final int DEFAULT_SIZE = 512;
private static int width = DEFAULT_SIZE;
private static int height = DEFAULT_SIZE;
// default pen radius
private static final double DEFAULT_PEN_RADIUS = 0.002;
// current pen radius
private static double penRadius;
// show we draw immediately or wait until next show?
private static boolean defer = false;
// boundary of drawing canvas, 0% border
// private static final double BORDER = 0.05;
private static final double BORDER = 0.00;
private static final double DEFAULT_XMIN = 0.0;
private static final double DEFAULT_XMAX = 1.0;
private static final double DEFAULT_YMIN = 0.0;
private static final double DEFAULT_YMAX = 1.0;
private static double xmin, ymin, xmax, ymax;
// for synchronization
private static Object mouseLock = new Object();
private static Object keyLock = new Object();
// default font
private static final Font DEFAULT_FONT = new
Font("SansSerif", Font.PLAIN, 16);
// current font
private static Font font;

// double buffered graphics


private static BufferedImage offscreenImage,
onscreenImage;
private static Graphics2D offscreen, onscreen;
// singleton for callbacks: avoids generation of
extra .class files
private static StdDraw std = new StdDraw();
// the frame for drawing to the screen
private static JFrame frame;
// mouse state
private static boolean mousePressed = false;
private static double mouseX = 0;
private static double mouseY = 0;
// queue of typed key characters
private static LinkedList<Character> keysTyped = new
LinkedList<Character>();
// set of key codes currently pressed down
private static TreeSet<Integer> keysDown = new
TreeSet<Integer>();
// time
we can draw
// used
private

in milliseconds (from currentTimeMillis()) when


again
to control the frame rate
static long nextDraw = -1;

// singleton pattern: client can't instantiate


private StdDraw() { }
// static initializer
static {
init();
}
/**
* Set the window size to the default size 512-by-512
pixels.
* This method must be called before any other
commands.
*/
public static void setCanvasSize() {

setCanvasSize(DEFAULT_SIZE, DEFAULT_SIZE);
}
/**
* Set the window size to w-by-h pixels.
* This method must be called before any other
commands.
*
* @param w the width as a number of pixels
* @param h the height as a number of pixels
* @throws a IllegalArgumentException if the width or
height is 0 or negative
*/
public static void setCanvasSize(int w, int h) {
if (w < 1 || h < 1) throw new
IllegalArgumentException("width and height must be
positive");
width = w;
height = h;
init();
}
// init
private static void init() {
if (frame != null) frame.setVisible(false);
frame = new JFrame();
offscreenImage = new BufferedImage(width, height,
BufferedImage.TYPE_INT_ARGB);
onscreenImage = new BufferedImage(width, height,
BufferedImage.TYPE_INT_ARGB);
offscreen = offscreenImage.createGraphics();
onscreen = onscreenImage.createGraphics();
setXscale();
setYscale();
offscreen.setColor(DEFAULT_CLEAR_COLOR);
offscreen.fillRect(0, 0, width, height);
setPenColor();
setPenRadius();
setFont();
clear();
// add antialiasing
RenderingHints hints = new
RenderingHints(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);

hints.put(RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY);
offscreen.addRenderingHints(hints);
// frame stuff
ImageIcon icon = new ImageIcon(onscreenImage);
JLabel draw = new JLabel(icon);
draw.addMouseListener(std);
draw.addMouseMotionListener(std);
frame.setContentPane(draw);
frame.addKeyListener(std);
keyboard focus
frame.setResizable(false);

// JLabel cannot get

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// closes all windows
//
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
// closes only current window
frame.setTitle("Standard Draw");
frame.setJMenuBar(createMenuBar());
frame.pack();
frame.requestFocusInWindow();
frame.setVisible(true);
}
// create the menu bar (changed to private)
private static JMenuBar createMenuBar() {
JMenuBar menuBar = new JMenuBar();
JMenu menu = new JMenu("File");
menuBar.add(menu);
JMenuItem menuItem1 = new JMenuItem(" Save...
menuItem1.addActionListener(std);

");

menuItem1.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_
S,
Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
menu.add(menuItem1);
return menuBar;
}

/**********************************************************
***************

User and screen coordinate systems

***********************************************************
**************/
/**
* Set the x-scale to be the default (between 0.0 and
1.0).
*/
public static void setXscale() { setXscale(DEFAULT_XMIN,
DEFAULT_XMAX); }
/**
* Set the y-scale to be the default (between 0.0 and
1.0).
*/
public static void setYscale() { setYscale(DEFAULT_YMIN,
DEFAULT_YMAX); }
/**
* Set the x-scale.
* @param min the minimum value of the x-scale
* @param max the maximum value of the x-scale
*/
public static void setXscale(double min, double max) {
double size = max - min;
synchronized (mouseLock) {
xmin = min - BORDER * size;
xmax = max + BORDER * size;
}
}
/**
* Set the y-scale.
* @param min the minimum value of the y-scale
* @param max the maximum value of the y-scale
*/
public static void setYscale(double min, double max) {
double size = max - min;
synchronized (mouseLock) {
ymin = min - BORDER * size;
ymax = max + BORDER * size;
}
}
/**
* Set the x-scale and y-scale.

* @param min the minimum value of the x- and y-scales


* @param max the maximum value of the x- and y-scales
*/
public static void setScale(double min, double max) {
double size = max - min;
synchronized (mouseLock) {
xmin = min - BORDER * size;
xmax = max + BORDER * size;
ymin = min - BORDER * size;
ymax = max + BORDER * size;
}
}
// helper functions that scale from user coordinates to
screen coordinates and back
private static double scaleX(double x) { return width
* (x - xmin) / (xmax - xmin); }
private static double scaleY(double y) { return height
* (ymax - y) / (ymax - ymin); }
private static double factorX(double w) { return w *
width / Math.abs(xmax - xmin); }
private static double factorY(double h) { return h *
height / Math.abs(ymax - ymin); }
private static double
userX(double x) { return xmin +
x * (xmax - xmin) / width;
}
private static double
userY(double y) { return ymax y * (ymax - ymin) / height;
}
/**
* Clear the screen to the default color (white).
*/
public static void clear() { clear(DEFAULT_CLEAR_COLOR);
}
/**
* Clear the screen to the given color.
* @param color the Color to make the background
*/
public static void clear(Color color) {
offscreen.setColor(color);
offscreen.fillRect(0, 0, width, height);
offscreen.setColor(penColor);
draw();
}
/**
* Get the current pen radius.

*/
public static double getPenRadius() { return penRadius;
}
/**
* Set the pen size to the default (.002).
*/
public static void setPenRadius() {
setPenRadius(DEFAULT_PEN_RADIUS); }
/**
* Set the radius of the pen to the given size.
* @param r the radius of the pen
* @throws IllegalArgumentException if r is negative
*/
public static void setPenRadius(double r) {
if (r < 0) throw new IllegalArgumentException("pen
radius must be nonnegative");
penRadius = r;
float scaledPenRadius = (float) (r * DEFAULT_SIZE);
BasicStroke stroke = new
BasicStroke(scaledPenRadius, BasicStroke.CAP_ROUND,
BasicStroke.JOIN_ROUND);
// BasicStroke stroke = new
BasicStroke(scaledPenRadius);
offscreen.setStroke(stroke);
}
/**
* Get the current pen color.
*/
public static Color getPenColor() { return penColor; }
/**
* Set the pen color to the default color (black).
*/
public static void setPenColor() {
setPenColor(DEFAULT_PEN_COLOR); }
/**
* Set the pen color to the given color. The available
pen colors are
* BLACK, BLUE, CYAN, DARK_GRAY, GRAY, GREEN,
LIGHT_GRAY, MAGENTA,
* ORANGE, PINK, RED, WHITE, and YELLOW.
* @param color the Color to make the pen
*/
public static void setPenColor(Color color) {

penColor = color;
offscreen.setColor(penColor);
}
/**
* Set the pen color to the given RGB color.
* @param red the amount of red (between 0 and 255)
* @param green the amount of green (between 0 and 255)
* @param blue the amount of blue (between 0 and 255)
* @throws IllegalArgumentException if the amount of
red, green, or blue are outside prescribed range
*/
public static void setPenColor(int red, int green, int
blue) {
if (red
< 0 || red
>= 256) throw new
IllegalArgumentException("amount of red must be between 0
and 255");
if (green < 0 || green >= 256) throw new
IllegalArgumentException("amount of green must be between 0
and 255");
if (blue < 0 || blue >= 256) throw new
IllegalArgumentException("amount of blue must be between 0
and 255");
setPenColor(new Color(red, green, blue));
}
/**
* Get the current font.
*/
public static Font getFont() { return font; }
/**
* Set the font to the default font (sans serif, 16
point).
*/
public static void setFont() { setFont(DEFAULT_FONT); }
/**
* Set the font to the given value.
* @param f the font to make text
*/
public static void setFont(Font f) { font = f; }

/**********************************************************
***************

Drawing geometric shapes.

***********************************************************
**************/
/**
* Draw a line from (x0, y0) to (x1, y1).
* @param x0 the x-coordinate of the starting point
* @param y0 the y-coordinate of the starting point
* @param x1 the x-coordinate of the destination point
* @param y1 the y-coordinate of the destination point
*/
public static void line(double x0, double y0, double x1,
double y1) {
offscreen.draw(new Line2D.Double(scaleX(x0),
scaleY(y0), scaleX(x1), scaleY(y1)));
draw();
}
/**
* Draw one pixel at (x, y).
* @param x the x-coordinate of the pixel
* @param y the y-coordinate of the pixel
*/
private static void pixel(double x, double y) {
offscreen.fillRect((int) Math.round(scaleX(x)),
(int) Math.round(scaleY(y)), 1, 1);
}
/**
* Draw a point at (x, y).
* @param x the x-coordinate of the point
* @param y the y-coordinate of the point
*/
public static void point(double x, double y) {
double xs = scaleX(x);
double ys = scaleY(y);
double r = penRadius;
float scaledPenRadius = (float) (r * DEFAULT_SIZE);
// double ws = factorX(2*r);
// double hs = factorY(2*r);
// if (ws <= 1 && hs <= 1) pixel(x, y);
if (scaledPenRadius <= 1) pixel(x, y);
else offscreen.fill(new Ellipse2D.Double(xs scaledPenRadius/2, ys - scaledPenRadius/2,

scaledPenRadius, scaledPenRadius));
draw();
}
/**
* Draw a circle of radius r, centered on (x, y).
* @param x the x-coordinate of the center of the
circle
* @param y the y-coordinate of the center of the
circle
* @param r the radius of the circle
* @throws IllegalArgumentException if the radius of
the circle is negative
*/
public static void circle(double x, double y, double r)
{
if (r < 0) throw new
IllegalArgumentException("circle radius must be
nonnegative");
double xs = scaleX(x);
double ys = scaleY(y);
double ws = factorX(2*r);
double hs = factorY(2*r);
if (ws <= 1 && hs <= 1) pixel(x, y);
else offscreen.draw(new Ellipse2D.Double(xs - ws/2,
ys - hs/2, ws, hs));
draw();
}
/**
* Draw filled circle of radius r, centered on (x, y).
* @param x the x-coordinate of the center of the
circle
* @param y the y-coordinate of the center of the
circle
* @param r the radius of the circle
* @throws IllegalArgumentException if the radius of
the circle is negative
*/
public static void filledCircle(double x, double y,
double r) {
if (r < 0) throw new
IllegalArgumentException("circle radius must be
nonnegative");
double xs = scaleX(x);
double ys = scaleY(y);

double ws = factorX(2*r);
double hs = factorY(2*r);
if (ws <= 1 && hs <= 1) pixel(x, y);
else offscreen.fill(new Ellipse2D.Double(xs - ws/2,
ys - hs/2, ws, hs));
draw();
}
/**
* Draw an ellipse with given semimajor and semiminor
axes, centered on (x, y).
* @param x the x-coordinate of the center of the
ellipse
* @param y the y-coordinate of the center of the
ellipse
* @param semiMajorAxis is the semimajor axis of the
ellipse
* @param semiMinorAxis is the semiminor axis of the
ellipse
* @throws IllegalArgumentException if either of the
axes are negative
*/
public static void ellipse(double x, double y, double
semiMajorAxis, double semiMinorAxis) {
if (semiMajorAxis < 0) throw new
IllegalArgumentException("ellipse semimajor axis must be
nonnegative");
if (semiMinorAxis < 0) throw new
IllegalArgumentException("ellipse semiminor axis must be
nonnegative");
double xs = scaleX(x);
double ys = scaleY(y);
double ws = factorX(2*semiMajorAxis);
double hs = factorY(2*semiMinorAxis);
if (ws <= 1 && hs <= 1) pixel(x, y);
else offscreen.draw(new Ellipse2D.Double(xs - ws/2,
ys - hs/2, ws, hs));
draw();
}
/**
* Draw an ellipse with given semimajor and semiminor
axes, centered on (x, y).
* @param x the x-coordinate of the center of the
ellipse

* @param y the y-coordinate of the center of the


ellipse
* @param semiMajorAxis is the semimajor axis of the
ellipse
* @param semiMinorAxis is the semiminor axis of the
ellipse
* @throws IllegalArgumentException if either of the
axes are negative
*/
public static void filledEllipse(double x, double y,
double semiMajorAxis, double semiMinorAxis) {
if (semiMajorAxis < 0) throw new
IllegalArgumentException("ellipse semimajor axis must be
nonnegative");
if (semiMinorAxis < 0) throw new
IllegalArgumentException("ellipse semiminor axis must be
nonnegative");
double xs = scaleX(x);
double ys = scaleY(y);
double ws = factorX(2*semiMajorAxis);
double hs = factorY(2*semiMinorAxis);
if (ws <= 1 && hs <= 1) pixel(x, y);
else offscreen.fill(new Ellipse2D.Double(xs - ws/2,
ys - hs/2, ws, hs));
draw();
}
/**
* Draw an arc of radius r, centered on (x, y), from
angle1 to angle2 (in degrees).
* @param x the x-coordinate of the center of the
circle
* @param y the y-coordinate of the center of the
circle
* @param r the radius of the circle
* @param angle1 the starting angle. 0 would mean an
arc beginning at 3 o'clock.
* @param angle2 the angle at the end of the arc. For
example, if
*
you want a 90 degree arc, then angle2 should
be angle1 + 90.
* @throws IllegalArgumentException if the radius of
the circle is negative
*/
public static void arc(double x, double y, double r,
double angle1, double angle2) {

if (r < 0) throw new IllegalArgumentException("arc


radius must be nonnegative");
while (angle2 < angle1) angle2 += 360;
double xs = scaleX(x);
double ys = scaleY(y);
double ws = factorX(2*r);
double hs = factorY(2*r);
if (ws <= 1 && hs <= 1) pixel(x, y);
else offscreen.draw(new Arc2D.Double(xs - ws/2, ys hs/2, ws, hs, angle1, angle2 - angle1, Arc2D.OPEN));
draw();
}
/**
* Draw a square of side length 2r, centered on (x, y).
* @param x the x-coordinate of the center of the
square
* @param y the y-coordinate of the center of the
square
* @param r radius is half the length of any side of
the square
* @throws IllegalArgumentException if r is negative
*/
public static void square(double x, double y, double r)
{
if (r < 0) throw new
IllegalArgumentException("square side length must be
nonnegative");
double xs = scaleX(x);
double ys = scaleY(y);
double ws = factorX(2*r);
double hs = factorY(2*r);
if (ws <= 1 && hs <= 1) pixel(x, y);
else offscreen.draw(new Rectangle2D.Double(xs ws/2, ys - hs/2, ws, hs));
draw();
}
/**
* Draw a
(x, y).
* @param
square
* @param
square
* @param
the square

filled square of side length 2r, centered on


x the x-coordinate of the center of the
y the y-coordinate of the center of the
r radius is half the length of any side of

* @throws IllegalArgumentException if r is negative


*/
public static void filledSquare(double x, double y,
double r) {
if (r < 0) throw new
IllegalArgumentException("square side length must be
nonnegative");
double xs = scaleX(x);
double ys = scaleY(y);
double ws = factorX(2*r);
double hs = factorY(2*r);
if (ws <= 1 && hs <= 1) pixel(x, y);
else offscreen.fill(new Rectangle2D.Double(xs ws/2, ys - hs/2, ws, hs));
draw();
}
/**
* Draw a rectangle of given half width and half
height, centered on (x, y).
* @param x the x-coordinate of the center of the
rectangle
* @param y the y-coordinate of the center of the
rectangle
* @param halfWidth is half the width of the rectangle
* @param halfHeight is half the height of the
rectangle
* @throws IllegalArgumentException if halfWidth or
halfHeight is negative
*/
public static void rectangle(double x, double y, double
halfWidth, double halfHeight) {
if (halfWidth < 0) throw new
IllegalArgumentException("half width must be nonnegative");
if (halfHeight < 0) throw new
IllegalArgumentException("half height must be nonnegative");
double xs = scaleX(x);
double ys = scaleY(y);
double ws = factorX(2*halfWidth);
double hs = factorY(2*halfHeight);
if (ws <= 1 && hs <= 1) pixel(x, y);
else offscreen.draw(new Rectangle2D.Double(xs ws/2, ys - hs/2, ws, hs));
draw();
}

/**
* Draw a filled rectangle of given half width and half
height, centered on (x, y).
* @param x the x-coordinate of the center of the
rectangle
* @param y the y-coordinate of the center of the
rectangle
* @param halfWidth is half the width of the rectangle
* @param halfHeight is half the height of the
rectangle
* @throws IllegalArgumentException if halfWidth or
halfHeight is negative
*/
public static void filledRectangle(double x, double y,
double halfWidth, double halfHeight) {
if (halfWidth < 0) throw new
IllegalArgumentException("half width must be nonnegative");
if (halfHeight < 0) throw new
IllegalArgumentException("half height must be nonnegative");
double xs = scaleX(x);
double ys = scaleY(y);
double ws = factorX(2*halfWidth);
double hs = factorY(2*halfHeight);
if (ws <= 1 && hs <= 1) pixel(x, y);
else offscreen.fill(new Rectangle2D.Double(xs ws/2, ys - hs/2, ws, hs));
draw();
}
/**
* Draw a polygon with the given (x[i], y[i])
coordinates.
* @param x an array of all the x-coordinates of the
polygon
* @param y an array of all the y-coordinates of the
polygon
*/
public static void polygon(double[] x, double[] y) {
int N = x.length;
GeneralPath path = new GeneralPath();
path.moveTo((float) scaleX(x[0]), (float)
scaleY(y[0]));
for (int i = 0; i < N; i++)
path.lineTo((float) scaleX(x[i]), (float)
scaleY(y[i]));
path.closePath();

offscreen.draw(path);
draw();
}
/**
* Draw a filled polygon with the given (x[i], y[i])
coordinates.
* @param x an array of all the x-coordinates of the
polygon
* @param y an array of all the y-coordinates of the
polygon
*/
public static void filledPolygon(double[] x, double[] y)
{
int N = x.length;
GeneralPath path = new GeneralPath();
path.moveTo((float) scaleX(x[0]), (float)
scaleY(y[0]));
for (int i = 0; i < N; i++)
path.lineTo((float) scaleX(x[i]), (float)
scaleY(y[i]));
path.closePath();
offscreen.fill(path);
draw();
}

/**********************************************************
***************
* Drawing images.
***********************************************************
**************/
// get an image from the given filename
private static Image getImage(String filename) {
// to read from file
ImageIcon icon = new ImageIcon(filename);
// try to read from URL
if ((icon == null) || (icon.getImageLoadStatus() !=
MediaTracker.COMPLETE)) {
try {
URL url = new URL(filename);

icon = new ImageIcon(url);


}
catch (Exception e) {
/* not a url */
}
}
// in case file is inside a .jar
if ((icon == null) || (icon.getImageLoadStatus() !=
MediaTracker.COMPLETE)) {
URL url = StdDraw.class.getResource(filename);
if (url == null) throw new
IllegalArgumentException("image " + filename + " not
found");
icon = new ImageIcon(url);
}
return icon.getImage();
}
/**
* Draw picture (gif, jpg, or png) centered on (x, y).
* @param x the center x-coordinate of the image
* @param y the center y-coordinate of the image
* @param s the name of the image/picture, e.g.,
"ball.gif"
* @throws IllegalArgumentException if the image is
corrupt
*/
public static void picture(double x, double y, String s)
{
Image image = getImage(s);
double xs = scaleX(x);
double ys = scaleY(y);
int ws = image.getWidth(null);
int hs = image.getHeight(null);
if (ws < 0 || hs < 0) throw new
IllegalArgumentException("image " + s + " is corrupt");
offscreen.drawImage(image, (int) Math.round(xs ws/2.0), (int) Math.round(ys - hs/2.0), null);
draw();
}
/**
* Draw picture (gif, jpg, or png) centered on (x, y),
* rotated given number of degrees.

* @param x the center x-coordinate of the image


* @param y the center y-coordinate of the image
* @param s the name of the image/picture, e.g.,
"ball.gif"
* @param degrees is the number of degrees to rotate
counterclockwise
* @throws IllegalArgumentException if the image is
corrupt
*/
public static void picture(double x, double y, String s,
double degrees) {
Image image = getImage(s);
double xs = scaleX(x);
double ys = scaleY(y);
int ws = image.getWidth(null);
int hs = image.getHeight(null);
if (ws < 0 || hs < 0) throw new
IllegalArgumentException("image " + s + " is corrupt");
offscreen.rotate(Math.toRadians(-degrees), xs, ys);
offscreen.drawImage(image, (int) Math.round(xs ws/2.0), (int) Math.round(ys - hs/2.0), null);
offscreen.rotate(Math.toRadians(+degrees), xs, ys);
draw();
}
/**
* Draw picture (gif, jpg, or png) centered on (x, y),
rescaled to w-by-h.
* @param x the center x coordinate of the image
* @param y the center y coordinate of the image
* @param s the name of the image/picture, e.g.,
"ball.gif"
* @param w the width of the image
* @param h the height of the image
* @throws IllegalArgumentException if the width height
are negative
* @throws IllegalArgumentException if the image is
corrupt
*/
public static void picture(double x, double y, String s,
double w, double h) {
Image image = getImage(s);
double xs = scaleX(x);
double ys = scaleY(y);

if (w < 0) throw new IllegalArgumentException("width


is negative: " + w);
if (h < 0) throw new
IllegalArgumentException("height is negative: " + h);
double ws = factorX(w);
double hs = factorY(h);
if (ws < 0 || hs < 0) throw new
IllegalArgumentException("image " + s + " is corrupt");
if (ws <= 1 && hs <= 1) pixel(x, y);
else {
offscreen.drawImage(image, (int) Math.round(xs ws/2.0),
(int) Math.round(ys hs/2.0),
(int) Math.round(ws),
(int) Math.round(hs),
null);
}
draw();
}
/**
* Draw picture (gif, jpg, or png) centered on (x, y),
rotated
* given number of degrees, rescaled to w-by-h.
* @param x the center x-coordinate of the image
* @param y the center y-coordinate of the image
* @param s the name of the image/picture, e.g.,
"ball.gif"
* @param w the width of the image
* @param h the height of the image
* @param degrees is the number of degrees to rotate
counterclockwise
* @throws IllegalArgumentException if the image is
corrupt
*/
public static void picture(double x, double y, String s,
double w, double h, double degrees) {
Image image = getImage(s);
double xs = scaleX(x);
double ys = scaleY(y);
double ws = factorX(w);
double hs = factorY(h);
if (ws < 0 || hs < 0) throw new
IllegalArgumentException("image " + s + " is corrupt");
if (ws <= 1 && hs <= 1) pixel(x, y);

offscreen.rotate(Math.toRadians(-degrees), xs, ys);


offscreen.drawImage(image, (int) Math.round(xs ws/2.0),
(int) Math.round(ys hs/2.0),
(int) Math.round(ws),
(int) Math.round(hs),
null);
offscreen.rotate(Math.toRadians(+degrees), xs, ys);
draw();
}

/**********************************************************
***************
* Drawing text.
***********************************************************
**************/
/**
* Write the given text string in the current font,
centered on (x, y).
* @param x the center x-coordinate of the text
* @param y the center y-coordinate of the text
* @param s the text
*/
public static void text(double x, double y, String s) {
offscreen.setFont(font);
FontMetrics metrics = offscreen.getFontMetrics();
double xs = scaleX(x);
double ys = scaleY(y);
int ws = metrics.stringWidth(s);
int hs = metrics.getDescent();
offscreen.drawString(s, (float) (xs - ws/2.0),
(float) (ys + hs));
draw();
}
/**
* Write the given text string in the current font,
centered on (x, y) and
* rotated by the specified number of degrees.
* @param x the center x-coordinate of the text

* @param y the center y-coordinate of the text


* @param s the text
* @param degrees is the number of degrees to rotate
counterclockwise
*/
public static void text(double x, double y, String s,
double degrees) {
double xs = scaleX(x);
double ys = scaleY(y);
offscreen.rotate(Math.toRadians(-degrees), xs, ys);
text(x, y, s);
offscreen.rotate(Math.toRadians(+degrees), xs, ys);
}
/**
* Write the given text string in the current font,
left-aligned at (x, y).
* @param x the x-coordinate of the text
* @param y the y-coordinate of the text
* @param s the text
*/
public static void textLeft(double x, double y, String
s) {
offscreen.setFont(font);
FontMetrics metrics = offscreen.getFontMetrics();
double xs = scaleX(x);
double ys = scaleY(y);
int hs = metrics.getDescent();
offscreen.drawString(s, (float) (xs), (float) (ys +
hs));
draw();
}
/**
* Write the given text string in the current font,
right-aligned at (x, y).
* @param x the x-coordinate of the text
* @param y the y-coordinate of the text
* @param s the text
*/
public static void textRight(double x, double y, String
s) {
offscreen.setFont(font);
FontMetrics metrics = offscreen.getFontMetrics();
double xs = scaleX(x);
double ys = scaleY(y);

int ws = metrics.stringWidth(s);
int hs = metrics.getDescent();
offscreen.drawString(s, (float) (xs - ws), (float)
(ys + hs));
draw();
}

/**
* Display on screen, pause for t milliseconds, and
turn on
* <em>animation mode</em>: subsequent calls to
* drawing methods such as <tt>line()</tt>,
<tt>circle()</tt>, and <tt>square()</tt>
* will not be displayed on screen until the next call
to <tt>show()</tt>.
* This is useful for producing animations (clear the
screen, draw a bunch of shapes,
* display on screen for a fixed amount of time, and
repeat). It also speeds up
* drawing a huge number of shapes (call
<tt>show(0)</tt> to defer drawing
* on screen, draw the shapes, and call <tt>show(0)</tt>
to display them all
* on screen at once).
* @param t number of milliseconds
*/
public static void show(int t) {
// sleep until the next time we're allowed to draw
long millis = System.currentTimeMillis();
if (millis < nextDraw) {
try {
Thread.sleep(nextDraw - millis);
}
catch (InterruptedException e) {
System.out.println("Error sleeping");
}
millis = nextDraw;
}
defer = false;
draw();
defer = true;
// when are we allowed to draw again
nextDraw = millis + t;

}
/**
* Display on-screen and turn off animation mode:
* subsequent calls to
* drawing methods such as <tt>line()</tt>,
<tt>circle()</tt>, and <tt>square()</tt>
* will be displayed on screen when called. This is the
default.
*/
public static void show() {
defer = false;
nextDraw = -1;
draw();
}
// draw onscreen if defer is false
private static void draw() {
if (defer) return;
onscreen.drawImage(offscreenImage, 0, 0, null);
frame.repaint();
}

/**********************************************************
***************
* Save drawing to a file.
***********************************************************
**************/
/**
* Save onscreen image to file - suffix must be png,
jpg, or gif.
* @param filename the name of the file with one of the
required suffixes
*/
public static void save(String filename) {
File file = new File(filename);
String suffix =
filename.substring(filename.lastIndexOf('.') + 1);
// png files
if (suffix.toLowerCase().equals("png")) {
try {
ImageIO.write(onscreenImage, suffix, file);

}
catch (IOException e) {
e.printStackTrace();
}
}
// need to change from ARGB to RGB for jpeg
// reference: http://archives.java.sun.com/cgibin/wa?A2=ind0404&L=java2d-interest&D=0&P=2727
else if (suffix.toLowerCase().equals("jpg")) {
WritableRaster raster =
onscreenImage.getRaster();
WritableRaster newRaster;
newRaster = raster.createWritableChild(0, 0,
width, height, 0, 0, new int[] {0, 1, 2});
DirectColorModel cm = (DirectColorModel)
onscreenImage.getColorModel();
DirectColorModel newCM = new
DirectColorModel(cm.getPixelSize(),
cm.getRedMask(),
cm.getGreenMask(),
cm.getBlueMask());
BufferedImage rgbBuffer = new
BufferedImage(newCM, newRaster, false, null);
try {
ImageIO.write(rgbBuffer, suffix, file);
}
catch (IOException e) {
e.printStackTrace();
}
}
else {
System.out.println("Invalid image file type: " +
suffix);
}
}
/**
* This method cannot be called directly.
*/
public void actionPerformed(ActionEvent e) {
FileDialog chooser = new FileDialog(StdDraw.frame,
"Use a .png or .jpg extension", FileDialog.SAVE);

chooser.setVisible(true);
String filename = chooser.getFile();
if (filename != null) {
StdDraw.save(chooser.getDirectory() +
File.separator + chooser.getFile());
}
}

/**********************************************************
***************
* Mouse interactions.
***********************************************************
**************/
/**
* Is the mouse being pressed?
* @return true or false
*/
public static boolean mousePressed() {
synchronized (mouseLock) {
return mousePressed;
}
}
/**
* What is the x-coordinate of the mouse?
* @return the value of the x-coordinate of the mouse
*/
public static double mouseX() {
synchronized (mouseLock) {
return mouseX;
}
}
/**
* What is the y-coordinate of the mouse?
* @return the value of the y-coordinate of the mouse
*/
public static double mouseY() {
synchronized (mouseLock) {
return mouseY;
}
}

/**
* This method cannot be called directly.
*/
public void mouseClicked(MouseEvent e) { }
/**
* This method cannot be called directly.
*/
public void mouseEntered(MouseEvent e) { }
/**
* This method cannot be called directly.
*/
public void mouseExited(MouseEvent e) { }
/**
* This method cannot be called directly.
*/
public void mousePressed(MouseEvent e) {
synchronized (mouseLock) {
mouseX = StdDraw.userX(e.getX());
mouseY = StdDraw.userY(e.getY());
mousePressed = true;
}
}
/**
* This method cannot be called directly.
*/
public void mouseReleased(MouseEvent e) {
synchronized (mouseLock) {
mousePressed = false;
}
}
/**
* This method cannot be called directly.
*/
public void mouseDragged(MouseEvent e) {
synchronized (mouseLock) {
mouseX = StdDraw.userX(e.getX());
mouseY = StdDraw.userY(e.getY());
}
}
/**

* This method cannot be called directly.


*/
public void mouseMoved(MouseEvent e) {
synchronized (mouseLock) {
mouseX = StdDraw.userX(e.getX());
mouseY = StdDraw.userY(e.getY());
}
}

/**********************************************************
***************
* Keyboard interactions.
***********************************************************
**************/
/**
* Has the user typed a key?
* @return true if the user has typed a key, false
otherwise
*/
public static boolean hasNextKeyTyped() {
synchronized (keyLock) {
return !keysTyped.isEmpty();
}
}
/**
* What is the next key that was typed by the user?
This method returns
* a Unicode character corresponding to the key typed
(such as 'a' or 'A').
* It cannot identify action keys (such as F1
* and arrow keys) or modifier keys (such as control).
* @return the next Unicode key typed
*/
public static char nextKeyTyped() {
synchronized (keyLock) {
return keysTyped.removeLast();
}
}
/**
* Is the keycode currently being pressed? This method
takes as an argument

* the keycode (corresponding to a physical key). It


can handle action keys
* (such as F1 and arrow keys) and modifier keys (such
as shift and control).
* See <a href =
"http://download.oracle.com/javase/6/docs/api/java/awt/event
/KeyEvent.html">KeyEvent.java</a>
* for a description of key codes.
* @return true if keycode is currently being pressed,
false otherwise
*/
public static boolean isKeyPressed(int keycode) {
synchronized (keyLock) {
return keysDown.contains(keycode);
}
}
/**
* This method cannot be called directly.
*/
public void keyTyped(KeyEvent e) {
synchronized (keyLock) {
keysTyped.addFirst(e.getKeyChar());
}
}
/**
* This method cannot be called directly.
*/
public void keyPressed(KeyEvent e) {
synchronized (keyLock) {
keysDown.add(e.getKeyCode());
}
}
/**
* This method cannot be called directly.
*/
public void keyReleased(KeyEvent e) {
synchronized (keyLock) {
keysDown.remove(e.getKeyCode());
}
}

/**
* Test client.
*/
public static void main(String[] args) {
StdDraw.square(.2, .8, .1);
StdDraw.filledSquare(.8, .8, .2);
StdDraw.circle(.8, .2, .2);
StdDraw.setPenColor(StdDraw.BOOK_RED);
StdDraw.setPenRadius(.02);
StdDraw.arc(.8, .2, .1, 200, 45);
// draw a blue diamond
StdDraw.setPenRadius();
StdDraw.setPenColor(StdDraw.BOOK_BLUE);
double[] x = { .1, .2, .3, .2 };
double[] y = { .2, .3, .2, .1 };
StdDraw.filledPolygon(x, y);
// text
StdDraw.setPenColor(StdDraw.BLACK);
StdDraw.text(0.2, 0.5, "black text");
StdDraw.setPenColor(StdDraw.WHITE);
StdDraw.text(0.8, 0.8, "white text");
}
}
Copyright 20002011, Robert Sedgewick and Kevin Wayne.
Last updated: Fri Jul 24 09:39:19 EDT 2015.
StdAudio.java
Below is the syntax highlighted version
of StdAudio.java from Standard Libraries.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac StdAudio.java
* Execution:
java StdAudio
* Dependencies: none

*
* Simple library for reading, writing, and
manipulating .wav files.
*
* Limitations
* ----------*
- Does not seem to work properly when reading .wav
files from a .jar file.
*
- Assumes the audio is monaural, with sampling rate
of 44,100.
*
***********************************************************
**************/
import java.applet.AudioClip;
import java.applet.Applet;
import java.io.File;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import
import
import
import
import
import
import
import

javax.sound.sampled.AudioFileFormat;
javax.sound.sampled.AudioFormat;
javax.sound.sampled.AudioInputStream;
javax.sound.sampled.AudioSystem;
javax.sound.sampled.DataLine;
javax.sound.sampled.LineUnavailableException;
javax.sound.sampled.SourceDataLine;
javax.sound.sampled.UnsupportedAudioFileException;

/**
* <i>Standard audio</i>. This class provides a basic
capability for
* creating, reading, and saving audio.
* <p>
* The audio format uses a sampling rate of 44,100 (CD
quality audio), 16-bit, monaural.
*
* <p>
* For additional documentation, see <a
href="http://introcs.cs.princeton.edu/15inout">Section
1.5</a> of

* <i>Introduction to Programming in Java: An


Interdisciplinary Approach</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public final class StdAudio {
/**
* The sample rate - 44,100 Hz for CD quality audio.
*/
public static final int SAMPLE_RATE = 44100;
private static
// 16-bit audio
private static
// 16-bit audio
private static
Short.MAX_VALUE;
private static

final int BYTES_PER_SAMPLE = 2;


final int BITS_PER_SAMPLE = 16;
final double MAX_16_BIT =
// 32,767
final int SAMPLE_BUFFER_SIZE = 4096;

private static SourceDataLine line;


sound
private static byte[] buffer;
buffer
private static int bufferSize = 0;
samples currently in internal buffer

// to play the
// our internal
// number of

private StdAudio() {
// can not instantiate
}
// static initializer
static {
init();
}
// open up an audio stream
private static void init() {
try {
// 44,100 samples per second, 16-bit audio,
mono, signed PCM, little Endian
AudioFormat format = new AudioFormat((float)
SAMPLE_RATE, BITS_PER_SAMPLE, 1, true, false);

DataLine.Info info = new


DataLine.Info(SourceDataLine.class, format);
line = (SourceDataLine)
AudioSystem.getLine(info);
line.open(format, SAMPLE_BUFFER_SIZE *
BYTES_PER_SAMPLE);
// the internal buffer is a fraction of the
actual buffer size, this choice is arbitrary
// it gets divided because we can't expect the
buffered data to line up exactly with when
// the sound card decides to push out its
samples.
buffer = new byte[SAMPLE_BUFFER_SIZE *
BYTES_PER_SAMPLE/3];
}
catch (LineUnavailableException e) {
System.out.println(e.getMessage());
System.exit(1);
}
// no sound gets made before this call
line.start();
}
/**
* Close standard audio.
*/
public static void close() {
line.drain();
line.stop();
}
/**
* Write one sample (between -1.0 and +1.0) to standard
audio. If the sample
* is outside the range, it will be clipped.
*/
public static void play(double in) {
// clip if outside [-1, +1]
if (in < -1.0) in = -1.0;
if (in > +1.0) in = +1.0;
// convert to bytes

short s = (short) (MAX_16_BIT * in);


buffer[bufferSize++] = (byte) s;
buffer[bufferSize++] = (byte) (s >> 8);

// little

Endian
// send to sound card if buffer is full
if (bufferSize >= buffer.length) {
line.write(buffer, 0, buffer.length);
bufferSize = 0;
}
}
/**
* Write an array of samples (between -1.0 and +1.0) to
standard audio. If a sample
* is outside the range, it will be clipped.
*/
public static void play(double[] input) {
for (int i = 0; i < input.length; i++) {
play(input[i]);
}
}
/**
* Read audio samples from a file (in .wav or .au
format) and return them as a double array
* with values between -1.0 and +1.0.
*/
public static double[] read(String filename) {
byte[] data = readByte(filename);
int N = data.length;
double[] d = new double[N/2];
for (int i = 0; i < N/2; i++) {
d[i] = ((short) (((data[2*i+1] & 0xFF) << 8) +
(data[2*i] & 0xFF))) / ((double) MAX_16_BIT);
}
return d;
}

/**
* Play a sound file (in .wav, .mid, or .au format) in
a background thread.
*/
public static void play(String filename) {

URL url = null;


try {
File file = new File(filename);
if (file.canRead()) url = file.toURI().toURL();
}
catch (MalformedURLException e) {
e.printStackTrace();
}
// URL url = StdAudio.class.getResource(filename);
if (url == null) throw new RuntimeException("audio "
+ filename + " not found");
AudioClip clip = Applet.newAudioClip(url);
clip.play();
}
/**
* Loop a sound file (in .wav, .mid, or .au format) in
a background thread.
*/
public static void loop(String filename) {
URL url = null;
try {
File file = new File(filename);
if (file.canRead()) url = file.toURI().toURL();
}
catch (MalformedURLException e) {
e.printStackTrace();
}
// URL url = StdAudio.class.getResource(filename);
if (url == null) throw new RuntimeException("audio "
+ filename + " not found");
AudioClip clip = Applet.newAudioClip(url);
clip.loop();
}
// return data as a byte array
private static byte[] readByte(String filename) {
byte[] data = null;
AudioInputStream ais = null;
try {
// try to read from file
File file = new File(filename);
if (file.exists()) {
ais = AudioSystem.getAudioInputStream(file);
data = new byte[ais.available()];

ais.read(data);
}
// try to read from URL
else {
URL url =
StdAudio.class.getResource(filename);
ais = AudioSystem.getAudioInputStream(url);
data = new byte[ais.available()];
ais.read(data);
}
}
catch (IOException e) {
System.out.println(e.getMessage());
throw new RuntimeException("Could not read " +
filename);
}
catch (UnsupportedAudioFileException e) {
System.out.println(e.getMessage());
throw new RuntimeException(filename + " in
unsupported audio format");
}
return data;
}

/**
* Save the double array as a sound file (using .wav or
.au format).
*/
public static void save(String filename, double[] input)
{
// assumes 44,100 samples per second
// use 16-bit audio, mono, signed PCM, little
Endian
AudioFormat format = new AudioFormat(SAMPLE_RATE,
16, 1, true, false);
byte[] data = new byte[2 * input.length];
for (int i = 0; i < input.length; i++) {
int temp = (short) (input[i] * MAX_16_BIT);
data[2*i + 0] = (byte) temp;
data[2*i + 1] = (byte) (temp >> 8);
}

// now save the file


try {
ByteArrayInputStream bais = new
ByteArrayInputStream(data);
AudioInputStream ais = new
AudioInputStream(bais, format, input.length);
if (filename.endsWith(".wav") ||
filename.endsWith(".WAV")) {
AudioSystem.write(ais,
AudioFileFormat.Type.WAVE, new File(filename));
}
else if (filename.endsWith(".au") ||
filename.endsWith(".AU")) {
AudioSystem.write(ais,
AudioFileFormat.Type.AU, new File(filename));
}
else {
throw new RuntimeException("File format not
supported: " + filename);
}
}
catch (IOException e) {
System.out.println(e);
System.exit(1);
}
}

/**********************************************************
*************
* Sample test client.
***********************************************************
************/
// create a note (sine wave) of the given frequency
(Hz), for the given
// duration (seconds) scaled to the given volume
(amplitude)
private static double[] note(double hz, double duration,
double amplitude) {
int N = (int) (StdAudio.SAMPLE_RATE * duration);
double[] a = new double[N+1];

for (int i = 0; i <= N; i++)


a[i] = amplitude * Math.sin(2 * Math.PI * i * hz
/ StdAudio.SAMPLE_RATE);
return a;
}
/**
* Test client - play an A major scale to standard
audio.
*/
public static void main(String[] args) {
// 440 Hz for 1 sec
double freq = 440.0;
for (int i = 0; i <= StdAudio.SAMPLE_RATE; i++) {
StdAudio.play(0.5 * Math.sin(2*Math.PI * freq *
i / StdAudio.SAMPLE_RATE));
}
// scale increments
int[] steps = { 0, 2, 4, 5, 7, 9, 11, 12 };
for (int i = 0; i < steps.length; i++) {
double hz = 440.0 * Math.pow(2, steps[i] /
12.0);
StdAudio.play(note(hz, 1.0, 0.5));
}
// need to call this in non-interactive stuff so
the program doesn't terminate
// until all the sound leaves the speaker.
StdAudio.close();
// need to terminate a Java program with sound
System.exit(0);
}
}
Copyright 20002011, Robert Sedgewick and Kevin Wayne.
Last updated: Fri Jul 24 09:39:19 EDT 2015.
StdRandom.java
Below is the syntax highlighted version
of StdRandom.java from Standard Libraries.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac StdRandom.java
* Execution:
java StdRandom
* Dependencies: StdOut.java
*
* A library of static methods to generate pseudo-random
numbers from
* different distributions (bernoulli, uniform, gaussian,
discrete,
* and exponential). Also includes a method for shuffling
an array.
*
*
* % java StdRandom 5
* seed = 1316600602069
* 59 16.81826 true 8.83954 0
* 32 91.32098 true 9.11026 0
* 35 10.11874 true 8.95396 3
* 92 32.88401 true 8.87089 0
* 72 92.55791 true 9.46241 0
*
* % java StdRandom 5
* seed = 1316600616575
* 96 60.17070 true 8.72821 0
* 79 32.01607 true 8.58159 0
* 81 59.49065 true 9.10423 1
* 96 51.65818 true 9.02102 0
* 99 17.55771 true 8.99762 0
*
* % java StdRandom 5 1316600616575
* seed = 1316600616575
* 96 60.17070 true 8.72821 0
* 79 32.01607 true 8.58159 0
* 81 59.49065 true 9.10423 1
* 96 51.65818 true 9.02102 0
* 99 17.55771 true 8.99762 0
*
*
* Remark
* -----*
- Relies on randomness of nextDouble() method in
java.util.Random
*
to generate pseudorandom numbers in [0, 1).

*
*
- This library allows you to set and get the
pseudorandom number seed.
*
*
- See http://www.honeylocust.com/RngPack/ for an
industrial
*
strength random number generator in Java.
*
***********************************************************
**************/
import java.util.Random;
/**
* <i>Standard random</i>. This class provides methods for
generating
* random number from various distributions.
* <p>
* For additional documentation, see <a
href="http://introcs.cs.princeton.edu/22library">Section
2.2</a> of
* <i>Introduction to Programming in Java: An
Interdisciplinary Approach</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public final class StdRandom {
private static Random random;
number generator
private static long seed;
number generator seed

// pseudo-random
// pseudo-random

// static initializer
static {
// this is how the seed was set in Java 1.4
seed = System.currentTimeMillis();
random = new Random(seed);
}
// don't instantiate
private StdRandom() { }
/**

* Sets the seed of the psedurandom number generator.


*/
public static void setSeed(long s) {
seed
= s;
random = new Random(seed);
}
/**
* Returns the seed of the psedurandom number
generator.
*/
public static long getSeed() {
return seed;
}
/**
* Return real number uniformly in [0, 1).
*/
public static double uniform() {
return random.nextDouble();
}
/**
* Returns an integer uniformly between 0 (inclusive)
and N (exclusive).
* @throws IllegalArgumentException if <tt>N <= 0</tt>
*/
public static int uniform(int N) {
if (N <= 0) throw new
IllegalArgumentException("Parameter N must be positive");
return random.nextInt(N);
}
///////////////////////////////////////////////////////
////////////////////
// STATIC METHODS BELOW RELY ON JAVA.UTIL.RANDOM ONLY
INDIRECTLY VIA
// THE STATIC METHODS ABOVE.
///////////////////////////////////////////////////////
////////////////////
/**
* Returns a real number uniformly in [0, 1).
* @deprecated clearer to use {@link #uniform()}
*/
public static double random() {
return uniform();

}
/**
* Returns an integer uniformly in [a, b).
* @throws IllegalArgumentException if <tt>b <= a</tt>
* @throws IllegalArgumentException if <tt>b - a >=
Integer.MAX_VALUE</tt>
*/
public static int uniform(int a, int b) {
if (b <= a) throw new
IllegalArgumentException("Invalid range");
if ((long) b - a >= Integer.MAX_VALUE) throw new
IllegalArgumentException("Invalid range");
return a + uniform(b - a);
}
/**
* Returns a real number uniformly in [a, b).
* @throws IllegalArgumentException unless <tt>a <
b</tt>
*/
public static double uniform(double a, double b) {
if (!(a < b)) throw new
IllegalArgumentException("Invalid range");
return a + uniform() * (b-a);
}
/**
* Returns a boolean, which is true with probability p,
and false otherwise.
* @throws IllegalArgumentException unless <tt>p >=
0.0</tt> and <tt>p <= 1.0</tt>
*/
public static boolean bernoulli(double p) {
if (!(p >= 0.0 && p <= 1.0))
throw new IllegalArgumentException("Probability
must be between 0.0 and 1.0");
return uniform() < p;
}
/**
* Returns a boolean, which is true with probability .
5, and false otherwise.
*/
public static boolean bernoulli() {
return bernoulli(0.5);
}

/**
* Returns a real number with a standard Gaussian
distribution.
*/
public static double gaussian() {
// use the polar form of the Box-Muller transform
double r, x, y;
do {
x = uniform(-1.0, 1.0);
y = uniform(-1.0, 1.0);
r = x*x + y*y;
} while (r >= 1 || r == 0);
return x * Math.sqrt(-2 * Math.log(r) / r);
// Remark: y * Math.sqrt(-2 * Math.log(r) / r)
// is an independent random gaussian
}
/**
* Returns a real number from a gaussian distribution
with given mean and stddev.
*/
public static double gaussian(double mean, double
stddev) {
return mean + stddev * gaussian();
}
/**
* Returns an integer with a geometric distribution
with mean 1/p.
* @throws IllegalArgumentException unless <tt>p >=
0.0</tt> and <tt>p <= 1.0</tt>
*/
public static int geometric(double p) {
if (!(p >= 0.0 && p <= 1.0))
throw new IllegalArgumentException("Probability
must be between 0.0 and 1.0");
// using algorithm given by Knuth
return (int) Math.ceil(Math.log(uniform()) /
Math.log(1.0 - p));
}
/**
* Return an integer with a Poisson distribution with
mean lambda.

* @throws IllegalArgumentException unless <tt>lambda >


0.0</tt> and not infinite
*/
public static int poisson(double lambda) {
if (!(lambda > 0.0))
throw new IllegalArgumentException("Parameter
lambda must be positive");
if (Double.isInfinite(lambda))
throw new IllegalArgumentException("Parameter
lambda must not be infinite");
// using algorithm given by Knuth
// see
http://en.wikipedia.org/wiki/Poisson_distribution
int k = 0;
double p = 1.0;
double L = Math.exp(-lambda);
do {
k++;
p *= uniform();
} while (p >= L);
return k-1;
}
/**
* Returns a real number with a Pareto distribution
with parameter alpha.
* @throws IllegalArgumentException unless <tt>alpha >
0.0</tt>
*/
public static double pareto(double alpha) {
if (!(alpha > 0.0))
throw new IllegalArgumentException("Shape
parameter alpha must be positive");
return Math.pow(1 - uniform(), -1.0/alpha) - 1.0;
}
/**
* Returns a real number with a Cauchy distribution.
*/
public static double cauchy() {
return Math.tan(Math.PI * (uniform() - 0.5));
}
/**
* Returns a number from a discrete distribution: i
with probability a[i].

* throws IllegalArgumentException if sum of array


entries is not (very nearly) equal to <tt>1.0</tt>
* throws IllegalArgumentException unless <tt>a[i] >=
0.0</tt> for each index <tt>i</tt>
*/
public static int discrete(double[] a) {
double EPSILON = 1E-14;
double sum = 0.0;
for (int i = 0; i < a.length; i++) {
if (!(a[i] >= 0.0)) throw new
IllegalArgumentException("array entry " + i + " must be
nonnegative: " + a[i]);
sum = sum + a[i];
}
if (sum > 1.0 + EPSILON || sum < 1.0 - EPSILON)
throw new IllegalArgumentException("sum of array
entries does not approximately equal 1.0: " + sum);
// the for loop may not return a value when both r
is (nearly) 1.0 and when the
// cumulative sum is less than 1.0 (as a result of
floating-point roundoff error)
while (true) {
double r = uniform();
sum = 0.0;
for (int i = 0; i < a.length; i++) {
sum = sum + a[i];
if (sum > r) return i;
}
}
}
/**
* Returns a real number from an exponential
distribution with rate lambda.
* @throws IllegalArgumentException unless <tt>lambda >
0.0</tt>
*/
public static double exp(double lambda) {
if (!(lambda > 0.0))
throw new IllegalArgumentException("Rate lambda
must be positive");
return -Math.log(1 - uniform()) / lambda;
}
/**
* Rearrange the elements of an array in random order.

*/
public static void shuffle(Object[] a) {
int N = a.length;
for (int i = 0; i < N; i++) {
int r = i + uniform(N-i);
// between i and
N-1
Object temp = a[i];
a[i] = a[r];
a[r] = temp;
}
}
/**
* Rearrange the elements of a double array in random
order.
*/
public static void shuffle(double[] a) {
int N = a.length;
for (int i = 0; i < N; i++) {
int r = i + uniform(N-i);
// between i and
N-1
double temp = a[i];
a[i] = a[r];
a[r] = temp;
}
}
/**
* Rearrange the elements of an int array in random
order.
*/
public static void shuffle(int[] a) {
int N = a.length;
for (int i = 0; i < N; i++) {
int r = i + uniform(N-i);
// between i and
N-1
int temp = a[i];
a[i] = a[r];
a[r] = temp;
}
}
/**
* Rearrange the elements of the subarray a[lo..hi] in
random order.
*/

public static void shuffle(Object[] a, int lo, int hi) {


if (lo < 0 || lo > hi || hi >= a.length) {
throw new IndexOutOfBoundsException("Illegal
subarray range");
}
for (int i = lo; i <= hi; i++) {
int r = i + uniform(hi-i+1);
// between i
and hi
Object temp = a[i];
a[i] = a[r];
a[r] = temp;
}
}
/**
* Rearrange the elements of the subarray a[lo..hi] in
random order.
*/
public static void shuffle(double[] a, int lo, int hi) {
if (lo < 0 || lo > hi || hi >= a.length) {
throw new IndexOutOfBoundsException("Illegal
subarray range");
}
for (int i = lo; i <= hi; i++) {
int r = i + uniform(hi-i+1);
// between i
and hi
double temp = a[i];
a[i] = a[r];
a[r] = temp;
}
}
/**
* Rearrange the elements of the subarray a[lo..hi] in
random order.
*/
public static void shuffle(int[] a, int lo, int hi) {
if (lo < 0 || lo > hi || hi >= a.length) {
throw new IndexOutOfBoundsException("Illegal
subarray range");
}
for (int i = lo; i <= hi; i++) {
int r = i + uniform(hi-i+1);
// between i
and hi
int temp = a[i];
a[i] = a[r];
a[r] = temp;

}
}
/**
* Unit test.
*/
public static void main(String[] args) {
int N = Integer.parseInt(args[0]);
if (args.length == 2)
StdRandom.setSeed(Long.parseLong(args[1]));
double[] t = { .5, .3, .1, .1 };
StdOut.println("seed = " + StdRandom.getSeed());
for (int i = 0; i < N; i++) {
StdOut.printf("%2d " , uniform(100));
StdOut.printf("%8.5f ", uniform(10.0, 99.0));
StdOut.printf("%5b " , bernoulli(.5));
StdOut.printf("%7.5f ", gaussian(9.0, .2));
StdOut.printf("%2d " , discrete(t));
StdOut.println();
}
String[] a = "A B C D E F G".split(" ");
for (String s : a)
StdOut.print(s + " ");
StdOut.println();
}
}
Copyright 20002011, Robert Sedgewick and Kevin Wayne.
Last updated: Thu Jul 23 09:50:06 EDT 2015.
StdStats.java
Below is the syntax highlighted version
of StdStats.java from Standard Libraries.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac StdStats.java
* Dependencies: StdOut.java

* Execution:
java StdStats < input.txt
*
* Library of statistical functions.
*
* The test client reads an array of real numbers from
standard
* input, and computes the minimum, mean, maximum, and
* standard deviation.
*
* The functions all throw a NullPointerException if the
array
* passed in is null.
*
* The floating-point functions all return NaN if any
input is NaN.
*
* Unlike Math.min() and Math.max(), the min() and max()
functions
* do not differentiate between -0.0 and 0.0.
*
* % more tiny.txt
* 5
* 3.0 1.0 2.0 5.0 4.0
*
* % java StdStats < tiny.txt
*
min
1.000
*
mean
3.000
*
max
5.000
*
std dev
1.581
*
* Should these funtions use varargs instead of array
arguments?
*
***********************************************************
**************/
/**
* <i>Standard statistics</i>. This class provides methods
for computing
* statistics such as min, max, mean, sample standard
deviation, and
* sample variance.
* <p>
* For additional documentation, see

* <a
href="http://introcs.cs.princeton.edu/22library">Section
2.2</a> of
* <i>Introduction to Programming in Java: An
Interdisciplinary Approach</i>
* by Robert Sedgewick and Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public final class StdStats {
private StdStats() { }
/**
* Returns the maximum value in the array a[],
-infinity if no such value.
*/
public static double max(double[] a) {
double max = Double.NEGATIVE_INFINITY;
for (int i = 0; i < a.length; i++) {
if (Double.isNaN(a[i])) return Double.NaN;
if (a[i] > max) max = a[i];
}
return max;
}
/**
* Returns the maximum value in the subarray
a[lo..hi], -infinity if no such value.
*/
public static double max(double[] a, int lo, int hi) {
if (lo < 0 || hi >= a.length || lo > hi)
throw new RuntimeException("Subarray indices out
of bounds");
double max = Double.NEGATIVE_INFINITY;
for (int i = lo; i <= hi; i++) {
if (Double.isNaN(a[i])) return Double.NaN;
if (a[i] > max) max = a[i];
}
return max;
}
/**
* Returns the maximum value in the array a[],
Integer.MIN_VALUE if no such value.
*/

public static int max(int[] a) {


int max = Integer.MIN_VALUE;
for (int i = 0; i < a.length; i++) {
if (a[i] > max) max = a[i];
}
return max;
}
/**
* Returns the minimum value in the array a[],
+infinity if no such value.
*/
public static double min(double[] a) {
double min = Double.POSITIVE_INFINITY;
for (int i = 0; i < a.length; i++) {
if (Double.isNaN(a[i])) return Double.NaN;
if (a[i] < min) min = a[i];
}
return min;
}
/**
* Returns the minimum value in the subarray
a[lo..hi], +infinity if no such value.
*/
public static double min(double[] a, int lo, int hi) {
if (lo < 0 || hi >= a.length || lo > hi)
throw new RuntimeException("Subarray indices out
of bounds");
double min = Double.POSITIVE_INFINITY;
for (int i = lo; i <= hi; i++) {
if (Double.isNaN(a[i])) return Double.NaN;
if (a[i] < min) min = a[i];
}
return min;
}
/**
* Returns the minimum value in the array a[],
Integer.MAX_VALUE if no such value.
*/
public static int min(int[] a) {
int min = Integer.MAX_VALUE;
for (int i = 0; i < a.length; i++) {
if (a[i] < min) min = a[i];
}
return min;

}
/**
* Returns the average value in the array a[], NaN if
no such value.
*/
public static double mean(double[] a) {
if (a.length == 0) return Double.NaN;
double sum = sum(a);
return sum / a.length;
}
/**
* Returns the average value in the subarray a[lo..hi],
NaN if no such value.
*/
public static double mean(double[] a, int lo, int hi) {
int length = hi - lo + 1;
if (lo < 0 || hi >= a.length || lo > hi)
throw new RuntimeException("Subarray indices out
of bounds");
if (length == 0) return Double.NaN;
double sum = sum(a, lo, hi);
return sum / length;
}
/**
* Returns the average value in the array a[], NaN if
no such value.
*/
public static double mean(int[] a) {
if (a.length == 0) return Double.NaN;
double sum = 0.0;
for (int i = 0; i < a.length; i++) {
sum = sum + a[i];
}
return sum / a.length;
}
/**
* Returns the sample variance in the array a[], NaN if
no such value.
*/
public static double var(double[] a) {
if (a.length == 0) return Double.NaN;
double avg = mean(a);
double sum = 0.0;

for (int i = 0; i < a.length; i++) {


sum += (a[i] - avg) * (a[i] - avg);
}
return sum / (a.length - 1);
}
/**
* Returns the sample variance in the subarray
a[lo..hi], NaN if no such value.
*/
public static double var(double[] a, int lo, int hi) {
int length = hi - lo + 1;
if (lo < 0 || hi >= a.length || lo > hi)
throw new RuntimeException("Subarray indices out
of bounds");
if (length == 0) return Double.NaN;
double avg = mean(a, lo, hi);
double sum = 0.0;
for (int i = lo; i <= hi; i++) {
sum += (a[i] - avg) * (a[i] - avg);
}
return sum / (length - 1);
}
/**
* Returns the sample variance in the array a[], NaN if
no such value.
*/
public static double var(int[] a) {
if (a.length == 0) return Double.NaN;
double avg = mean(a);
double sum = 0.0;
for (int i = 0; i < a.length; i++) {
sum += (a[i] - avg) * (a[i] - avg);
}
return sum / (a.length - 1);
}
/**
* Returns the population variance in the array a[],
NaN if no such value.
*/
public static double varp(double[] a) {
if (a.length == 0) return Double.NaN;
double avg = mean(a);
double sum = 0.0;
for (int i = 0; i < a.length; i++) {

sum += (a[i] - avg) * (a[i] - avg);


}
return sum / a.length;
}
/**
* Returns the population variance in the subarray
a[lo..hi], NaN if no such value.
*/
public static double varp(double[] a, int lo, int hi) {
int length = hi - lo + 1;
if (lo < 0 || hi >= a.length || lo > hi)
throw new RuntimeException("Subarray indices out
of bounds");
if (length == 0) return Double.NaN;
double avg = mean(a, lo, hi);
double sum = 0.0;
for (int i = lo; i <= hi; i++) {
sum += (a[i] - avg) * (a[i] - avg);
}
return sum / length;
}
/**
* Returns the sample standard deviation in the array
a[], NaN if no such value.
*/
public static double stddev(double[] a) {
return Math.sqrt(var(a));
}
/**
* Returns the sample standard deviation in the
subarray a[lo..hi], NaN if no such value.
*/
public static double stddev(double[] a, int lo, int hi)
{
return Math.sqrt(var(a, lo, hi));
}
/**
* Returns the sample standard deviation in the array
a[], NaN if no such value.
*/
public static double stddev(int[] a) {
return Math.sqrt(var(a));

}
/**
* Returns the population standard deviation in the
array a[], NaN if no such value.
*/
public static double stddevp(double[] a) {
return Math.sqrt(varp(a));
}
/**
* Returns the population standard deviation in the
subarray a[lo..hi], NaN if no such value.
*/
public static double stddevp(double[] a, int lo, int hi)
{
return Math.sqrt(varp(a, lo, hi));
}
/**
* Returns the sum of all values in the array a[].
*/
public static double sum(double[] a) {
double sum = 0.0;
for (int i = 0; i < a.length; i++) {
sum += a[i];
}
return sum;
}
/**
* Returns the sum of all values in the subarray
a[lo..hi].
*/
public static double sum(double[] a, int lo, int hi) {
if (lo < 0 || hi >= a.length || lo > hi)
throw new RuntimeException("Subarray indices out
of bounds");
double sum = 0.0;
for (int i = lo; i <= hi; i++) {
sum += a[i];
}
return sum;
}
/**
* Returns the sum of all values in the array a[].

*/
public static int sum(int[] a) {
int sum = 0;
for (int i = 0; i < a.length; i++) {
sum += a[i];
}
return sum;
}
/**
* Plots the points (i, a[i]) to standard draw.
*/
public static void plotPoints(double[] a) {
int N = a.length;
StdDraw.setXscale(-1, N);
StdDraw.setPenRadius(1.0 / (3.0 * N));
for (int i = 0; i < N; i++) {
StdDraw.point(i, a[i]);
}
}
/**
* Plots line segments connecting points (i, a[i]) to
standard draw.
*/
public static void plotLines(double[] a) {
int N = a.length;
StdDraw.setXscale(-1, N);
StdDraw.setPenRadius();
for (int i = 1; i < N; i++) {
StdDraw.line(i-1, a[i-1], i, a[i]);
}
}
/**
* Plots bars from (0, a[i]) to (i, a[i]) to standard
draw.
*/
public static void plotBars(double[] a) {
int N = a.length;
StdDraw.setXscale(-1, N);
for (int i = 0; i < N; i++) {
StdDraw.filledRectangle(i, a[i]/2, .25, a[i]/2);
}
}

/**
* Test client.
* Convert command-line arguments to array of doubles
and call various methods.
*/
public static void main(String[] args) {
double[] a = StdArrayIO.readDouble1D();
StdOut.printf("
min %10.3f\n", min(a));
StdOut.printf("
mean %10.3f\n", mean(a));
StdOut.printf("
max %10.3f\n", max(a));
StdOut.printf("
sum %10.3f\n", sum(a));
StdOut.printf("
stddev %10.3f\n", stddev(a));
StdOut.printf("
var %10.3f\n", var(a));
StdOut.printf("
stddevp %10.3f\n", stddevp(a));
StdOut.printf("
varp %10.3f\n", varp(a));
}
}
Copyright 20002011, Robert Sedgewick and Kevin Wayne.
Last updated: Thu Jul 23 17:05:31 EDT 2015.
StdArrayIO.java
Below is the syntax highlighted version
of StdArrayIO.java from Standard Libraries.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac StdArrayIO.java
* Execution:
java StdArrayIO < input.txt
* Dependencies: StdOut.java
*
* A library for reading in 1D and 2D arrays of integers,
doubles,
* and booleans from standard input and printing them out
to
* standard output.
*
* % more tinyDouble1D.txt
* 4
*
.000 .246 .222 -.032
*

* % more tinyDouble2D.txt
* 4 3
*
.000 .270 .000
*
.246 .224 -.036
*
.222 .176 .0893
*
-.032 .739 .270
*
* % more tinyBoolean2D.txt
* 4 3
*
1 1 0
*
0 0 0
*
0 1 1
*
1 1 1
*
* % cat tinyDouble1D.txt tinyDouble2D.txt
tinyBoolean2D.txt | java StdArrayIO
* 4
*
0.00000
0.24600
0.22200 -0.03200
*
* 4 3
*
0.00000
0.27000
0.00000
*
0.24600
0.22400 -0.03600
*
0.22200
0.17600
0.08930
*
0.03200
0.73900
0.27000
*
* 4 3
* 1 1 0
* 0 0 0
* 0 1 1
* 1 1 1
*
***********************************************************
**************/
/**
* <i>Standard array IO</i>. This class provides methods
for reading
* in 1D and 2D arrays from standard input and printing
out to
* standard output.
* <p>
* For additional documentation, see
* <a
href="http://introcs.cs.princeton.edu/22libary">Section
2.2</a> of

* <i>Introduction to Programming in Java: An


Interdisciplinary Approach</i>
* by Robert Sedgewick and Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class StdArrayIO {
// it doesn't make sense to instantiate this class
private StdArrayIO() { }
/**
* Read in and return an array of doubles from standard
input.
*/
public static double[] readDouble1D() {
int N = StdIn.readInt();
double[] a = new double[N];
for (int i = 0; i < N; i++) {
a[i] = StdIn.readDouble();
}
return a;
}
/**
* Print an array of doubles to standard output.
*/
public static void print(double[] a) {
int N = a.length;
StdOut.println(N);
for (int i = 0; i < N; i++) {
StdOut.printf("%9.5f ", a[i]);
}
StdOut.println();
}
/**
* Read in and return an M-by-N array of doubles from
standard input.
*/
public static double[][] readDouble2D() {
int M = StdIn.readInt();
int N = StdIn.readInt();
double[][] a = new double[M][N];
for (int i = 0; i < M; i++) {

for (int j = 0; j < N; j++) {


a[i][j] = StdIn.readDouble();
}
}
return a;
}
/**
* Print the M-by-N array of doubles to standard
output.
*/
public static void print(double[][] a) {
int M = a.length;
int N = a[0].length;
StdOut.println(M + " " + N);
for (int i = 0; i < M; i++) {
for (int j = 0; j < N; j++) {
StdOut.printf("%9.5f ", a[i][j]);
}
StdOut.println();
}
}
/**
* Read in and return an array of ints from standard
input.
*/
public static int[] readInt1D() {
int N = StdIn.readInt();
int[] a = new int[N];
for (int i = 0; i < N; i++) {
a[i] = StdIn.readInt();
}
return a;
}
/**
* Print an array of ints to standard output.
*/
public static void print(int[] a) {
int N = a.length;
StdOut.println(N);
for (int i = 0; i < N; i++) {
StdOut.printf("%9d ", a[i]);
}
StdOut.println();

}
/**
* Read in and return an M-by-N array of ints from
standard input.
*/
public static int[][] readInt2D() {
int M = StdIn.readInt();
int N = StdIn.readInt();
int[][] a = new int[M][N];
for (int i = 0; i < M; i++) {
for (int j = 0; j < N; j++) {
a[i][j] = StdIn.readInt();
}
}
return a;
}
/**
* Print the M-by-N array of ints to standard output.
*/
public static void print(int[][] a) {
int M = a.length;
int N = a[0].length;
StdOut.println(M + " " + N);
for (int i = 0; i < M; i++) {
for (int j = 0; j < N; j++) {
StdOut.printf("%9d ", a[i][j]);
}
StdOut.println();
}
}
/**
* Read in and return an array of booleans from
standard input.
*/
public static boolean[] readBoolean1D() {
int N = StdIn.readInt();
boolean[] a = new boolean[N];
for (int i = 0; i < N; i++) {
a[i] = StdIn.readBoolean();
}
return a;
}

/**
* Print an array of booleans to standard output.
*/
public static void print(boolean[] a) {
int N = a.length;
StdOut.println(N);
for (int i = 0; i < N; i++) {
if (a[i]) StdOut.print("1 ");
else
StdOut.print("0 ");
}
StdOut.println();
}
/**
* Read in and return an M-by-N array of booleans from
standard input.
*/
public static boolean[][] readBoolean2D() {
int M = StdIn.readInt();
int N = StdIn.readInt();
boolean[][] a = new boolean[M][N];
for (int i = 0; i < M; i++) {
for (int j = 0; j < N; j++) {
a[i][j] = StdIn.readBoolean();
}
}
return a;
}
/**
* Print the M-by-N array of booleans to standard
output.
*/
public static void print(boolean[][] a) {
int M = a.length;
int N = a[0].length;
StdOut.println(M + " " + N);
for (int i = 0; i < M; i++) {
for (int j = 0; j < N; j++) {
if (a[i][j]) StdOut.print("1 ");
else
StdOut.print("0 ");
}
StdOut.println();
}
}

/**
* Test client.
*/
public static void main(String[] args) {
// read and print an array of doubles
double[] a = StdArrayIO.readDouble1D();
StdArrayIO.print(a);
StdOut.println();
// read and print a matrix of doubles
double[][] b = StdArrayIO.readDouble2D();
StdArrayIO.print(b);
StdOut.println();
// read and print a matrix of doubles
boolean[][] d = StdArrayIO.readBoolean2D();
StdArrayIO.print(d);
StdOut.println();
}
}
Copyright 20002011, Robert Sedgewick and Kevin Wayne.
Last updated: Fri Jul 24 06:35:13 EDT 2015.
In.java
Below is the syntax highlighted version of In.java from
Standard Libraries.
Here is the Javadoc.

/
***********************************************************
**************
* Compilation: javac In.java
* Execution:
java In
(basic test --- see source for
required files)
* Dependencies: none
*
* Reads in data of various types from standard input,
files, and URLs.
*

***********************************************************
**************/
import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
// import java.net.HttpURLConnection;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.InputMismatchException;
import java.util.Locale;
import java.util.NoSuchElementException;
import java.util.Scanner;
import java.util.regex.Pattern;
/**
* <i>Input</i>. This class provides methods for reading
strings
* and numbers from standard input, file input, URLs, and
sockets.
* <p>
* The Locale used is: language = English, country = US.
This is consistent
* with the formatting conventions with Java floatingpoint literals,
* command-line arguments (via {@link
Double#parseDouble(String)})
* and standard output.
* <p>
* For additional documentation, see
* <a
href="http://introcs.cs.princeton.edu/31datatype">Section
3.1</a> of
* <i>Introduction to Programming in Java: An
Interdisciplinary Approach</i>
* by Robert Sedgewick and Kevin Wayne.
* <p>
* 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.
* <p>

* Whitespace is defined in {@link


Character#isWhitespace(char)}. Newlines
* consist of \n, \r, \r\n, and Unicode hex code points
0x2028, 0x2029, 0x0085;
* see <tt><a
href="http://www.docjar.com/html/api/java/util/Scanner.java.
html">
* Scanner.java</a></tt> (NB: Java 6u23 and earlier uses
only \r, \r, \r\n).
*
* @author David Pritchard
* @author Robert Sedgewick
* @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
// is held by the scanner's delimiter between calls
private static final Pattern WHITESPACE_PATTERN
= Pattern.compile("\\p{javaWhitespace}+");
// makes whitespace characters significant
private static final Pattern EMPTY_PATTERN
= Pattern.compile("");
// used to read the entire input. source:
//
http://weblogs.java.net/blog/pat/archive/2004/10/stupid_sca
nner_1.html
private static final Pattern EVERYTHING_PATTERN
= Pattern.compile("\\A");
/*** end: section (1 of 2) of code duplicated from In
to StdIn. */
private Scanner scanner;

/**
* Create an input stream from standard input.
*/
public In() {
scanner = new Scanner(new
BufferedInputStream(System.in), CHARSET_NAME);
scanner.useLocale(LOCALE);
}
/**
* Create an input stream from a socket.
*/
public In(java.net.Socket socket) {
try {
InputStream is = socket.getInputStream();
scanner = new Scanner(new
BufferedInputStream(is), CHARSET_NAME);
scanner.useLocale(LOCALE);
}
catch (IOException ioe) {
System.err.println("Could not open " + socket);
}
}
/**
* Create an input stream from a URL.
*/
public In(URL url) {
try {
URLConnection site = url.openConnection();
InputStream is
= site.getInputStream();
scanner
= new Scanner(new
BufferedInputStream(is), CHARSET_NAME);
scanner.useLocale(LOCALE);
}
catch (IOException ioe) {
System.err.println("Could not open " + url);
}
}
/**
* Create an input stream from a file.
*/
public In(File file) {
try {
scanner = new Scanner(file, CHARSET_NAME);

scanner.useLocale(LOCALE);
}
catch (IOException ioe) {
System.err.println("Could not open " + file);
}
}
/**
* Create an input stream from a filename or web page
name.
*/
public In(String s) {
try {
// first try to read file from local file
system
File file = new File(s);
if (file.exists()) {
scanner = new Scanner(file, CHARSET_NAME);
scanner.useLocale(LOCALE);
return;
}
// next try for files included in jar
URL url = getClass().getResource(s);
// or URL from web
if (url == null) {
url = new URL(s);
}
URLConnection site = url.openConnection();
// in order to set User-Agent, replace above
line with these two
// HttpURLConnection site = (HttpURLConnection)
url.openConnection();
// site.addRequestProperty("User-Agent",
"Mozilla/4.76");
InputStream is
= site.getInputStream();
scanner
= new Scanner(new
BufferedInputStream(is), CHARSET_NAME);
scanner.useLocale(LOCALE);
}
catch (IOException ioe) {
System.err.println("Could not open " + s);

}
}
/**
* Create an input stream from a given Scanner source;
use with
* <tt>new Scanner(String)</tt> to read from a string.
* <p>
* Note that this does not create a defensive copy, so
the
* scanner will be mutated as you read on.
*/
public In(Scanner scanner) {
this.scanner = scanner;
}
/**
* Does the input stream exist?
*/
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". ***/
/**
* Is the input empty (except possibly for whitespace)?
Use this
* to know whether the next call to {@link
#readString()},
* {@link #readDouble()}, etc will succeed.
*/
public boolean isEmpty() {
return !scanner.hasNext();
}
/**
* Does the input have a next line? Use this to know
whether the
* next call to {@link #readLine()} will succeed. <p>
Functionally
* equivalent to {@link #hasNextChar()}.
*/
public boolean hasNextLine() {

return scanner.hasNextLine();
}
/**
* Is the input empty (including whitespace)? Use this
to know
* whether the next call to {@link #readChar()} will
succeed. <p> Functionally
* equivalent to {@link #hasNextLine()}.
*/
public boolean hasNextChar() {
scanner.useDelimiter(EMPTY_PATTERN);
boolean result = scanner.hasNext();
scanner.useDelimiter(WHITESPACE_PATTERN);
return result;
}
/**
* Read and return the next line.
*/
public String readLine() {
String line;
try {
line = scanner.nextLine();
}
catch (NoSuchElementException e) {
line = null;
}
return line;
}
/**
* Read and return the next character.
*/
public char readChar() {
scanner.useDelimiter(EMPTY_PATTERN);
String ch = scanner.next();
assert (ch.length() == 1) : "Internal
(Std)In.readChar() error!"
+ " Please contact the authors.";
scanner.useDelimiter(WHITESPACE_PATTERN);
return ch.charAt(0);
}
/**

* Read and return the remainder of the input as a


string.
*/
public String readAll() {
if (!scanner.hasNextLine())
return "";
String result =
scanner.useDelimiter(EVERYTHING_PATTERN).next();
// not that important to reset delimeter, since now
scanner is empty
scanner.useDelimiter(WHITESPACE_PATTERN); // but
let's do it anyway
return result;
}
/**
* Read and return the next string.
*/
public String readString() {
return scanner.next();
}
/**
* Read and return the next int.
*/
public int readInt() {
return scanner.nextInt();
}
/**
* Read and return the next double.
*/
public double readDouble() {
return scanner.nextDouble();
}
/**
* Read and return the next float.
*/
public float readFloat() {
return scanner.nextFloat();
}
/**
* Read and return the next long.

*/
public long readLong() {
return scanner.nextLong();
}
/**
* Read and return the next short.
*/
public short readShort() {
return scanner.nextShort();
}
/**
* Read and return the next byte.
*/
public byte readByte() {
return scanner.nextByte();
}
/**
* Read and return the next boolean, allowing caseinsensitive
* "true" or "1" for true, and "false" or "0" for
false.
*/
public boolean readBoolean() {
String s = readString();
if (s.equalsIgnoreCase("true")) return true;
if (s.equalsIgnoreCase("false")) return false;
if (s.equals("1"))
return true;
if (s.equals("0"))
return false;
throw new InputMismatchException();
}
/**
* Read all strings until the end of input is reached,
and return them.
*/
public String[] readAllStrings() {
// we could use readAll.trim().split(), but that's
not consistent
// since trim() uses characters 0x00..0x20 as
whitespace
String[] tokens =
WHITESPACE_PATTERN.split(readAll());
if (tokens.length == 0 || tokens[0].length() > 0)
return tokens;

String[] decapitokens = new String[tokens.length-1];


for (int i = 0; i < tokens.length-1; i++)
decapitokens[i] = tokens[i+1];
return decapitokens;
}
/**
* Reads all remaining lines from input stream and
returns them as an array of strings.
* @return all remaining lines on input stream, as an
array of strings
*/
public String[] readAllLines() {
ArrayList<String> lines = new ArrayList<String>();
while (hasNextLine()) {
lines.add(readLine());
}
return lines.toArray(new String[0]);
}
/**
* Read all ints until the end of input is reached, and
return them.
*/
public int[] readAllInts() {
String[] fields = readAllStrings();
int[] vals = new int[fields.length];
for (int i = 0; i < fields.length; i++)
vals[i] = Integer.parseInt(fields[i]);
return vals;
}
/**
* Read all doubles until the end of input is reached,
and return them.
*/
public double[] readAllDoubles() {
String[] fields = readAllStrings();
double[] vals = new double[fields.length];
for (int i = 0; i < fields.length; i++)
vals[i] = Double.parseDouble(fields[i]);
return vals;
}
/*** end: section (2 of 2) of code duplicated from In
to StdIn */

/**
* Close the input stream.
*/
public void close() {
scanner.close();
}
/**
* Reads all ints from a file.
* @deprecated Clearer to use
* <tt>new In(filename)</tt>.{@link #readAllInts()}
*/
public static int[] readInts(String filename) {
return new In(filename).readAllInts();
}
/**
* Reads all doubles from a file.
* @deprecated Clearer to use
* <tt>new In(filename)</tt>.{@link #readAllDoubles()}
*/
public static double[] readDoubles(String filename) {
return new In(filename).readAllDoubles();
}
/**
* Reads all strings from a file.
* @deprecated Clearer to use
* <tt>new In(filename)</tt>.{@link #readAllStrings()}
*/
public static String[] readStrings(String filename) {
return new In(filename).readAllStrings();
}
/**
* Reads all ints from standard input.
* @deprecated Clearer to use {@link
StdIn#readAllInts()}
*/
public static int[] readInts() {
return new In().readAllInts();
}
/**
* Reads all doubles from standard input.

* @deprecated Clearer to use {@link


StdIn#readAllDoubles()}
*/
public static double[] readDoubles() {
return new In().readAllDoubles();
}
/**
* Reads all strings from standard input.
* @deprecated Clearer to use {@link
StdIn#readAllStrings()}
*/
public static String[] readStrings() {
return new In().readAllStrings();
}
/**
* Test client.
*/
public static void main(String[] args) {
In in;
String urlName =
"http://introcs.cs.princeton.edu/stdlib/InTest.txt";
// read from a URL
System.out.println("readAll() from URL " + urlName);
System.out.println("--------------------------------------------------------------------------");
try {
in = new In(urlName);
System.out.println(in.readAll());
}
catch (Exception e) {
System.out.println(e);
}
System.out.println();
// read one line at a time from URL
System.out.println("readLine() from URL " +
urlName);
System.out.println("--------------------------------------------------------------------------");
try {
in = new In(urlName);
while (!in.isEmpty()) {
String s = in.readLine();

System.out.println(s);
}
}
catch (Exception e) {
System.out.println(e);
}
System.out.println();
// read one string at a time from URL
System.out.println("readString() from URL " +
urlName);
System.out.println("--------------------------------------------------------------------------");
try {
in = new In(urlName);
while (!in.isEmpty()) {
String s = in.readString();
System.out.println(s);
}
}
catch (Exception e) {
System.out.println(e);
}
System.out.println();
// read one line at a time from file in current
directory
System.out.println("readLine() from current
directory");
System.out.println("--------------------------------------------------------------------------");
try {
in = new In("./InTest.txt");
while (!in.isEmpty()) {
String s = in.readLine();
System.out.println(s);
}
}
catch (Exception e) {
System.out.println(e);
}
System.out.println();

// read one line at a time from file using relative


path
System.out.println("readLine() from relative path");
System.out.println("--------------------------------------------------------------------------");
try {
in = new In("../stdlib/InTest.txt");
while (!in.isEmpty()) {
String s = in.readLine();
System.out.println(s);
}
}
catch (Exception e) {
System.out.println(e);
}
System.out.println();
// read one char at a time
System.out.println("readChar() from file");
System.out.println("--------------------------------------------------------------------------");
try {
in = new In("InTest.txt");
while (!in.isEmpty()) {
char c = in.readChar();
System.out.print(c);
}
}
catch (Exception e) {
System.out.println(e);
}
System.out.println();
System.out.println();
// 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 {
while (!in.isEmpty()) {
String s = in.readLine();

System.out.println(s);
}
}
catch (Exception e) {
System.out.println(e);
}
System.out.println();
// read one line at a time from absolute Windows
path
System.out.println("readLine() from absolute Windows
path");
System.out.println("--------------------------------------------------------------------------");
try {
in = new
In("G:\\www\\introcs\\stdlib\\InTest.txt");
while (!in.isEmpty()) {
String s = in.readLine();
System.out.println(s);
}
System.out.println();
}
catch (Exception e) {
System.out.println(e);
}
System.out.println();
}
}
Copyright 20002011, Robert Sedgewick and Kevin Wayne.
Last updated: Fri Jul 24 09:39:19 EDT 2015.
Out.java
Below is the syntax highlighted version of Out.java from
Standard Libraries.
Here is the Javadoc.

/
***********************************************************
**************
* Compilation: javac Out.java
* Execution:
java Out
* Dependencies: none
*
* Writes data of various types to: stdout, file, or
socket.
*
***********************************************************
**************/
import
import
import
import
import
import
import

java.io.FileOutputStream;
java.io.IOException;
java.io.OutputStream;
java.io.OutputStreamWriter;
java.io.PrintWriter;
java.net.Socket;
java.util.Locale;

/**
* This class provides methods for writing strings and
numbers to
* various output streams, including standard output,
file, and sockets.
* <p>
* For additional documentation, see
* <a
href="http://introcs.cs.princeton.edu/31datatype">Section
3.1</a> of
* <i>Introduction to Programming in Java: An
Interdisciplinary Approach</i>
* by Robert Sedgewick and Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class Out {
// force Unicode UTF-8 encoding; otherwise it's system
dependent
private static final String CHARSET_NAME = "UTF-8";

// assume language = English, country = US for


consistency with In
private static final Locale LOCALE = Locale.US;
private PrintWriter out;
/**
* Create an Out object using an OutputStream.
*/
public Out(OutputStream os) {
try {
OutputStreamWriter osw = new
OutputStreamWriter(os, CHARSET_NAME);
out = new PrintWriter(osw, true);
}
catch (IOException e) {
e.printStackTrace();
}
}
/**
* Create an Out object using standard output.
*/
public Out() {
this(System.out);
}
/**
* Create an Out object using a Socket.
*/
public Out(Socket socket) {
try {
OutputStream os = socket.getOutputStream();
OutputStreamWriter osw = new
OutputStreamWriter(os, CHARSET_NAME);
out = new PrintWriter(osw, true);
}
catch (IOException e) {
e.printStackTrace();
}
}
/**
* Create an Out object using a file specified by the
given name.
*/
public Out(String s) {

try {
OutputStream os = new FileOutputStream(s);
OutputStreamWriter osw = new
OutputStreamWriter(os, CHARSET_NAME);
out = new PrintWriter(osw, true);
}
catch (IOException e) {
e.printStackTrace();
}
}
/**
* Close the output stream.
*/
public void close() {
out.close();
}
/**
* Terminate the line.
*/
public void println() {
out.println();
}
/**
* Print an object and then terminate the line.
*/
public void println(Object x) {
out.println(x);
}
/**
* Print a boolean and then terminate the line.
*/
public void println(boolean x) {
out.println(x);
}
/**
* Print a char and then terminate the line.
*/
public void println(char x) {
out.println(x);
}
/**

* Print an double and then terminate the line.


*/
public void println(double x) {
out.println(x);
}
/**
* Print a float and then terminate the line.
*/
public void println(float x) {
out.println(x);
}
/**
* Print an int and then terminate the line.
*/
public void println(int x) {
out.println(x);
}
/**
* Print a long and then terminate the line.
*/
public void println(long x) {
out.println(x);
}
/**
* Print a byte and then terminate the line.
*/
public void println(byte x) {
out.println(x);
}

/**
* Flush the output stream.
*/
public void print() {
out.flush();
}
/**
* Print an object and then flush the output stream.
*/
public void print(Object x) {

out.print(x);
out.flush();
}
/**
* Print an boolean and then flush the output stream.
*/
public void print(boolean x) {
out.print(x);
out.flush();
}
/**
* Print an char and then flush the output stream.
*/
public void print(char x) {
out.print(x);
out.flush();
}
/**
* Print an double and then flush the output stream.
*/
public void print(double x) {
out.print(x);
out.flush();
}
/**
* Print a float and then flush the output stream.
*/
public void print(float x) {
out.print(x);
out.flush();
}
/**
* Print an int and then flush the output stream.
*/
public void print(int x) {
out.print(x);
out.flush();
}
/**
* Print a long and then flush the output stream.
*/

public void print(long x) {


out.print(x);
out.flush();
}
/**
* Print a byte and then flush the output stream.
*/
public void print(byte x) {
out.print(x);
out.flush();
}
/**
* Print a formatted string using the specified format
string and arguments,
* and then flush the output stream.
*/
public void printf(String format, Object... args) {
out.printf(LOCALE, format, args);
out.flush();
}
/**
* Print a formatted string using the specified locale,
format string and arguments,
* and then flush the output stream.
*/
public void printf(Locale locale, String format,
Object... args) {
out.printf(locale, format, args);
out.flush();
}
/**
* A test client.
*/
public static void main(String[] args) {
Out out;
// write to stdout
out = new Out();
out.println("Test 1");
out.close();
// write to a file

out = new Out("test.txt");


out.println("Test 2");
out.close();
}
}
Copyright 20002011, Robert Sedgewick and Kevin Wayne.
Last updated: Fri Jul 24 09:39:19 EDT 2015.
Draw.java
Below is the syntax highlighted version of Draw.java from
Standard Libraries.
Here is the Javadoc.

/
***********************************************************
**************
* Compilation: javac Draw.java
* Execution:
java Draw
* Dependencies: none
*
* Drawing library. This class 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.
*
* Todo
* ---*
- Add support for gradient fill, etc.
*
* Remarks
* ------*
- don't use AffineTransform for rescaling since it
inverts
*
images and strings

*
- careful using setFont in inner loop within an
animation *
it can cause flicker
*
***********************************************************
**************/
import
import
import
import
import
import
import
import
import
import

java.awt.BasicStroke;
java.awt.Color;
java.awt.FileDialog;
java.awt.Font;
java.awt.FontMetrics;
java.awt.Graphics2D;
java.awt.Image;
java.awt.MediaTracker;
java.awt.RenderingHints;
java.awt.Toolkit;

import
import
import
import
import
import
import

java.awt.event.ActionEvent;
java.awt.event.ActionListener;
java.awt.event.MouseEvent;
java.awt.event.MouseListener;
java.awt.event.MouseMotionListener;
java.awt.event.KeyEvent;
java.awt.event.KeyListener;

import
import
import
import
import

java.awt.geom.Arc2D;
java.awt.geom.Ellipse2D;
java.awt.geom.GeneralPath;
java.awt.geom.Line2D;
java.awt.geom.Rectangle2D;

import java.awt.image.BufferedImage;
import java.awt.image.DirectColorModel;
import java.awt.image.WritableRaster;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.LinkedList;
import java.util.TreeSet;
import javax.imageio.ImageIO;

import
import
import
import
import
import
import

javax.swing.ImageIcon;
javax.swing.JFrame;
javax.swing.JLabel;
javax.swing.JMenu;
javax.swing.JMenuBar;
javax.swing.JMenuItem;
javax.swing.KeyStroke;

/**
* <i>Draw</i>. This class 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.
* <p>
* For additional documentation, see <a
href="http://introcs.cs.princeton.edu/31datatype">Section
3.1</a> of
* <i>Introduction to Programming in Java: An
Interdisciplinary Approach</i> by Robert Sedgewick and
Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
import java.util.ArrayList;
public final class Draw implements ActionListener,
MouseListener, MouseMotionListener, KeyListener {
// pre-defined colors
public static final Color
public static final Color
public static final Color
public static final Color
public static final Color
public static final Color
public static final Color
public static final Color
public static final Color
public static final Color

BLACK
BLUE
CYAN
DARK_GRAY
GRAY
GREEN
LIGHT_GRAY
MAGENTA
ORANGE
PINK

=
=
=
=
=
=
=
=
=
=

Color.BLACK;
Color.BLUE;
Color.CYAN;
Color.DARK_GRAY;
Color.GRAY;
Color.GREEN;
Color.LIGHT_GRAY;
Color.MAGENTA;
Color.ORANGE;
Color.PINK;

public static final Color RED


public static final Color WHITE
public static final Color YELLOW

= Color.RED;
= Color.WHITE;
= Color.YELLOW;

/**
* Shade of blue used in Introduction to Programming in
Java.
* The RGB values are (9, 90, 166).
*/
public static final Color BOOK_BLUE = new Color(9, 90,
166);
/**
* Shade of red used in Algorithms 4th edition.
* The RGB values are (173, 32, 24).
*/
public static final Color BOOK_RED = new Color(173, 32,
24);
// default colors
private static final Color DEFAULT_PEN_COLOR
= BLACK;
private static final Color DEFAULT_CLEAR_COLOR = WHITE;
// boundary of
private static
private static
private static
private static
private static

drawing canvas, 0% border


final double BORDER = 0.0;
final double DEFAULT_XMIN =
final double DEFAULT_XMAX =
final double DEFAULT_YMIN =
final double DEFAULT_YMAX =

0.0;
1.0;
0.0;
1.0;

// default canvas size is SIZE-by-SIZE


private static final int DEFAULT_SIZE = 512;
// default pen radius
private static final double DEFAULT_PEN_RADIUS = 0.002;
// default font
private static final Font DEFAULT_FONT = new
Font("SansSerif", Font.PLAIN, 16);
// current pen color
private Color penColor;
// canvas size
private int width = DEFAULT_SIZE;
private int height = DEFAULT_SIZE;

// current pen radius


private double penRadius;
// 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";
// for synchronization
private Object mouseLock = new Object();
private Object keyLock = new Object();
// current font
private Font font;
// double buffered graphics
private BufferedImage offscreenImage, onscreenImage;
private Graphics2D offscreen, onscreen;
// the frame for drawing to the screen
private JFrame frame = new JFrame();
// mouse state
private boolean mousePressed = false;
private double mouseX = 0;
private double mouseY = 0;
// keyboard state
private LinkedList<Character> keysTyped = new
LinkedList<Character>();
private TreeSet<Integer> keysDown = new
TreeSet<Integer>();
// event-based listeners
private ArrayList<DrawListener> listeners = new
ArrayList<DrawListener>();
/**
* Create an empty drawing object with the given name.
*
* @param name the title of the drawing window.
*/
public Draw(String name) {

this.name = name;
init();
}
/**
* Create an empty drawing object.
*/
public Draw() {
init();
}
private void init() {
if (frame != null) frame.setVisible(false);
frame = new JFrame();
offscreenImage = new BufferedImage(width, height,
BufferedImage.TYPE_INT_ARGB);
onscreenImage = new BufferedImage(width, height,
BufferedImage.TYPE_INT_ARGB);
offscreen = offscreenImage.createGraphics();
onscreen = onscreenImage.createGraphics();
setXscale();
setYscale();
offscreen.setColor(DEFAULT_CLEAR_COLOR);
offscreen.fillRect(0, 0, width, height);
setPenColor();
setPenRadius();
setFont();
clear();
// add antialiasing
RenderingHints hints = new
RenderingHints(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
hints.put(RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY);
offscreen.addRenderingHints(hints);
// frame stuff
ImageIcon icon = new ImageIcon(onscreenImage);
JLabel draw = new JLabel(icon);
draw.addMouseListener(this);
draw.addMouseMotionListener(this);
frame.setContentPane(draw);

frame.addKeyListener(this);
// JLabel cannot get
keyboard focus
frame.setResizable(false);
//
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// closes all windows
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
// closes only current window
frame.setTitle(name);
frame.setJMenuBar(createMenuBar());
frame.pack();
frame.requestFocusInWindow();
frame.setVisible(true);
}
/**
* Set the upper-left hand corner of the drawing window
to be (x, y), where (0, 0) is upper left.
*
* @param x the number of pixels from the left
* @param y the number of pixels from the top
* @throws a RunTimeException if the width or height is
0 or negative
*/
public void setLocationOnScreen(int x, int y) {
frame.setLocation(x, y);
}

/**
* Set the window size to w-by-h pixels.
*
* @param w the width as a number of pixels
* @param h the height as a number of pixels
* @throws a RunTimeException if the width or height is
0 or negative
*/
public void setCanvasSize(int w, int h) {
if (w < 1 || h < 1) throw new
RuntimeException("width and height must be positive");
width = w;
height = h;
init();
}

// create the menu bar (changed to private)


private JMenuBar createMenuBar() {
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);
return menuBar;
}

/**********************************************************
***************
* User and screen coordinate systems
***********************************************************
**************/
/**
* Set the x-scale to be the default (between 0.0 and
1.0).
*/
public void setXscale() { setXscale(DEFAULT_XMIN,
DEFAULT_XMAX); }
/**
* Set the y-scale to be the default (between 0.0 and
1.0).
*/
public void setYscale() { setYscale(DEFAULT_YMIN,
DEFAULT_YMAX); }
/**
* Set the x-scale (a 10% border is added to the
values).
* @param min the minimum value of the x-scale
* @param max the maximum value of the x-scale
*/
public void setXscale(double min, double max) {

double size = max - min;


xmin = min - BORDER * size;
xmax = max + BORDER * size;
}
/**
* Set the y-scale (a 10% border is added to the
values).
* @param min the minimum value of the y-scale
* @param max the maximum value of the y-scale
*/
public void setYscale(double min, double max) {
double size = max - min;
ymin = min - BORDER * size;
ymax = max + BORDER * size;
}
// helper functions that scale from user coordinates to
screen coordinates and back
private double scaleX(double x) { return width * (x xmin) / (xmax - xmin); }
private double scaleY(double y) { return height * (ymax
- y) / (ymax - ymin); }
private double factorX(double w) { return w * width /
Math.abs(xmax - xmin); }
private double factorY(double h) { return h * height /
Math.abs(ymax - ymin); }
private double
userX(double x) { return xmin + x *
(xmax - xmin) / width;
}
private double
userY(double y) { return ymax - y *
(ymax - ymin) / height;
}
/**
* Clear the screen to the default color (white).
*/
public void clear() { clear(DEFAULT_CLEAR_COLOR); }
/**
* Clear the screen to the given color.
* @param color the Color to make the background
*/
public void clear(Color color) {
offscreen.setColor(color);
offscreen.fillRect(0, 0, width, height);
offscreen.setColor(penColor);
draw();
}

/**
* Get the current pen radius.
*/
public double getPenRadius() { return penRadius; }
/**
* Set the pen size to the default (.002).
*/
public void setPenRadius() {
setPenRadius(DEFAULT_PEN_RADIUS); }
/**
* Set the radius of the pen to the given size.
* @param r the radius of the pen
* @throws RuntimeException if r is negative
*/
public void setPenRadius(double r) {
if (r < 0) throw new RuntimeException("pen radius
must be positive");
penRadius = r * DEFAULT_SIZE;
BasicStroke stroke = new BasicStroke((float)
penRadius, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
// BasicStroke stroke = new BasicStroke((float)
penRadius);
offscreen.setStroke(stroke);
}
/**
* Get the current pen color.
*/
public Color getPenColor() { return penColor; }
/**
* Set the pen color to the default color (black).
*/
public void setPenColor() {
setPenColor(DEFAULT_PEN_COLOR); }
/**
* Set the pen color to the given color.
* @param color the Color to make the pen
*/
public void setPenColor(Color color) {
penColor = color;
offscreen.setColor(penColor);
}

/**
* Set the pen color to the given RGB color.
* @param red the amount of red (between 0 and 255)
* @param green the amount of green (between 0 and 255)
* @param blue the amount of blue (between 0 and 255)
* @throws IllegalArgumentException if the amount of
red, green, or blue are outside prescribed range
*/
public void setPenColor(int red, int green, int blue) {
if (red
< 0 || red
>= 256) throw new
IllegalArgumentException("amount of red must be between 0
and 255");
if (green < 0 || green >= 256) throw new
IllegalArgumentException("amount of red must be between 0
and 255");
if (blue < 0 || blue >= 256) throw new
IllegalArgumentException("amount of red must be between 0
and 255");
setPenColor(new Color(red, green, blue));
}
public void xorOn()
{ offscreen.setXORMode(DEFAULT_CLEAR_COLOR); }
public void xorOff() { offscreen.setPaintMode();
}
/**
* Get the current font.
*/
public Font getFont() { return font; }
/**
* Set the font to the default font (sans serif, 16
point).
*/
public void setFont() { setFont(DEFAULT_FONT); }
/**
* Set the font to the given value.
* @param f the font to make text
*/
public void setFont(Font f) { font = f; }

/**********************************************************
***************
* Drawing geometric shapes.
***********************************************************
**************/
/**
* Draw a line from (x0, y0) to (x1, y1).
* @param x0 the x-coordinate of the starting point
* @param y0 the y-coordinate of the starting point
* @param x1 the x-coordinate of the destination point
* @param y1 the y-coordinate of the destination point
*/
public void line(double x0, double y0, double x1, double
y1) {
offscreen.draw(new Line2D.Double(scaleX(x0),
scaleY(y0), scaleX(x1), scaleY(y1)));
draw();
}
/**
* Draw one pixel at (x, y).
* @param x the x-coordinate of the pixel
* @param y the y-coordinate of the pixel
*/
private void pixel(double x, double y) {
offscreen.fillRect((int) Math.round(scaleX(x)),
(int) Math.round(scaleY(y)), 1, 1);
}
/**
* Draw a point at (x, y).
* @param x the x-coordinate of the point
* @param y the y-coordinate of the point
*/
public void point(double x, double y) {
double xs = scaleX(x);
double ys = scaleY(y);
double r = penRadius;
// double ws = factorX(2*r);
// double hs = factorY(2*r);
// if (ws <= 1 && hs <= 1) pixel(x, y);
if (r <= 1) pixel(x, y);
else offscreen.fill(new Ellipse2D.Double(xs - r/2,
ys - r/2, r, r));

draw();
}
/**
* Draw a circle of radius r, centered on (x, y).
* @param x the x-coordinate of the center of the
circle
* @param y the y-coordinate of the center of the
circle
* @param r the radius of the circle
* @throws RuntimeException if the radius of the circle
is negative
*/
public void circle(double x, double y, double r) {
if (r < 0) throw new RuntimeException("circle radius
can't be negative");
double xs = scaleX(x);
double ys = scaleY(y);
double ws = factorX(2*r);
double hs = factorY(2*r);
if (ws <= 1 && hs <= 1) pixel(x, y);
else offscreen.draw(new Ellipse2D.Double(xs - ws/2,
ys - hs/2, ws, hs));
draw();
}
/**
* Draw filled circle of radius r, centered on (x, y).
* @param x the x-coordinate of the center of the
circle
* @param y the y-coordinate of the center of the
circle
* @param r the radius of the circle
* @throws RuntimeException if the radius of the circle
is negative
*/
public void filledCircle(double x, double y, double r) {
if (r < 0) throw new RuntimeException("circle radius
can't be negative");
double xs = scaleX(x);
double ys = scaleY(y);
double ws = factorX(2*r);
double hs = factorY(2*r);
if (ws <= 1 && hs <= 1) pixel(x, y);
else offscreen.fill(new Ellipse2D.Double(xs - ws/2,
ys - hs/2, ws, hs));
draw();

}
/**
* Draw an ellipse with given semimajor and semiminor
axes, centered on (x, y).
* @param x the x-coordinate of the center of the
ellipse
* @param y the y-coordinate of the center of the
ellipse
* @param semiMajorAxis is the semimajor axis of the
ellipse
* @param semiMinorAxis is the semiminor axis of the
ellipse
* @throws RuntimeException if either of the axes are
negative
*/
public void ellipse(double x, double y, double
semiMajorAxis, double semiMinorAxis) {
if (semiMajorAxis < 0) throw new
RuntimeException("ellipse semimajor axis can't be
negative");
if (semiMinorAxis < 0) throw new
RuntimeException("ellipse semiminor axis can't be
negative");
double xs = scaleX(x);
double ys = scaleY(y);
double ws = factorX(2*semiMajorAxis);
double hs = factorY(2*semiMinorAxis);
if (ws <= 1 && hs <= 1) pixel(x, y);
else offscreen.draw(new Ellipse2D.Double(xs - ws/2,
ys - hs/2, ws, hs));
draw();
}
/**
* Draw an ellipse with given semimajor and semiminor
axes, centered on (x, y).
* @param x the x-coordinate of the center of the
ellipse
* @param y the y-coordinate of the center of the
ellipse
* @param semiMajorAxis is the semimajor axis of the
ellipse
* @param semiMinorAxis is the semiminor axis of the
ellipse

* @throws RuntimeException if either of the axes are


negative
*/
public void filledEllipse(double x, double y, double
semiMajorAxis, double semiMinorAxis) {
if (semiMajorAxis < 0) throw new
RuntimeException("ellipse semimajor axis can't be
negative");
if (semiMinorAxis < 0) throw new
RuntimeException("ellipse semiminor axis can't be
negative");
double xs = scaleX(x);
double ys = scaleY(y);
double ws = factorX(2*semiMajorAxis);
double hs = factorY(2*semiMinorAxis);
if (ws <= 1 && hs <= 1) pixel(x, y);
else offscreen.fill(new Ellipse2D.Double(xs - ws/2,
ys - hs/2, ws, hs));
draw();
}
/**
* Draw an arc of radius r, centered on (x, y), from
angle1 to angle2 (in degrees).
* @param x the x-coordinate of the center of the
circle
* @param y the y-coordinate of the center of the
circle
* @param r the radius of the circle
* @param angle1 the starting angle. 0 would mean an
arc beginning at 3 o'clock.
* @param angle2 the angle at the end of the arc. For
example, if
*
you want a 90 degree arc, then angle2 should
be angle1 + 90.
* @throws RuntimeException if the radius of the circle
is negative
*/
public void arc(double x, double y, double r, double
angle1, double angle2) {
if (r < 0) throw new RuntimeException("arc radius
can't be negative");
while (angle2 < angle1) angle2 += 360;
double xs = scaleX(x);
double ys = scaleY(y);
double ws = factorX(2*r);
double hs = factorY(2*r);

if (ws <= 1 && hs <= 1) pixel(x, y);


else offscreen.draw(new Arc2D.Double(xs - ws/2, ys hs/2, ws, hs, angle1, angle2 - angle1, Arc2D.OPEN));
draw();
}
/**
* Draw a square of side length 2r, centered on (x, y).
* @param x the x-coordinate of the center of the
square
* @param y the y-coordinate of the center of the
square
* @param r radius is half the length of any side of
the square
* @throws RuntimeException if r is negative
*/
public void square(double x, double y, double r) {
if (r < 0) throw new RuntimeException("square side
length can't be negative");
double xs = scaleX(x);
double ys = scaleY(y);
double ws = factorX(2*r);
double hs = factorY(2*r);
if (ws <= 1 && hs <= 1) pixel(x, y);
else offscreen.draw(new Rectangle2D.Double(xs ws/2, ys - hs/2, ws, hs));
draw();
}
/**
* Draw a filled square of side length 2r, centered on
(x, y).
* @param x the x-coordinate of the center of the
square
* @param y the y-coordinate of the center of the
square
* @param r radius is half the length of any side of
the square
* @throws RuntimeException if r is negative
*/
public void filledSquare(double x, double y, double r) {
if (r < 0) throw new RuntimeException("square side
length can't be negative");
double xs = scaleX(x);
double ys = scaleY(y);
double ws = factorX(2*r);
double hs = factorY(2*r);

if (ws <= 1 && hs <= 1) pixel(x, y);


else offscreen.fill(new Rectangle2D.Double(xs ws/2, ys - hs/2, ws, hs));
draw();
}
/**
* Draw a rectangle of given half width and half
height, centered on (x, y).
* @param x the x-coordinate of the center of the
rectangle
* @param y the y-coordinate of the center of the
rectangle
* @param halfWidth is half the width of the rectangle
* @param halfHeight is half the height of the
rectangle
* @throws RuntimeException if halfWidth or halfHeight
is negative
*/
public void rectangle(double x, double y, double
halfWidth, double halfHeight) {
if (halfWidth < 0) throw new RuntimeException("half
width can't be negative");
if (halfHeight < 0) throw new RuntimeException("half
height can't be negative");
double xs = scaleX(x);
double ys = scaleY(y);
double ws = factorX(2*halfWidth);
double hs = factorY(2*halfHeight);
if (ws <= 1 && hs <= 1) pixel(x, y);
else offscreen.draw(new Rectangle2D.Double(xs ws/2, ys - hs/2, ws, hs));
draw();
}
/**
* Draw a filled rectangle of given half width and half
height, centered on (x, y).
* @param x the x-coordinate of the center of the
rectangle
* @param y the y-coordinate of the center of the
rectangle
* @param halfWidth is half the width of the rectangle
* @param halfHeight is half the height of the
rectangle

* @throws RuntimeException if halfWidth or halfHeight


is negative
*/
public void filledRectangle(double x, double y, double
halfWidth, double halfHeight) {
if (halfWidth < 0) throw new RuntimeException("half
width can't be negative");
if (halfHeight < 0) throw new RuntimeException("half
height can't be negative");
double xs = scaleX(x);
double ys = scaleY(y);
double ws = factorX(2*halfWidth);
double hs = factorY(2*halfHeight);
if (ws <= 1 && hs <= 1) pixel(x, y);
else offscreen.fill(new Rectangle2D.Double(xs ws/2, ys - hs/2, ws, hs));
draw();
}
/**
* Draw a polygon with the given (x[i], y[i])
coordinates.
* @param x an array of all the x-coordindates of the
polygon
* @param y an array of all the y-coordindates of the
polygon
*/
public void polygon(double[] x, double[] y) {
int N = x.length;
GeneralPath path = new GeneralPath();
path.moveTo((float) scaleX(x[0]), (float)
scaleY(y[0]));
for (int i = 0; i < N; i++)
path.lineTo((float) scaleX(x[i]), (float)
scaleY(y[i]));
path.closePath();
offscreen.draw(path);
draw();
}
/**
* Draw a filled polygon with the given (x[i], y[i])
coordinates.
* @param x an array of all the x-coordindates of the
polygon
* @param y an array of all the y-coordindates of the
polygon

*/
public void filledPolygon(double[] x, double[] y) {
int N = x.length;
GeneralPath path = new GeneralPath();
path.moveTo((float) scaleX(x[0]), (float)
scaleY(y[0]));
for (int i = 0; i < N; i++)
path.lineTo((float) scaleX(x[i]), (float)
scaleY(y[i]));
path.closePath();
offscreen.fill(path);
draw();
}

/**********************************************************
***************
* Drawing images.
***********************************************************
**************/
// get an image from the given filename
private Image getImage(String filename) {
// to read from file
ImageIcon icon = new ImageIcon(filename);
// try to read from URL
if ((icon == null) || (icon.getImageLoadStatus() !=
MediaTracker.COMPLETE)) {
try {
URL url = new URL(filename);
icon = new ImageIcon(url);
}
catch (Exception e) {
/* not a url */
}
}
// in case file is inside a .jar
if ((icon == null) || (icon.getImageLoadStatus() !=
MediaTracker.COMPLETE)) {
URL url = Draw.class.getResource(filename);

if (url == null) throw new


RuntimeException("image " + filename + " not found");
icon = new ImageIcon(url);
}
return icon.getImage();
}
/**
* Draw picture (gif, jpg, or png) centered on (x, y).
* @param x the center x-coordinate of the image
* @param y the center y-coordinate of the image
* @param s the name of the image/picture, e.g.,
"ball.gif"
* @throws RuntimeException if the image is corrupt
*/
public void picture(double x, double y, String s) {
Image image = getImage(s);
double xs = scaleX(x);
double ys = scaleY(y);
int ws = image.getWidth(null);
int hs = image.getHeight(null);
if (ws < 0 || hs < 0) throw new
RuntimeException("image " + s + " is corrupt");
offscreen.drawImage(image, (int) Math.round(xs ws/2.0), (int) Math.round(ys - hs/2.0), null);
draw();
}
/**
* Draw picture (gif, jpg, or png) centered on (x, y),
* rotated given number of degrees.
* @param x the center x-coordinate of the image
* @param y the center y-coordinate of the image
* @param s the name of the image/picture, e.g.,
"ball.gif"
* @param degrees is the number of degrees to rotate
counterclockwise
* @throws RuntimeException if the image is corrupt
*/
public void picture(double x, double y, String s, double
degrees) {
Image image = getImage(s);
double xs = scaleX(x);
double ys = scaleY(y);
int ws = image.getWidth(null);

int hs = image.getHeight(null);
if (ws < 0 || hs < 0) throw new
RuntimeException("image " + s + " is corrupt");
offscreen.rotate(Math.toRadians(-degrees), xs, ys);
offscreen.drawImage(image, (int) Math.round(xs ws/2.0), (int) Math.round(ys - hs/2.0), null);
offscreen.rotate(Math.toRadians(+degrees), xs, ys);
draw();
}
/**
* Draw picture (gif, jpg, or png) centered on (x, y),
rescaled to w-by-h.
* @param x the center x coordinate of the image
* @param y the center y coordinate of the image
* @param s the name of the image/picture, e.g.,
"ball.gif"
* @param w the width of the image
* @param h the height of the image
* @throws RuntimeException if the image is corrupt
*/
public void picture(double x, double y, String s, double
w, double h) {
Image image = getImage(s);
double xs = scaleX(x);
double ys = scaleY(y);
double ws = factorX(w);
double hs = factorY(h);
if (ws < 0 || hs < 0) throw new
RuntimeException("image " + s + " is corrupt");
if (ws <= 1 && hs <= 1) pixel(x, y);
else {
offscreen.drawImage(image, (int) Math.round(xs ws/2.0),
(int) Math.round(ys hs/2.0),
(int) Math.round(ws),
(int) Math.round(hs),
null);
}
draw();
}
/**

* Draw picture (gif, jpg, or png) centered on (x, y),


rotated
* given number of degrees, rescaled to w-by-h.
* @param x the center x-coordinate of the image
* @param y the center y-coordinate of the image
* @param s the name of the image/picture, e.g.,
"ball.gif"
* @param w the width of the image
* @param h the height of the image
* @param degrees is the number of degrees to rotate
counterclockwise
* @throws RuntimeException if the image is corrupt
*/
public void picture(double x, double y, String s, double
w, double h, double degrees) {
Image image = getImage(s);
double xs = scaleX(x);
double ys = scaleY(y);
double ws = factorX(w);
double hs = factorY(h);
if (ws < 0 || hs < 0) throw new
RuntimeException("image " + s + " is corrupt");
if (ws <= 1 && hs <= 1) pixel(x, y);
offscreen.rotate(Math.toRadians(-degrees), xs, ys);
offscreen.drawImage(image, (int) Math.round(xs ws/2.0),
(int) Math.round(ys hs/2.0),
(int) Math.round(ws),
(int) Math.round(hs),
null);
offscreen.rotate(Math.toRadians(+degrees), xs, ys);
draw();
}

/**********************************************************
***************
* Drawing text.
***********************************************************
**************/
/**

* Write the given text string in the current font,


centered on (x, y).
* @param x the center x-coordinate of the text
* @param y the center y-coordinate of the text
* @param s the text
*/
public void text(double x, double y, String s) {
offscreen.setFont(font);
FontMetrics metrics = offscreen.getFontMetrics();
double xs = scaleX(x);
double ys = scaleY(y);
int ws = metrics.stringWidth(s);
int hs = metrics.getDescent();
offscreen.drawString(s, (float) (xs - ws/2.0),
(float) (ys + hs));
draw();
}
/**
* Write the given text string in the current font,
centered on (x, y) and
* rotated by the specified number of degrees.
* @param x the center x-coordinate of the text
* @param y the center y-coordinate of the text
* @param s the text
* @param degrees is the number of degrees to rotate
counterclockwise
*/
public void text(double x, double y, String s, double
degrees) {
double xs = scaleX(x);
double ys = scaleY(y);
offscreen.rotate(Math.toRadians(-degrees), xs, ys);
text(x, y, s);
offscreen.rotate(Math.toRadians(+degrees), xs, ys);
}
/**
* Write the given text string in the current font,
left-aligned at (x, y).
* @param x the x-coordinate of the text
* @param y the y-coordinate of the text
* @param s the text
*/
public void textLeft(double x, double y, String s) {
offscreen.setFont(font);
FontMetrics metrics = offscreen.getFontMetrics();

double xs = scaleX(x);
double ys = scaleY(y);
// int ws = metrics.stringWidth(s);
int hs = metrics.getDescent();
offscreen.drawString(s, (float) (xs), (float) (ys +
hs));
show();
}
/**
* Display on screen, pause for t milliseconds, and
turn on
* <em>animation mode</em>: subsequent calls to
* drawing methods such as <tt>line()</tt>,
<tt>circle()</tt>, and <tt>square()</tt>
* will not be displayed on screen until the next call
to <tt>show()</tt>.
* This is useful for producing animations (clear the
screen, draw a bunch of shapes,
* display on screen for a fixed amount of time, and
repeat). It also speeds up
* drawing a huge number of shapes (call
<tt>show(0)</tt> to defer drawing
* on screen, draw the shapes, and call <tt>show(0)</tt>
to display them all
* on screen at once).
* @param t number of milliseconds
*/
public void show(int t) {
defer = false;
draw();
try {
Thread.sleep(t);
}
catch (InterruptedException e) {
System.out.println("Error sleeping");
}
defer = true;
}
/**
* Display on-screen and turn off animation mode:
* subsequent calls to
* drawing methods such as <tt>line()</tt>,
<tt>circle()</tt>, and <tt>square()</tt>

* will be displayed on screen when called. This is the


default.
*/
public void show() {
defer = false;
draw();
}
// draw onscreen if defer is false
private void draw() {
if (defer) return;
onscreen.drawImage(offscreenImage, 0, 0, null);
frame.repaint();
}

/**********************************************************
***************
* Save drawing to a file.
***********************************************************
**************/
/**
* Save to file - suffix must be png, jpg, or gif.
* @param filename the name of the file with one of the
required suffixes
*/
public void save(String filename) {
File file = new File(filename);
String suffix =
filename.substring(filename.lastIndexOf('.') + 1);
// png files
if (suffix.toLowerCase().equals("png")) {
try {
ImageIO.write(offscreenImage, suffix, file);
}
catch (IOException e) {
e.printStackTrace();
}
}
// need to change from ARGB to RGB for jpeg
// reference: http://archives.java.sun.com/cgibin/wa?A2=ind0404&L=java2d-interest&D=0&P=2727

else if (suffix.toLowerCase().equals("jpg")) {
WritableRaster raster =
offscreenImage.getRaster();
WritableRaster newRaster;
newRaster = raster.createWritableChild(0, 0,
width, height, 0, 0, new int[] {0, 1, 2});
DirectColorModel cm = (DirectColorModel)
offscreenImage.getColorModel();
DirectColorModel newCM = new
DirectColorModel(cm.getPixelSize(),
cm.getRedMask(),
cm.getGreenMask(),
cm.getBlueMask());
BufferedImage rgbBuffer = new
BufferedImage(newCM, newRaster, false, null);
try {
ImageIO.write(rgbBuffer, suffix, file);
}
catch (IOException e) {
e.printStackTrace();
}
}
else {
System.out.println("Invalid image file type: " +
suffix);
}
}
/**
* This method cannot be called directly.
*/
public void actionPerformed(ActionEvent e) {
FileDialog chooser = new FileDialog(frame, "Use a
.png or .jpg extension", FileDialog.SAVE);
chooser.setVisible(true);
String filename = chooser.getFile();
if (filename != null) {
save(chooser.getDirectory() + File.separator +
chooser.getFile());
}
}

/**********************************************************
***************
* Event-based interactions.
***********************************************************
**************/
public void addListener(DrawListener listener) {
// ensure there is a window for listenting to
events
show();
listeners.add(listener);
frame.addKeyListener(this);
frame.addMouseListener(this);
frame.addMouseMotionListener(this);
frame.setFocusable(true);
}

/**********************************************************
***************
* Mouse interactions.
***********************************************************
**************/
/**
* Is the mouse being pressed?
* @return true or false
*/
public boolean mousePressed() {
synchronized (mouseLock) {
return mousePressed;
}
}
/**
* What is the x-coordinate of the mouse?
* @return the value of the x-coordinate of the mouse
*/
public double mouseX() {
synchronized (mouseLock) {
return mouseX;

}
}
/**
* What is the y-coordinate of the mouse?
* @return the value of the y-coordinate of the mouse
*/
public double mouseY() {
synchronized (mouseLock) {
return mouseY;
}
}

/**
* This method cannot be called directly.
*/
public void mouseClicked(MouseEvent e) { }
/**
* This method cannot be called directly.
*/
public void mouseEntered(MouseEvent e) { }
/**
* This method cannot be called directly.
*/
public void mouseExited(MouseEvent e) { }
/**
* This method cannot be called directly.
*/
public void mousePressed(MouseEvent e) {
synchronized (mouseLock) {
mouseX = userX(e.getX());
mouseY = userY(e.getY());
mousePressed = true;
}
if (e.getButton() == MouseEvent.BUTTON1) {
for (DrawListener listener : listeners)
listener.mousePressed(userX(e.getX()),
userY(e.getY()));
}
}

/**
* This method cannot be called directly.
*/
public void mouseReleased(MouseEvent e) {
synchronized (mouseLock) {
mousePressed = false;
}
if (e.getButton() == MouseEvent.BUTTON1) {
for (DrawListener listener : listeners)
listener.mouseReleased(userX(e.getX()),
userY(e.getY()));
}
}
/**
* This method cannot be called directly.
*/
public void mouseDragged(MouseEvent e) {
synchronized (mouseLock) {
mouseX = userX(e.getX());
mouseY = userY(e.getY());
}
// doesn't seem to work if a button is specified
for (DrawListener listener : listeners)
listener.mouseDragged(userX(e.getX()),
userY(e.getY()));
}
/**
* This method cannot be called directly.
*/
public void mouseMoved(MouseEvent e) {
synchronized (mouseLock) {
mouseX = userX(e.getX());
mouseY = userY(e.getY());
}
}

/**********************************************************
***************
* Keyboard interactions.
***********************************************************
**************/

/**
* Has the user typed a key?
* @return true if the user has typed a key, false
otherwise
*/
public boolean hasNextKeyTyped() {
synchronized (keyLock) {
return !keysTyped.isEmpty();
}
}
/**
* What is the next key that was typed by the user?
* @return the next key typed
*/
public char nextKeyTyped() {
synchronized (keyLock) {
return keysTyped.removeLast();
}
}
/**
* Is the keycode currently being pressed? This method
takes as an argument
* the keycode (corresponding to a physical key). It
can handle action keys
* (such as F1 and arrow keys) and modifier keys (such
as shift and control).
* See <a href =
"http://download.oracle.com/javase/6/docs/api/java/awt/event
/KeyEvent.html">KeyEvent.java</a>
* for a description of key codes.
* @return true if keycode is currently being pressed,
false otherwise
*/
public boolean isKeyPressed(int keycode) {
synchronized (keyLock) {
return keysDown.contains(keycode);
}
}
/**
* This method cannot be called directly.
*/
public void keyTyped(KeyEvent e) {
synchronized (keyLock) {

keysTyped.addFirst(e.getKeyChar());
}
// notify all listeners
for (DrawListener listener : listeners)
listener.keyTyped(e.getKeyChar());
}
/**
* This method cannot be called directly.
*/
public void keyPressed(KeyEvent e) {
synchronized (keyLock) {
keysDown.add(e.getKeyCode());
}
}
/**
* This method cannot be called directly.
*/
public void keyReleased(KeyEvent e) {
synchronized (keyLock) {
keysDown.remove(e.getKeyCode());
}
}

/**
* Test client.
*/
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);
draw1.setPenColor(Draw.MAGENTA);
draw1.setPenRadius(.02);
draw1.arc(.8, .2, .1, 200, 45);
// create another one
Draw draw2 = new Draw("Test client 2");
draw2.setCanvasSize(900, 200);

// draw a blue diamond


draw2.setPenRadius();
draw2.setPenColor(Draw.BLUE);
double[] x = { .1, .2, .3, .2 };
double[] y = { .2, .3, .2, .1 };
draw2.filledPolygon(x, y);
// text
draw2.setPenColor(Draw.BLACK);
draw2.text(0.2, 0.5, "bdfdfdfdlack text");
draw2.setPenColor(Draw.WHITE);
draw2.text(0.8, 0.8, "white text");
}
}
Copyright 20002011, Robert Sedgewick and Kevin Wayne.
Last updated: Fri Jul 24 09:39:19 EDT 2015.
Picture.java
Below is the syntax highlighted version
of Picture.java from Standard Libraries.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac Picture.java
* Execution:
java Picture imagename
* 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 size. 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
*
***********************************************************
**************/
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import

java.awt.Color;
java.awt.FileDialog;
java.awt.Toolkit;
java.awt.event.ActionEvent;
java.awt.event.ActionListener;
java.awt.event.KeyEvent;
java.awt.image.BufferedImage;
java.io.File;
java.io.IOException;
java.net.URL;
javax.imageio.ImageIO;
javax.swing.ImageIcon;
javax.swing.JFrame;
javax.swing.JLabel;
javax.swing.JMenu;
javax.swing.JMenuBar;
javax.swing.JMenuItem;
javax.swing.KeyStroke;

/**
* This class provides methods for manipulating individual
pixels of
* an image. The original image can be read from a
<tt>.jpg</tt>, <tt>.gif</tt>,
* or <tt>.png</tt> file or the user can create a blank
image of a given size.
* This class includes methods for displaying the image in
a window on
* the screen or saving it to a file.
* <p>
* Pixel (<em>x</em>, <em>y</em>) is column <em>x</em> and
row <em>y</em>.
* By default, the origin (0, 0) is upper left, which is a
common convention
* in image processing.

* The method <tt>setOriginLowerLeft()</tt> change the


origin to the lower left.
* <p>
* For additional documentation, see
* <a
href="http://introcs.cs.princeton.edu/31datatype">Section
3.1</a> of
* <i>Introduction to Programming in Java: An
Interdisciplinary Approach</i>
* by Robert Sedgewick and Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
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 boolean isOriginUpperLeft = true; // location
of origin
private final int width, height;
// width and
height
/**
* Initializes a blank <tt>width</tt>-by-<tt>height</tt>
picture, with <tt>width</tt> columns
* and <tt>height</tt> rows, where each pixel is black.
*/
public Picture(int width, int height) {
if (width < 0) throw new
IllegalArgumentException("width must be nonnegative");
if (height < 0) throw new
IllegalArgumentException("height must be nonnegative");
this.width = width;
this.height = height;
image = new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);
// set to TYPE_INT_ARGB to support transparency
filename = width + "-by-" + height;
}
/**
* Initializes a new picture that is a deep copy of
<tt>picture</tt>.

*/
public Picture(Picture picture) {
width = picture.width();
height = picture.height();
image = new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);
filename = picture.filename;
for (int col = 0; col < width(); col++)
for (int row = 0; row < height(); row++)
image.setRGB(col, row, picture.get(col,
row).getRGB());
}
/**
* Initializes a picture by reading in a .png, .gif, or
.jpg from
* the given filename or URL name.
*/
public Picture(String filename) {
this.filename = filename;
try {
// try to read from file in working directory
File file = new File(filename);
if (file.isFile()) {
image = ImageIO.read(file);
}
// now try to read from file in same directory
as this .class file
else {
URL url = getClass().getResource(filename);
if (url == null) {
url = new URL(filename);
}
image = ImageIO.read(url);
}
width = image.getWidth(null);
height = image.getHeight(null);
}
catch (IOException e) {
// e.printStackTrace();
throw new RuntimeException("Could not open file:
" + filename);
}
}
/**

* Initializes a picture by reading in a .png, .gif, or


.jpg from a File.
*/
public Picture(File file) {
try {
image = ImageIO.read(file);
}
catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("Could not open file:
" + file);
}
if (image == null) {
throw new RuntimeException("Invalid image file:
" + file);
}
width = image.getWidth(null);
height = image.getHeight(null);
filename = file.getName();
}
/**
* Returns a JLabel containing this picture, for
embedding in a JPanel,
* JFrame or other GUI widget.
* @return the <tt>JLabel</tt>
*/
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);
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);
frame.setTitle(filename);
frame.setResizable(false);
frame.pack();
frame.setVisible(true);
}
// draw
frame.repaint();
}
/**
* Returns
* @return
*/
public int
return

the height of the picture.


the height of the picture (in pixels)
height() {
height;

}
/**
* Returns
* @return
*/
public int
return
}

the width of the picture.


the width of the picture (in pixels)
width() {
width;

/**
* Returns the color of pixel (<tt>col</tt>,
<tt>row</tt>).
* @return the color of pixel (<tt>col</tt>,
<tt>row</tt>)
* @throws IndexOutOfBoundsException unless both 0 &le;
<tt>col</tt> &lt; <tt>width</tt>
* and 0 &le; <tt>row</tt> &lt; <tt>height</tt>
*/
public Color get(int col, int row) {
if (col < 0 || col >= width()) throw new
IndexOutOfBoundsException("col must be between 0 and " +
(width()-1));
if (row < 0 || row >= height()) throw new
IndexOutOfBoundsException("row must be between 0 and " +
(height()-1));
if (isOriginUpperLeft) return new
Color(image.getRGB(col, row));
else
return new
Color(image.getRGB(col, height - row - 1));
}
/**
* Sets the color of pixel (<tt>col</tt>, <tt>row</tt>)
to given color.
* @throws IndexOutOfBoundsException unless both 0 &le;
<tt>col</tt> &lt; <tt>width</tt>
* and 0 &le; <tt>row</tt> &lt; <tt>height</tt>
* @throws NullPointerException if <tt>color</tt> is
<tt>null</tt>
*/
public void set(int col, int row, Color color) {
if (col < 0 || col >= width()) throw new
IndexOutOfBoundsException("col must be between 0 and " +
(width()-1));

if (row < 0 || row >= height()) throw new


IndexOutOfBoundsException("row must be between 0 and " +
(height()-1));
if (color == null) throw new
NullPointerException("can't set Color to null");
if (isOriginUpperLeft) image.setRGB(col, row,
color.getRGB());
else
image.setRGB(col, height row - 1, color.getRGB());
}
/**
* Is this Picture equal to obj?
* @return <tt>true</tt> if this picture is the same
dimension as <tt>obj</tt>
* and if all pixels have the same color
*/
public boolean equals(Object obj) {
if (obj == this) return true;
if (obj == null) return false;
if (obj.getClass() != this.getClass()) return false;
Picture that = (Picture) obj;
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.get(col, row).equals(that.get(col,
row))) return false;
return true;
}
/**
* 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 a standard image
format.
* The filetype must be .png or .jpg.
*/

public void save(String name) {


save(new File(name));
}
/**
* Saves the picture to a file in a standard image
format.
*/
public void save(File file) {
this.filename = file.getName();
if (frame != null) frame.setTitle(filename);
String suffix =
filename.substring(filename.lastIndexOf('.') + 1);
suffix = suffix.toLowerCase();
if (suffix.equals("jpg") || suffix.equals("png")) {
try {
ImageIO.write(image, suffix, file);
}
catch (IOException e) {
e.printStackTrace();
}
}
else {
System.out.println("Error: filename must end
in .jpg or .png");
}
}
/**
* Opens a save dialog box when the user selects "Save
As" from the menu.
*/
public void actionPerformed(ActionEvent e) {
FileDialog chooser = new FileDialog(frame,
"Use a .png or .jpg extension",
FileDialog.SAVE);
chooser.setVisible(true);
if (chooser.getFile() != null) {
save(chooser.getDirectory() + File.separator +
chooser.getFile());
}
}
/**
* Tests this <tt>Picture</tt> data type. Reads a
picture specified by the command-line argument,

* and shows it in a window on the screen.


*/
public static void main(String[] args) {
Picture picture = new Picture(args[0]);
System.out.printf("%d-by-%d\n", picture.width(),
picture.height());
picture.show();
}
}

Copyright 20002011, Robert Sedgewick and Kevin Wayne.


Last updated: Fri Jul 24 09:39:19 EDT 2015.
Stopwatch.java
Below is the syntax highlighted version
of Stopwatch.java from Standard Libraries.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac Stopwatch.java
* Execution:
none
* Dependencies: none
*
***********************************************************
**************/
/**
* <i>Stopwatch</i>. This class is a data type for
measuring
* the running time (wall clock) of a program.
* <p>
* For additional documentation, see
* <a
href="http://introcs.cs.princeton.edu/32class">Section
3.2</a> of
* <i>Introduction to Programming in Java: An
Interdisciplinary Approach</i>
* by Robert Sedgewick and Kevin Wayne.

*/

public class Stopwatch {


private final long start;
/**
* Create a stopwatch object.
*/
public Stopwatch() {
start = System.currentTimeMillis();
}
/**
* Return elapsed time (in seconds) since this object
was created.
*/
public double elapsedTime() {
long now = System.currentTimeMillis();
return (now - start) / 1000.0;
}
}
Copyright 20002011, Robert Sedgewick and Kevin Wayne.
Last updated: Fri Jul 24 06:35:13 EDT 2015.
BinaryStdIn.java
Below is the syntax highlighted version
of BinaryStdIn.java from Standard Libraries.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac BinaryStdIn.java
* Execution:
java BinaryStdIn < input > output
* Dependencies: none
*
* Supports reading binary data from standard input.

*
*
*
*

% java BinaryStdIn < input.jpg > output.jpg


% diff input.jpg output.jpg

***********************************************************
**************/
import java.io.BufferedInputStream;
import java.io.IOException;
/**
* <i>Binary standard input</i>. This class provides
methods for reading
* in bits from standard input, either one bit at a time
(as a <tt>boolean</tt>),
* 8 bits at a time (as a <tt>byte</tt> or <tt>char</tt>),
* 16 bits at a time (as a <tt>short</tt>), 32 bits at a
time
* (as an <tt>int</tt> or <tt>float</tt>), or 64 bits at a
time (as a
* <tt>double</tt> or <tt>long</tt>).
* <p>
* All primitive types are assumed to be represented using
their
* standard Java representations, in big-endian (most
significant
* byte first) order.
* <p>
* The client should not intermix calls to
<tt>BinaryStdIn</tt> with calls
* to <tt>StdIn</tt> or <tt>System.in</tt>;
* otherwise unexpected behavior will result.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public final class BinaryStdIn {
private static BufferedInputStream in = new
BufferedInputStream(System.in);
private static final int EOF = -1;
// end of file
private static int buffer;
buffer
private static int n;
left in buffer

// one character
// number of bits

// static initializer
static {
fillBuffer();
}
// don't instantiate
private BinaryStdIn() { }
private static void fillBuffer() {
try {
buffer = in.read();
n = 8;
}
catch (IOException e) {
System.out.println("EOF");
buffer = EOF;
n = -1;
}
}
/**
* Close this input stream and release any associated
system resources.
*/
public static void close() {
try {
in.close();
}
catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("Could not close
BinaryStdIn");
}
}
/**
* Returns true if standard input is empty.
* @return true if and only if standard input is empty
*/
public static boolean isEmpty() {
return buffer == EOF;
}
/**
* Read the next bit of data from standard input and
return as a boolean.

* @return the next bit of data from standard input as


a <tt>boolean</tt>
* @throws RuntimeException if standard input is empty
*/
public static boolean readBoolean() {
if (isEmpty()) throw new RuntimeException("Reading
from empty input stream");
n--;
boolean bit = ((buffer >> n) & 1) == 1;
if (n == 0) fillBuffer();
return bit;
}
/**
* Read the next 8 bits from standard input and return
as an 8-bit char.
* Note that <tt>char</tt> is a 16-bit type;
* to read the next 16 bits as a char, use
<tt>readChar(16)</tt>
* @return the next 8 bits of data from standard input
as a <tt>char</tt>
* @throws RuntimeException if there are fewer than 8
bits available on standard input
*/
public static char readChar() {
if (isEmpty()) throw new RuntimeException("Reading
from empty input stream");
// special case when aligned byte
if (n == 8) {
int x = buffer;
fillBuffer();
return (char) (x & 0xff);
}
// combine last n bits of current buffer with first
8-n bits of new buffer
int x = buffer;
x <<= (8 - n);
int oldN = n;
fillBuffer();
if (isEmpty()) throw new RuntimeException("Reading
from empty input stream");
n = oldN;
x |= (buffer >>> n);
return (char) (x & 0xff);

// the above code doesn't quite work for the last


character if n = 8
// because buffer will be -1, so there is a special
case for aligned byte
}
/**
* Read 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 <tt>char</tt>
* @throws IllegalArgumentException if there are fewer
than r bits available on standard input
* @throws IllegalArgumentException unless 1 &le; r &le;
16
*/
public static char readChar(int r) {
if (r < 1 || r > 16) throw new
IllegalArgumentException("Illegal value of r = " + r);
// optimize r = 8 case
if (r == 8) return readChar();
char x = 0;
for (int i = 0; i < r; i++) {
x <<= 1;
boolean bit = readBoolean();
if (bit) x |= 1;
}
return x;
}
/**
* Read the remaining bytes of data from standard input
and return as a string.
* @return the remaining bytes of data from standard
input as a <tt>String</tt>
* @throws RuntimeException if standard input is empty
or if the number of bits
* available on standard input is not a multiple of 8
(byte-aligned)
*/
public static String readString() {
if (isEmpty()) throw new RuntimeException("Reading
from empty input stream");

StringBuilder sb = new StringBuilder();


while (!isEmpty()) {
char c = readChar();
sb.append(c);
}
return sb.toString();
}
/**
* Read the next 16 bits from standard input and return
as a 16-bit short.
* @return the next 16 bits of data from standard input
as a <tt>short</tt>
* @throws RuntimeException if there are fewer than 16
bits available on standard input
*/
public static short readShort() {
short x = 0;
for (int i = 0; i < 2; i++) {
char c = readChar();
x <<= 8;
x |= c;
}
return x;
}
/**
* Read the next 32 bits from standard input and return
as a 32-bit int.
* @return the next 32 bits of data from standard input
as a <tt>int</tt>
* @throws RuntimeException if there are fewer than 32
bits available on standard input
*/
public static int readInt() {
int x = 0;
for (int i = 0; i < 4; i++) {
char c = readChar();
x <<= 8;
x |= c;
}
return x;
}
/**

* Read 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 <tt>int</tt>
* @throws IllegalArgumentException if there are fewer
than r bits available on standard input
* @throws IllegalArgumentException unless 1 &le; r &le;
32
*/
public static int readInt(int r) {
if (r < 1 || r > 32) throw new
IllegalArgumentException("Illegal value of r = " + r);
// optimize r = 32 case
if (r == 32) return readInt();
int x = 0;
for (int i = 0; i < r; i++) {
x <<= 1;
boolean bit = readBoolean();
if (bit) x |= 1;
}
return x;
}
/**
* Read the next 64 bits from standard input and return
as a 64-bit long.
* @return the next 64 bits of data from standard input
as a <tt>long</tt>
* @throws RuntimeException if there are fewer than 64
bits available on standard input
*/
public static long readLong() {
long x = 0;
for (int i = 0; i < 8; i++) {
char c = readChar();
x <<= 8;
x |= c;
}
return x;
}
/**

* Read the next 64 bits from standard input and return


as a 64-bit double.
* @return the next 64 bits of data from standard input
as a <tt>double</tt>
* @throws RuntimeExceptionArgument if there are fewer
than 64 bits available on standard input
*/
public static double readDouble() {
return Double.longBitsToDouble(readLong());
}
/**
* Read the next 32 bits from standard input and return
as a 32-bit float.
* @return the next 32 bits of data from standard input
as a <tt>float</tt>
* @throws RuntimeException if there are fewer than 32
bits available on standard input
*/
public static float readFloat() {
return Float.intBitsToFloat(readInt());
}
/**
* Read the next 8 bits from standard input and return
as an 8-bit byte.
* @return the next 8 bits of data from standard input
as a <tt>byte</tt>
* @throws RuntimeException if there are fewer than 8
bits available on standard input
*/
public static byte readByte() {
char c = readChar();
byte x = (byte) (c & 0xff);
return x;
}
/**
* Test client. Reads in a binary input file from
standard input and writes
* it to standard output.
*/
public static void main(String[] args) {
// read one 8-bit char at a time
while (!BinaryStdIn.isEmpty()) {

char c = BinaryStdIn.readChar();
BinaryStdOut.write(c);
}
BinaryStdOut.flush();
}
}
Copyright 20002011, Robert Sedgewick and Kevin Wayne.
Last updated: Fri Jul 24 09:39:19 EDT 2015.
BinaryStdOut.java
Below is the syntax highlighted version
of BinaryStdOut.java from Standard Libraries.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac BinaryStdOut.java
* Execution:
java BinaryStdOut
* Dependencies: none
*
* Write binary data to standard output, either one 1-bit
boolean,
* one 8-bit char, one 32-bit int, one 64-bit double, one
32-bit float,
* or one 64-bit long at a time.
*
* The bytes written are not aligned.
*
***********************************************************
**************/
import java.io.BufferedOutputStream;
import java.io.IOException;
/**
* <i>Binary standard output</i>. This class provides
methods for converting
* primtive type variables (<tt>boolean</tt>,
<tt>byte</tt>, <tt>char</tt>,

* <tt>int</tt>, <tt>long</tt>, <tt>float</tt>, and


<tt>double</tt>)
* to sequences of bits and writing them to standard
output.
* Uses big-endian (most-significant byte first).
* <p>
* The client must <tt>flush()</tt> the output stream when
finished writing bits.
* <p>
* The client should not intermixing calls to
<tt>BinaryStdOut</tt> with calls
* to <tt>StdOut</tt> or <tt>System.out</tt>; otherwise
unexpected behavior
* will result.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public final class BinaryStdOut {
private static BufferedOutputStream out = new
BufferedOutputStream(System.out);
private static int buffer;
to write out
private static int n;
remaining in buffer

// 8-bit buffer of bits


// number of bits

// don't instantiate
private BinaryStdOut() { }
/**
* Write the specified bit to standard output.
*/
private static void writeBit(boolean bit) {
// add bit to buffer
buffer <<= 1;
if (bit) buffer |= 1;
// if buffer is full (8 bits), write out as a
single byte
n++;
if (n == 8) clearBuffer();
}
/**
* Write the 8-bit byte to standard output.
*/

private static void writeByte(int x) {


assert x >= 0 && x < 256;
// optimized if byte-aligned
if (n == 0) {
try {
out.write(x);
}
catch (IOException e) {
e.printStackTrace();
}
return;
}
// otherwise write one bit at a time
for (int i = 0; i < 8; i++) {
boolean bit = ((x >>> (8 - i - 1)) & 1) == 1;
writeBit(bit);
}
}
// write out any remaining bits in buffer to standard
output, padding with 0s
private static void clearBuffer() {
if (n == 0) return;
if (n > 0) buffer <<= (8 - n);
try {
out.write(buffer);
}
catch (IOException e) {
e.printStackTrace();
}
n = 0;
buffer = 0;
}
/**
* Flush standard output, padding 0s if number of bits
written so far
* is not a multiple of 8.
*/
public static void flush() {
clearBuffer();
try {
out.flush();
}
catch (IOException e) {

e.printStackTrace();
}
}
/**
* Flush and close standard output. Once standard
output is closed, you can no
* longer write bits to it.
*/
public static void close() {
flush();
try {
out.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
/**
* Write the specified bit to standard output.
* @param x the <tt>boolean</tt> to write.
*/
public static void write(boolean x) {
writeBit(x);
}
/**
* Write the 8-bit byte to standard output.
* @param x the <tt>byte</tt> to write.
*/
public static void write(byte x) {
writeByte(x & 0xff);
}
/**
* Write the 32-bit int to standard output.
* @param x the <tt>int</tt> to write.
*/
public static void write(int x) {
writeByte((x >>> 24) & 0xff);
writeByte((x >>> 16) & 0xff);
writeByte((x >>> 8) & 0xff);
writeByte((x >>> 0) & 0xff);
}

/**
* Write the r-bit int to standard output.
* @param x the <tt>int</tt> to write.
* @param r the number of relevant bits in the char.
* @throws IllegalArgumentException if <tt>r</tt> is
not between 1 and 32.
* @throws IllegalArgumentException if <tt>x</tt> is
not between 0 and 2<sup>r</sup> - 1.
*/
public static void write(int x, int r) {
if (r == 32) {
write(x);
return;
}
if (r < 1 || r > 32)
throw new
IllegalArgumentException("Illegal value for r = " + r);
if (x < 0 || x >= (1 << r)) throw new
IllegalArgumentException("Illegal " + r + "-bit char = " +
x);
for (int i = 0; i < r; i++) {
boolean bit = ((x >>> (r - i - 1)) & 1) == 1;
writeBit(bit);
}
}

/**
* Write the 64-bit double to standard output.
* @param x the <tt>double</tt> to write.
*/
public static void write(double x) {
write(Double.doubleToRawLongBits(x));
}
/**
* Write the 64-bit long to standard output.
* @param x the <tt>long</tt> to write.
*/
public static void write(long x) {
writeByte((int) ((x >>> 56) & 0xff));
writeByte((int) ((x >>> 48) & 0xff));
writeByte((int) ((x >>> 40) & 0xff));
writeByte((int) ((x >>> 32) & 0xff));
writeByte((int) ((x >>> 24) & 0xff));

writeByte((int) ((x >>> 16) & 0xff));


writeByte((int) ((x >>> 8) & 0xff));
writeByte((int) ((x >>> 0) & 0xff));
}
/**
* Write the 32-bit float to standard output.
* @param x the <tt>float</tt> to write.
*/
public static void write(float x) {
write(Float.floatToRawIntBits(x));
}
/**
* Write the 16-bit int to standard output.
* @param x the <tt>short</tt> to write.
*/
public static void write(short x) {
writeByte((x >>> 8) & 0xff);
writeByte((x >>> 0) & 0xff);
}
/**
* Write the 8-bit char to standard output.
* @param x the <tt>char</tt> to write.
* @throws IllegalArgumentException if <tt>x</tt> is
not betwen 0 and 255.
*/
public static void write(char x) {
if (x < 0 || x >= 256) throw new
IllegalArgumentException("Illegal 8-bit char = " + x);
writeByte(x);
}
/**
* Write the r-bit char to standard output.
* @param x the <tt>char</tt> to write.
* @param r the number of relevant bits in the char.
* @throws IllegalArgumentException if <tt>r</tt> is
not between 1 and 16.
* @throws IllegalArgumentException if <tt>x</tt> is
not between 0 and 2<sup>r</sup> - 1.
*/
public static void write(char x, int r) {
if (r == 8) {
write(x);
return;

}
if (r < 1 || r > 16) throw new
IllegalArgumentException("Illegal value for r = " + r);
if (x >= (1 << r))
throw new
IllegalArgumentException("Illegal " + r + "-bit char = " +
x);
for (int i = 0; i < r; i++) {
boolean bit = ((x >>> (r - i - 1)) & 1) == 1;
writeBit(bit);
}
}
/**
* Write the string of 8-bit characters to standard
output.
* @param s the <tt>String</tt> to write.
* @throws IllegalArgumentException if any character in
the string is not
* between 0 and 255.
*/
public static void write(String s) {
for (int i = 0; i < s.length(); i++)
write(s.charAt(i));
}
/**
* Write the String of r-bit characters to standard
output.
* @param s the <tt>String</tt> to write.
* @param r the number of relevants 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 2<sup>r</sup> - 1.
*/
public static void write(String s, int r) {
for (int i = 0; i < s.length(); i++)
write(s.charAt(i), r);
}
/**
* Test client.
*/
public static void main(String[] args) {
int T = Integer.parseInt(args[0]);

// write to standard output


for (int i = 0; i < T; i++) {
BinaryStdOut.write(i);
}
BinaryStdOut.flush();
}
}
Copyright 20002011, Robert Sedgewick and Kevin Wayne.
Last updated: Fri Jul 24 09:39:19 EDT 2015.
BinaryIn.java
Below is the syntax highlighted version
of BinaryIn.java from Standard Libraries.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac BinaryIn.java
* Execution:
java BinaryIn input output
* Dependencies: none
*
* This library is for reading binary data from an input
stream.
*
* % java BinaryIn
http://introcs.cs.princeton.edu/cover.jpg output.jpg
*
***********************************************************
**************/
import
import
import
import
import
import
import
import

java.io.BufferedInputStream;
java.io.File;
java.io.FileInputStream;
java.io.IOException;
java.io.InputStream;
java.net.Socket;
java.net.URL;
java.net.URLConnection;

/**
* <i>Binary input</i>. This class provides methods for
reading
* in bits from a binary input stream, either
* one bit at a time (as a <tt>boolean</tt>),
* 8 bits at a time (as a <tt>byte</tt> or <tt>char</tt>),
* 16 bits at a time (as a <tt>short</tt>),
* 32 bits at a time (as an <tt>int</tt> or
<tt>float</tt>), or
* 64 bits at a time (as a <tt>double</tt> or
<tt>long</tt>).
* <p>
* The binary input stream can be from standard input, a
filename,
* a URL name, a Socket, or an InputStream.
* <p>
* All primitive types are assumed to be represented using
their
* standard Java representations, in big-endian (most
significant
* byte first) order.
* <p>
* The client should not intermix calls to
<tt>BinaryIn</tt> with calls
* to <tt>In</tt>; otherwise unexpected behavior will
result.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public final class BinaryIn {
private static final int EOF = -1;
// end of file
private BufferedInputStream in;
stream
private int buffer;
buffer
private int n;
left in buffer

// the input
// one character
// number of bits

/**
* Create a binary input stream from standard input.
*/
public BinaryIn() {
in = new BufferedInputStream(System.in);
fillBuffer();

}
/**
* Create a binary input stream from an InputStream.
*/
public BinaryIn(InputStream is) {
in = new BufferedInputStream(is);
fillBuffer();
}
/**
* Create a binary input stream from a socket.
*/
public BinaryIn(Socket socket) {
try {
InputStream is = socket.getInputStream();
in = new BufferedInputStream(is);
fillBuffer();
}
catch (IOException ioe) {
System.err.println("Could not open " + socket);
}
}
/**
* Create a binary input stream from a URL.
*/
public BinaryIn(URL url) {
try {
URLConnection site = url.openConnection();
InputStream is
= site.getInputStream();
in = new BufferedInputStream(is);
fillBuffer();
}
catch (IOException ioe) {
System.err.println("Could not open " + url);
}
}
/**
* Create a binary input stream from a filename or URL
name.
*/
public BinaryIn(String s) {
try {

// first try to read file from local file


system
File file = new File(s);
if (file.exists()) {
FileInputStream fis = new
FileInputStream(file);
in = new BufferedInputStream(fis);
fillBuffer();
return;
}
// next try for files included in jar
URL url = getClass().getResource(s);
// or URL from web
if (url == null) {
url = new URL(s);
}
URLConnection site = url.openConnection();
InputStream is
= site.getInputStream();
in = new BufferedInputStream(is);
fillBuffer();
}
catch (IOException ioe) {
System.err.println("Could not open " + s);
}
}
private void fillBuffer() {
try {
buffer = in.read();
n = 8;
}
catch (IOException e) {
System.err.println("EOF");
buffer = EOF;
n = -1;
}
}
/**
* Does the binary input stream exist?
*/
public boolean exists() {
return in != null;
}

/**
* Returns true if the binary input stream is empty.
* @return true if and only if the binary input stream
is empty
*/
public boolean isEmpty() {
return buffer == EOF;
}
/**
* Read the next bit of data from the binary input
stream and return as a boolean.
* @return the next bit of data from the binary input
stream as a <tt>boolean</tt>
* @throws RuntimeException if the input stream is
empty
*/
public boolean readBoolean() {
if (isEmpty()) throw new RuntimeException("Reading
from empty input stream");
n--;
boolean bit = ((buffer >> n) & 1) == 1;
if (n == 0) fillBuffer();
return bit;
}
/**
* Read the next 8 bits from the binary input stream
and return as an 8-bit char.
* @return the next 8 bits of data from the binary
input stream as a <tt>char</tt>
* @throws RuntimeException if there are fewer than 8
bits available
*/
public char readChar() {
if (isEmpty()) throw new RuntimeException("Reading
from empty input stream");
// special case when aligned byte
if (n == 8) {
int x = buffer;
fillBuffer();
return (char) (x & 0xff);
}

// combine last N bits of current buffer with first


8-N bits of new buffer
int x = buffer;
x <<= (8 - n);
int oldN = n;
fillBuffer();
if (isEmpty()) throw new RuntimeException("Reading
from empty input stream");
n = oldN;
x |= (buffer >>> n);
return (char) (x & 0xff);
// the above code doesn't quite work for the last
character if N = 8
// because buffer will be -1
}
/**
* Read the next r bits from the binary input stream
and return as an r-bit character.
* @param r number of bits to read.
* @return the next r bits of data from the binary
input streamt as a <tt>char</tt>
* @throws RuntimeException if there are fewer than r
bits available
*/
public char readChar(int r) {
if (r < 1 || r > 16) throw new
RuntimeException("Illegal value of r = " + r);
// optimize r = 8 case
if (r == 8) return readChar();
char x = 0;
for (int i = 0; i < r; i++) {
x <<= 1;
boolean bit = readBoolean();
if (bit) x |= 1;
}
return x;
}
/**
* Read the remaining bytes of data from the binary
input stream and return as a string.

* @return the remaining bytes of data from the binary


input stream as a <tt>String</tt>
* @throws RuntimeException if the input stream is
empty or if the number of bits
* available is not a multiple of 8 (byte-aligned)
*/
public String readString() {
if (isEmpty()) throw new RuntimeException("Reading
from empty input stream");
StringBuilder sb = new StringBuilder();
while (!isEmpty()) {
char c = readChar();
sb.append(c);
}
return sb.toString();
}
/**
* Read the next 16 bits from the binary input stream
and return as a 16-bit short.
* @return the next 16 bits of data from the binary
standard input as a <tt>short</tt>
* @throws RuntimeException if there are fewer than 16
bits available
*/
public short readShort() {
short x = 0;
for (int i = 0; i < 2; i++) {
char c = readChar();
x <<= 8;
x |= c;
}
return x;
}
/**
* Read the next 32 bits from the binary input stream
and return as a 32-bit int.
* @return the next 32 bits of data from the binary
input stream as a <tt>int</tt>
* @throws RuntimeException if there are fewer than 32
bits available
*/
public int readInt() {
int x = 0;

for (int i = 0; i < 4; i++) {


char c = readChar();
x <<= 8;
x |= c;
}
return x;
}
/**
* Read the next r bits from the binary input stream
return as an r-bit int.
* @param r number of bits to read.
* @return the next r bits of data from the binary
input stream as a <tt>int</tt>
* @throws RuntimeException if there are fewer than r
bits available on standard input
*/
public int readInt(int r) {
if (r < 1 || r > 32) throw new
RuntimeException("Illegal value of r = " + r);
// optimize r = 32 case
if (r == 32) return readInt();
int x = 0;
for (int i = 0; i < r; i++) {
x <<= 1;
boolean bit = readBoolean();
if (bit) x |= 1;
}
return x;
}
/**
* Read the next 64 bits from the binary input stream
and return as a 64-bit long.
* @return the next 64 bits of data from the binary
input stream as a <tt>long</tt>
* @throws RuntimeException if there are fewer than 64
bits available
*/
public long readLong() {
long x = 0;
for (int i = 0; i < 8; i++) {
char c = readChar();
x <<= 8;
x |= c;

}
return x;
}
/**
* Read the next 64 bits from the binary input stream
and return as a 64-bit double.
* @return the next 64 bits of data from the binary
input stream as a <tt>double</tt>
* @throws RuntimeException if there are fewer than 64
bits available
*/
public double readDouble() {
return Double.longBitsToDouble(readLong());
}
/**
* Read the next 32 bits from standard input and return
as a 32-bit float.
* @return the next 32 bits of data from standard input
as a <tt>float</tt>
* @throws RuntimeException if there are fewer than 32
bits available on standard input
*/
public float readFloat() {
return Float.intBitsToFloat(readInt());
}
/**
* Read the next 8 bits from the binary input stream
and return as an 8-bit byte.
* @return the next 8 bits of data from the binary
input stream as a <tt>byte</tt>
* @throws RuntimeException if there are fewer than 8
bits available
*/
public byte readByte() {
char c = readChar();
byte x = (byte) (c & 0xff);
return x;
}
/**
* Test client. Reads in the name of a file or url
(first command-line

* argument) and writes it to a file (second commandline argument).


*/
public static void main(String[] args) {
BinaryIn in = new BinaryIn(args[0]);
BinaryOut out = new BinaryOut(args[1]);
// read one 8-bit char at a time
while (!in.isEmpty()) {
char c = in.readChar();
out.write(c);
}
out.flush();
}
}
Copyright 20002011, Robert Sedgewick and Kevin Wayne.
Last updated: Fri Jul 24 09:39:19 EDT 2015.
BinaryOut.java
Below is the syntax highlighted version
of BinaryOut.java from Standard Libraries.
the Javadoc.

Here is

/
***********************************************************
**************
* Compilation: javac BinaryOut.java
* Execution:
java BinaryOut
* Dependencies: none
*
* Write binary data to an output stream, either one 1-bit
boolean,
* one 8-bit char, one 32-bit int, one 64-bit double, one
32-bit float,
* or one 64-bit long at a time. The output stream can be
standard
* output, a file, an OutputStream or a Socket.
*
* The bytes written are not aligned.
*
* [wayne 7.17.2013] fixed bugs in write(char x, int r)
and

*
8)
*
*

write(int x, int r) to add return statement for (r ==


and (r == 32) cases, respectively.

***********************************************************
**************/
import
import
import
import
import

java.io.BufferedOutputStream;
java.io.FileOutputStream;
java.io.IOException;
java.io.OutputStream;
java.net.Socket;

/**
* <i>Binary output</i>. This class provides methods for
converting
* primtive type variables (<tt>boolean</tt>,
<tt>byte</tt>, <tt>char</tt>,
* <tt>int</tt>, <tt>long</tt>, <tt>float</tt>, and
<tt>double</tt>)
* 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).
* <p>
* The client must <tt>flush()</tt> the output stream when
finished writing bits.
* <p>
* The client should not intermixing calls to
<tt>BinaryOut</tt> with calls
* to <tt>Out</tt>; otherwise unexpected behavior will
result.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public final class BinaryOut {
private BufferedOutputStream out;
private int buffer;
bits to write out
private int n;
remaining in buffer

// the output stream


// 8-bit buffer of
// number of bits

/**
* Create a binary output stream from an OutputStream.
*/
public BinaryOut(OutputStream os) {
out = new BufferedOutputStream(os);
}
/**
* Create a binary output stream from standard output.
*/
public BinaryOut() {
out = new BufferedOutputStream(System.out);
}
/**
* Create a binary output stream from a filename.
*/
public BinaryOut(String s) {
try {
OutputStream os = new FileOutputStream(s);
out = new BufferedOutputStream(os);
}
catch (IOException e) {
e.printStackTrace();
}
}
/**
* Create a binary output stream from a Socket.
*/
public BinaryOut(Socket socket) {
try {
OutputStream os = socket.getOutputStream();
out = new BufferedOutputStream(os);
}
catch (IOException e) {
e.printStackTrace();
}
}
/**
* Write the specified bit to the binary output stream.
*/
private void writeBit(boolean bit) {
// add bit to buffer
buffer <<= 1;

if (bit) buffer |= 1;
// if buffer is full (8 bits), write out as a
single byte
n++;
if (n == 8) clearBuffer();
}
/**
* Write the 8-bit byte to the binary output stream.
*/
private void writeByte(int x) {
assert x >= 0 && x < 256;
// optimized if byte-aligned
if (n == 0) {
try {
out.write(x);
}
catch (IOException e) {
e.printStackTrace();
}
return;
}
// otherwise write one bit at a time
for (int i = 0; i < 8; i++) {
boolean bit = ((x >>> (8 - i - 1)) & 1) == 1;
writeBit(bit);
}
}
// write out any remaining bits in buffer to the binary
output stream, padding with 0s
private void clearBuffer() {
if (n == 0) return;
if (n > 0) buffer <<= (8 - n);
try {
out.write(buffer);
}
catch (IOException e) {
e.printStackTrace();
}
n = 0;
buffer = 0;
}

/**
* Flush the binary output stream, padding 0s if number
of bits written so far
* is not a multiple of 8.
*/
public void flush() {
clearBuffer();
try {
out.flush();
}
catch (IOException e) {
e.printStackTrace();
}
}
/**
* Close and flush the binary output stream. Once it is
closed, you can no longer write bits.
*/
public void close() {
flush();
try {
out.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
/**
* Write the specified bit to the binary output stream.
* @param x the <tt>boolean</tt> to write.
*/
public void write(boolean x) {
writeBit(x);
}
/**
* Write the 8-bit byte to the binary output stream.
* @param x the <tt>byte</tt> to write.
*/
public void write(byte x) {
writeByte(x & 0xff);
}
/**

* Write the 32-bit int to the binary output stream.


* @param x the <tt>int</tt> to write.
*/
public void write(int x) {
writeByte((x >>> 24) & 0xff);
writeByte((x >>> 16) & 0xff);
writeByte((x >>> 8) & 0xff);
writeByte((x >>> 0) & 0xff);
}
/**
* Write the r-bit int to the binary output stream.
* @param x the <tt>int</tt> to write.
* @param r the number of relevant bits in the char.
* @throws RuntimeException if <tt>r</tt> is not
between 1 and 32.
* @throws RuntimeException if <tt>x</tt> is not
between 0 and 2<sup>r</sup> - 1.
*/
public void write(int x, int r) {
if (r == 32) {
write(x);
return;
}
if (r < 1 || r > 32) throw new
RuntimeException("Illegal value for r = " + r);
if (x >= (1 << r))
throw new
RuntimeException("Illegal " + r + "-bit char = " + x);
for (int i = 0; i < r; i++) {
boolean bit = ((x >>> (r - i - 1)) & 1) == 1;
writeBit(bit);
}
}
/**
* Write the 64-bit double to the binary output stream.
* @param x the <tt>double</tt> to write.
*/
public void write(double x) {
write(Double.doubleToRawLongBits(x));
}
/**
* Write the 64-bit long to the binary output stream.
* @param x the <tt>long</tt> to write.
*/

public void write(long x) {


writeByte((int) ((x >>>
writeByte((int) ((x >>>
writeByte((int) ((x >>>
writeByte((int) ((x >>>
writeByte((int) ((x >>>
writeByte((int) ((x >>>
writeByte((int) ((x >>>
writeByte((int) ((x >>>
}

56)
48)
40)
32)
24)
16)
8)
0)

&
&
&
&
&
&
&
&

0xff));
0xff));
0xff));
0xff));
0xff));
0xff));
0xff));
0xff));

/**
* Write the 32-bit float to the binary output stream.
* @param x the <tt>float</tt> to write.
*/
public void write(float x) {
write(Float.floatToRawIntBits(x));
}
/**
* Write the 16-bit int to the binary output stream.
* @param x the <tt>short</tt> to write.
*/
public void write(short x) {
writeByte((x >>> 8) & 0xff);
writeByte((x >>> 0) & 0xff);
}
/**
* Write the 8-bit char to the binary output stream.
* @param x the <tt>char</tt> to write.
* @throws RuntimeException if <tt>x</tt> is not betwen
0 and 255.
*/
public void write(char x) {
if (x < 0 || x >= 256) throw new
RuntimeException("Illegal 8-bit char = " + x);
writeByte(x);
}
/**
* Write the r-bit char to the binary output stream.
* @param x the <tt>char</tt> to write.
* @param r the number of relevant bits in the char.
* @throws RuntimeException if <tt>r</tt> is not
between 1 and 16.

* @throws RuntimeException if <tt>x</tt> is not


between 0 and 2<sup>r</sup> - 1.
*/
public void write(char x, int r) {
if (r == 8) {
write(x);
return;
}
if (r < 1 || r > 16) throw new
RuntimeException("Illegal value for r = " + r);
if (x >= (1 << r))
throw new
RuntimeException("Illegal " + r + "-bit char = " + x);
for (int i = 0; i < r; i++) {
boolean bit = ((x >>> (r - i - 1)) & 1) == 1;
writeBit(bit);
}
}
/**
* Write the string of 8-bit characters to the binary
output stream.
* @param s the <tt>String</tt> to write.
* @throws RuntimeException if any character in the
string is not
* between 0 and 255.
*/
public void write(String s) {
for (int i = 0; i < s.length(); i++)
write(s.charAt(i));
}
/**
* Write the String of r-bit characters to the binary
output stream.
* @param s the <tt>String</tt> to write.
* @param r the number of relevants bits in each
character.
* @throws RuntimeException if r is not between 1 and
16.
* @throws RuntimeException if any character in the
string is not
* between 0 and 2<sup>r</sup> - 1.
*/
public void write(String s, int r) {
for (int i = 0; i < s.length(); i++)
write(s.charAt(i), r);

}
/**
* Test client. Read bits from standard input and write
to the file
* specified on command line.
*/
public static void main(String[] args) {
// create binary output stream to write to file
String filename = args[0];
BinaryOut out = new BinaryOut(filename);
BinaryIn in = new BinaryIn();
// read from standard input and write to file
while (!in.isEmpty()) {
char c = in.readChar();
out.write(c);
}
out.flush();
}
}
Copyright 20002011, Robert Sedgewick and Kevin Wayne.
Last updated: Fri Jul 24 09:39:19 EDT 2015.

You might also like