Académique Documents
Professionnel Documents
Culture Documents
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;
/**
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 {
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
*
*
*
***********************************************************
**************/
/**
* 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>
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
***********************************************************
**************/
/**
* 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() { }
/**
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>
// 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
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.
/**
* 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];
/**
* 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.
*/
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.
*/
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;
/**
/**
* 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?
}
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
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();
}
}
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
// 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");
// convert -0.0 to
+0.0
else
this.x = x;
// 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.
/**
* 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
*/
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 + "]";
}
/**
* 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
}
// 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.
}
/**
* Returns
* @return
*/
public int
return
}
/**
* 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
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?
/**
* 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
}
/**
}
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)");
}
}
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>
*/
public boolean isEmpty() {
return N == 0;
}
/**
* Returns
* @return
*/
public int
return
}
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
{ throw new
}
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
}
/**
* 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;
}
public void remove()
UnsupportedOperationException();
{ throw new
}
}
}
/**
* 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
}
/**
* 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++;
}
/**
}
public boolean hasNext()
}
public void remove()
UnsupportedOperationException();
{ throw new
}
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
// 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
// beginning of bag
/**
* 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++;
}
/**
}
public void remove()
UnsupportedOperationException();
{ throw new
}
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
// beginning of bag
/**
* 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++;
}
/**
}
public void remove()
UnsupportedOperationException();
{ throw new
}
}
}
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
*
*
*
*/
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.
*
***********************************************************
**************/
/**
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> = β<sub>0</sub> + β<sub>1</sub>
<em>x</em> +
* β<sub>2</sub> <em>x</em><sup>2</sup> + ... +
* β<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 β<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
/**
* 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);
}
}
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
*/
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
*
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>
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();
}
/**
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
*/
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
}
/**
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>
}
/**
* 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
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> – 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> – 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>,
*
* <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
/**
* 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
< 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 ≤ p < N</tt>
*/
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
***********************************************************
**************/
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 ?
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
***********************************************************
**************/
/**
* 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
/**********************************************************
*************
* 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) {
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 ]
*
***********************************************************
**************/
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;
/**********************************************************
*************
* 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);
}
/**********************************************************
*************
* 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;
}
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.
/**********************************************************
*************
* 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
*
***********************************************************
**************/
/**
* 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++];
/**********************************************************
*************
* Helper sorting functions.
***********************************************************
************/
// is v < w ?
/**********************************************************
*************
* 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];
}
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) {
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
***********************************************************
**************/
/**
* 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;
}
/**********************************************************
*************
***********************************************************
************/
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
***********************************************************
**************/
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
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;
/**********************************************************
*********
* 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.
dst[k]
dst[k]
dst[k]
dst[k]
}
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
/**********************************************************
*************
* 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
*
// redundant since
/**********************************************************
*************
* 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;
}
/**********************************************************
*************
***********************************************************
************/
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 ]
*
***********************************************************
**************/
/**
* 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;
}
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
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) {
/**********************************************************
*************
***********************************************************
************/
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
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;
/**
* 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
}
/**
* 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);
}
/**********************************************************
*************
* 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]);
}
{ return !copy.isEmpty();
}
public void remove()
UnsupportedOperationException();
{ throw new
}
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
*/
/**
* 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;
}
/**
/**********************************************************
*************
* 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;
/**********************************************************
*************
* 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
}
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,
/**********************************************************
****
* 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
}
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;
/**
// 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 ≤ i < maxN)
*/
public boolean contains(int i) {
return qp[i] != -1;
}
/**
* Returns
* @return
*/
public int
return
}
/**
* Associate key with index i.
* @param i an index
* @param key the key to associate with index i
* @throws java.lang.IndexOutOfBoundsException unless 0
≤ 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
/**********************************************************
****
/**********************************************************
****
* 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
}
}
}
}
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 ]
*
***********************************************************
**************/
/**
* 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
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
***********************************************************
**************/
/**
* 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>
}
/**
* Initializes an empty symbol table.
*/
public SequentialSearchST() {
}
/**
* Returns
table.
* @return
table
*/
public int
return
}
/**
* 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
*
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;
}
// to avoid loitering
/**********************************************************
*******************
* 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];
}
/**********************************************************
*******************
* 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
***********************************************************
**************/
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
}
// 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);
/**********************************************************
*************
* 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 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);
}
/**********************************************************
*******************
* 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
***********************************************************
**************/
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;
// key
// associated data
// links to left and
// color of parent link
// subtree count
}
/**********************************************************
***************
* 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.
***********************************************************
**************/
***********************************************************
**************/
// 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.
/**********************************************************
***************
* 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;
return null;
/**********************************************************
***************
* 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?
/**********************************************************
*******************
* 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())
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
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;
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>—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.
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
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
}
/**
* 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
}
}
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() {
// 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();
= " +
= " +
= " +
= " +
= " +
= " +
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);
}
}
}
}
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]);
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,
new
index");
st.get(i);
0.0;
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>
*/
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
}
/**
* Returns the number of edges in the graph.
* @return the number of edges in the graph
*/
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;
{
-1;
+1;
-1;
+1;
}
/**
* Returns a random simple graph containing <tt>V</tt>
vertices and <tt>E</tt> 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.
/**
* 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
***********************************************************
**************/
/**
* 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
/**
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
%
0
0
0
0
0
0
0
***********************************************************
**************/
/**
* 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
*/
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++) {
// 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?
// 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
}
/**
* 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
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>
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.
StdOut.println("Graph is acyclic");
}
}
}
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
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
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
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;
{
-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
*/
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;
}
/**
}
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.
// 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.
not connected\n",
s, v);
}
}
}
}
Copyright 20022010, Robert Sedgewick and Kevin Wayne.
Last updated: Thu Oct 24 15:59:37 EDT 2013.
DirectedCycle.java
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),
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;
}
DepthFirstOrder.java
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
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;
}
/**
Topological.java
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
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.
*/
BreadthFirstDirectedPaths.java
/
***********************************************************
**************
* 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>,
/**
* 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>)
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>
}
/**
* 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
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 ...
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
***********************************************************
**************/
/**
* 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
/**
* 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
// marked[v] = has v
// id[v] = id of
// low[v] = low number
// 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
}
/**
* 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.
// 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
}
/**
* Are vertices <tt>v</tt> and <tt>w</tt> in the same
strong component?
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
*
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
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
}
/
***********************************************************
**************
* 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.
}
/**
* 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
*/
double weight;
Queue<Edge> mst;
boolean[] marked;
MinPQ<Edge> pq;
/**
* 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
// w
}
}
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
// run from
// minimum
}
/**
* 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);
}
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>
// 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()) {
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)
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>
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
}
}
/**
* 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.
*/
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
/**
* Returns
* @return
*/
public int
return
}
/**
* 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
* ...
*
***********************************************************
**************/
/**
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;
/**
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 ≤
<tt>s</tt> ≤ <tt>V</tt> - 1
*/
*/
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
/**
* 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() { }
/**
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));
}
}
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
// 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 ≤
<tt>s</tt> ≤ <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]);
*/
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;
}
/
***********************************************************
**************
* 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.
*
// 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);
}
Here is
/
***********************************************************
**************
* 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());
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();
/**
* 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);
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.
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
}
/**
* Returns the number of edges in the edge-weighted
digraph.
* @return the number of edges in the edge-weighted
digraph
*/
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
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
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
***********************************************************
**************/
/
***********************************************************
************************
* 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
/
***********************************************************
************************
* 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
//
15;
//
Math.min(v.length(),
< w.charAt(i)) return true;
> w.charAt(i)) return false;
w.length();
// 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
}
//
//
JAVA 7
//
d) {
//
d));
//
0;
//
/
***********************************************************
**************
* 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,
// root of trie
// number of keys in trie
/**
* 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;
}
/**
* 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
/**
* 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;
}
/**
*
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);
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
// root of trie
// number of keys in trie
/**
* 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>,
*
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);
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);
}
}
/
***********************************************************
**************
* 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>—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
}
/**
* 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) {
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>,
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
// Set match
X = dfa[pat.charAt(j)][X];
restart state.
}
}
// Update
// Set match
case.
X = dfa[pattern[j]][X];
restart state.
}
}
// Update
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
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
*
***********************************************************
****/
// the radix
// the bad-character skip
// store the pattern as a
// or as a string
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
// 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);
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
/
***********************************************************
**************
* 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);
}
}
}
}
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
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();
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.
Here is
/
***********************************************************
**************
* Compilation: javac RunLength.java
* Execution:
java RunLength - < input.txt
(compress)
* Execution:
java RunLength + < input.txt
(expand)
* Dependencies: BinaryIn.java BinaryOut.java
*
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;
}
}
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();
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
// number of
// number of
// codeword
// (unused)
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();
}
/
***********************************************************
**************
* 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
*
*
***********************************************************
**************/
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
/**********************************************************
**********************
* 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
/**********************************************************
**********************
* 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
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
//
//
//
//
//
//
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;
/
***********************************************************
**************
* 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
//
// the
// 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;
> j; i--)
h.children[i-1];
null;
split(h);
/**********************************************************
***************
* 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.
*/
}
/**
* Returns
* @return
*/
public int
return
}
/**
* 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
≤ <em>i</em> < <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
≤ <em>i</em> < <em>N</em>
*/
public int lcp(int i) {
if (i < 1 || i >= suffixes.length) throw new
IndexOutOfBoundsException();
return lcp(suffixes[i], suffixes[i-1]);
}
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>.
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
}
/**
* 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
≤ <em>i</em> < <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
≤ <em>i</em> < <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
≤ <em>i</em> < <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++) {
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;
/**
* 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()];
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;
/**
* 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++)
/
***********************************************************
**************
* 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
// 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
}
/**
* 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");
Here is
/
***********************************************************
**************
* Compilation: javac BipartiteMatching.java
* Execution:
java BipartiteMatching N E
* Dependencies: FordFulkerson.java FlowNetwork.java
FlowEdge.java
*
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;
double[][] weight;
double[] px;
double[] py;
int[] xy;
int[] yx;
/
***********************************************************
**************
* 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
// optimal
}
// find
private
int
for
test1() {
{
0 },
0 },
0 },
0 },
1 },
1, 1, 1 };
5, 45, 27, 24, 4 };
// 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
*
***********************************************************
**************/
= b.length;
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.
*
*
*
*
*
*
*
*
*
*
*
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) {
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)");
}
}
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;
}
// 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));
}
=
=
=
=
=
=
=
=
=
"
"
"
"
"
"
"
"
"
+
+
+
+
+
+
+
+
+
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
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);
}
}
/
***********************************************************
**************
* 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;
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; }
Here is
/
***********************************************************
**************
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++) {
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++];
}
}
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>.
*/
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) {
}
}
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.
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
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
***********************************************************
**************/
/**
* 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>—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
*/
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
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.
*/
/**
* 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
}
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...
*
*
*
*
*
*
*
*
*
*
*
*
*
***********************************************************
**************/
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
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));
}
/**
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
}
/**
* 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);
//
padding
/* 16 bits of 0xffff */
end marker
}
return true;
//
}
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
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) {
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.
*
* @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() {
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
/**
* 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
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
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
*/
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
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.
*
}
/**
* 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;
}
}
}
}
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.
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
}
}
/**
* 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
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">
*/
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();
}
/**
}
/**
* 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.
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;
/**
* 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.
*/
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
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
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);
/**
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);
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;
}
/**********************************************************
***************
***********************************************************
**************/
/**
* 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.
*/
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; }
/**********************************************************
***************
***********************************************************
**************/
/**
* 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
/**
* 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);
/**********************************************************
***************
* 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
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());
}
}
/**
/**********************************************************
***************
* 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
/**
* 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
// 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);
// 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) {
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);
}
/**********************************************************
*************
* 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];
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() { }
/**
}
/**
* 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.
*/
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.
*/
}
}
/**
* 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.
*/
}
/**
* 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;
}
/**
* 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
}
/**
* 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>
/**
* 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);
}
/**
*/
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;
/**
* 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.
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();
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";
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);
}
/**
/**
* 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.
*/
/
***********************************************************
**************
* 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;
= 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
0.0;
1.0;
0.0;
1.0;
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();
}
");
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) {
/**
* 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
*/
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);
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();
}
/**
/**********************************************************
***************
* Drawing text.
***********************************************************
**************/
/**
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>
/**********************************************************
***************
* 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);
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.
*/
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);
}
}
/**
}
/**
* 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
}
/**
* Returns
* @return
*/
public int
return
}
/**
* 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 ≤
<tt>col</tt> < <tt>width</tt>
* and 0 ≤ <tt>row</tt> < <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 ≤
<tt>col</tt> < <tt>width</tt>
* and 0 ≤ <tt>row</tt> < <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));
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.
*/
Here is
/
***********************************************************
**************
* Compilation: javac BinaryStdIn.java
* Execution:
java BinaryStdIn < input > output
* Dependencies: none
*
* Supports reading binary data from standard input.
*
*
*
*
***********************************************************
**************/
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.
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>,
// 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.
*/
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));
}
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]);
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 {
/**
* 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);
}
}
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
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)
*
*
***********************************************************
**************/
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
/**
* 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);
}
/**
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.
}
/**
* 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.